Repository navigation
Description
Description
Remote MCP OAuth against Turso (https://mcp.turso.ai/mcp) fails before sign-in with:
Invalid request
The redirect URI is not permitted for this client - it must be a loopback address, an allowed hosted callback, or listed in the client's metadata document.
Turso's authorization server advertises client_id_metadata_document_supported: true, so OpenCode selects CIMD registration (registration=cimd) and identifies as https://opencode.ai/oauth/opencode/client.json. That hosted document lists only:
"redirect_uris": ["http://127.0.0.1/callback", "http://localhost/callback"]
but OpenCode sends redirect_uri=http://127.0.0.1:19876/mcp/oauth/callback (dynamic/fixed port + /mcp/oauth/callback path). OAuth redirect matching is exact-string, so the authorization server rejects the request before the user can sign in.
This is the same root cause as #50510 (Exa), reproduced against a different authorization server (api.turso.tech), which suggests the problem is general to any CIMD-capable AS and not Exa-specific.
Turso AS metadata (https://mcp.turso.ai/.well-known/oauth-authorization-server):
{"authorization_endpoint":"https://app.turso.tech/oauth/mcp/authorize","client_id_metadata_document_supported":true,"code_challenge_methods_supported":["S256"],"grant_types_supported":["authorization_code"],"issuer":"https://api.turso.tech","registration_endpoint":"https://api.turso.tech/v1/oauth/register","response_types_supported":["code"],"token_endpoint":"https://api.turso.tech/v1/oauth/token","token_endpoint_auth_methods_supported":["none"]}Plugins
None
OpenCode version
2.0.22
Steps to reproduce
- Add a remote MCP server:
{"type":"remote","url":"https://mcp.turso.ai/mcp"}with nooauth.redirect_uriand nooauth.client_id. - Run
opencode mcp auth turso. - Open the printed authorization URL in the browser.
- Turso returns: "The redirect URI is not permitted for this client - it must be a loopback address, an allowed hosted callback, or listed in the client's metadata document."
Expected: sign-in page is shown and authorization completes.
Actual: rejected before sign-in.
Suggested fix
Either declare the loopback callback OpenCode actually sends (port + /mcp/oauth/callback path) in the hosted client.json, or fall back to Dynamic Client Registration when the CIMD document's redirect_uris do not cover the callback actually in use. The AS publishes a registration_endpoint, so DCR is viable.
Workaround
Set an explicit redirect URI (and callback port) in config, which forces DCR instead of CIMD:
"turso": {
"type": "remote",
"url": "https://mcp.turso.ai/mcp",
"oauth": {
"callback_port": 19876,
"redirect_uri": "http://127.0.0.1:19876/mcp/oauth/callback"
}
}Screenshot and/or share link
n/a - the error is returned by the browser redirect to the authorization server.
Operating System
Windows 10 (10.0.19045)
Terminal
xterm-256color (Windows Terminal)
Activity
opencode-agent commentedon Oct 11, 2026
Thanks for the detailed report and for testing it against a second authorization server.
I think this is a duplicate of #50510. It's the same problem: OpenCode picks CIMD registration, the hosted
client.jsonlists onlyhttp://127.0.0.1/callbackandhttp://localhost/callback, and theredirect_uriactually sent (http://127.0.0.1:<port>/mcp/oauth/callback) gets rejected. The only difference is that this one is Turso and that one is Exa.Possible duplicates and related issues, most likely first:
oauth.redirect_uriworkaround, shown with Exa's authorization serverclient.jsonYour Turso repro shows this isn't specific to Exa. It would help to add a short note about it on #50510.
Until then, the workaround you found (setting
oauth.redirect_uriandcallback_port, which forces dynamic client registration) is the way to go.The bot will close this issue as a duplicate in 1 day unless you reply explaining how your problem is different.
opencode-agent commentedon Oct 12, 2026
We haven't heard back, so I'm closing this as a duplicate of #50510. Both issues come from the same mismatch: the redirect URIs listed in the hosted CIMD
client.jsondon't match the loopback callback OpenCode actually sends. Please follow #50510 for updates. Adding a short note there about the Turso case would show that this affects more than Exa. Until it's fixed, settingoauth.redirect_uriandcallback_port(which forces dynamic client registration) still works around it. If your problem turns out to be different, reply here and we can reopen.