mirror of
https://github.com/tiennm99/DocsGPT.git
synced 2026-10-13 16:14:10 +00:00
Fix MCP OAuth for servers that publish their endpoint as the resource
Linear and Sentry publish https://host/mcp as their protected resource. DocsGPTOAuth gave the MCP SDK only the server's origin, so the SDK's resource check (RFC 8707) failed before sign-in with "Protected resource https://mcp.linear.app/mcp does not match expected https://mcp.linear.app". The provider now gets the full MCP URL; servers that publish their origin still pass, and tokens stay keyed by origin.
This commit is contained in:
1 parent
79fd2ac6cd
commit
a9390ec39e
2 files changed
+27
-1
No files matched your search
@@ -752,8 +752,12 @@ class DocsGPTOAuth(OAuthClientProvider):
|
||||
connection_id=connection_id,
|
||||
)
|
||||
|
||||
# The SDK checks the server's protected-resource metadata against a
|
||||
# resource derived from this URL, so it gets the full MCP endpoint:
|
||||
# Linear and Sentry publish ``https://host/mcp``, and an origin-only
|
||||
# URL fails that check before sign-in. Tokens stay keyed by origin.
|
||||
super().__init__(
|
||||
server_url=self.server_base_url,
|
||||
server_url=mcp_url.rstrip("/") or self.server_base_url,
|
||||
client_metadata=client_metadata,
|
||||
storage=storage,
|
||||
redirect_handler=self.redirect_handler,
|
||||
|
||||
@@ -120,3 +120,25 @@ class TestDiscover:
|
||||
with pytest.raises(service.ConnectionUnavailable), patch("docsgpt.agents.tools.mcp_tool.MCPTool") as tool_cls:
|
||||
mcp._discover("alice", connection, {"config": {}})
|
||||
tool_cls.assert_not_called()
|
||||
|
||||
|
||||
def test_oauth_resource_is_the_full_mcp_endpoint():
|
||||
"""Linear and Sentry publish ``https://host/mcp`` as their protected
|
||||
resource; the SDK must be given that endpoint, not only the origin."""
|
||||
from mcp.shared.auth_utils import check_resource_allowed, resource_url_from_server_url
|
||||
|
||||
from docsgpt.agents.tools.mcp_tool import DocsGPTOAuth
|
||||
|
||||
oauth = DocsGPTOAuth(
|
||||
mcp_url="https://mcp.linear.app/mcp",
|
||||
redis_client=MagicMock(),
|
||||
redirect_uri="https://example.com/callback",
|
||||
user_id="user1",
|
||||
)
|
||||
assert oauth.context.server_url == "https://mcp.linear.app/mcp"
|
||||
requested = resource_url_from_server_url(oauth.context.server_url)
|
||||
# Servers that publish the endpoint, and those that publish the origin.
|
||||
assert check_resource_allowed(requested_resource=requested, configured_resource="https://mcp.linear.app/mcp")
|
||||
assert check_resource_allowed(requested_resource=requested, configured_resource="https://mcp.linear.app")
|
||||
# Stored tokens stay keyed by the server's origin.
|
||||
assert oauth.context.storage.server_url == "https://mcp.linear.app"
|
||||
Reference in new issue
Block a user