Bug Description
OAuth-authenticated MCP servers whose endpoint URL contains a path component
(e.g. https://mcp.granola.ai/mcp) fail to connect due to a resource
identifier mismatch introduced by MCP SDK 1.27.0's RFC 8707 validation.
Steps to Reproduce
- Install hermes-agent with the
mcp extra (pip install "hermes-agent[mcp]")
- Add an OAuth MCP server whose endpoint URL has a path component:
mcp_servers:
granola:
url: https://mcp.granola.ai/mcp
auth: oauth
Expected Behavior
The OAuth discovery flow completes and the connection succeeds.
Actual Behavior
The connection fails immediately with a resource identifier mismatch error:
$ hermes mcp test granola
Testing 'granola'...
Transport: HTTP → https://mcp.granola.ai/mcp
Auth: OAuth 2.1 PKCE
✗ Connection failed (9573ms): Protected resource https://mcp.granola.ai/mcp does not match expected https://mcp.granola.ai
Affected Component
Other: MCP Server Authorization (OAuth)
Messaging Platform (if gateway-related)
N/A – setup issue, gateway agnostic
Debug Report
--- Granola MCP Server Failures ---
2026-04-15 10:40:09,554 WARNING tools.mcp_tool: MCP server 'granola' initial connection failed (attempt 1/3), retrying in 1s: unhandled errors in a TaskGroup (1 sub-exception)
2026-04-15 10:40:09,554 ERROR mcp.client.auth.oauth2: OAuth flow error
mcp.client.auth.exceptions.OAuthFlowError: Protected resource https://mcp.granola.ai/mcp does not match expected https://mcp.granola.ai
2026-04-15 10:40:09,554 WARNING tools.mcp_tool: MCP server 'granola' initial connection failed (attempt 2/3), retrying in 2s: unhandled errors in a TaskGroup (1 sub-exception)
2026-04-15 10:40:12,009 ERROR mcp.client.auth.oauth2: OAuth flow error
mcp.client.auth.exceptions.OAuthFlowError: Protected resource https://mcp.granola.ai/mcp does not match expected https://mcp.granola.ai
2026-04-15 10:40:12,012 WARNING tools.mcp_tool: MCP server 'granola' initial connection failed (attempt 3/3), retrying in 4s: unhandled errors in a TaskGroup (1 sub-exception)
2026-04-15 10:40:16,485 ERROR mcp.client.auth.oauth2: OAuth flow error
mcp.client.auth.exceptions.OAuthFlowError: Protected resource https://mcp.granola.ai/mcp does not match expected https://mcp.granola.ai
2026-04-15 10:40:16,488 WARNING tools.mcp_tool: MCP server 'granola' failed initial connection after 3 attempts, giving up: unhandled errors in a TaskGroup (1 sub-exception)
2026-04-15 10:40:53,930 INFO run_agent: Loaded environment variables from /home/open/.hermes/.env
2026-04-15 10:40:55,711 ERROR mcp.client.auth.oauth2: OAuth flow error
mcp.client.auth.exceptions.OAuthFlowError: Protected resource https://mcp.granola.ai/mcp does not match expected https://mcp.granola.ai
2026-04-15 10:40:55,713 WARNING tools.mcp_tool: MCP server 'granola' initial connection failed (attempt 1/3), retrying in 1s: unhandled errors in a TaskGroup (1 sub-exception)
2026-04-15 10:40:55,773 INFO mcp.client.streamable_http: Received session ID: ec548429-6754-4dc7-8a99-11fb453bc6e5
2026-04-15 10:40:55,774 INFO mcp.client.streamable_http: Negotiated protocol version: 2025-11-25
2026-04-15 10:40:56,164 INFO mcp.client.streamable_http: Negotiated protocol version: 2025-11-25
2026-04-15 10:40:56,286 INFO mcp.client.streamable_http: GET stream disconnected, reconnecting in 1000ms...
2026-04-15 10:40:57,356 ERROR mcp.client.auth.oauth2: OAuth flow error
mcp.client.auth.exceptions.OAuthFlowError: Protected resource https://mcp.granola.ai/mcp does not match expected https://mcp.granola.ai
Operating System
Ubuntu 24.04
Python Version
3.11.15
Hermes Version
v0.9.0 (2026.4.13)
Root Cause Analysis
build_oauth_auth() in tools/mcp_oauth.py strips the path from the server URL before constructing OAuthClientProvider:
parsed = urlparse(server_url)
base_url = f"{parsed.scheme}://{parsed.netloc}" # drops /mcp
provider = OAuthClientProvider(
server_url=base_url, # https://mcp.granola.ai, not https://mcp.granola.ai/mcp
...
)
MCP SDK 1.27.0 added RFC 8707 resource validation (python-sdk PR #2069) which checks that the resource field in the server's Protected Resource Metadata (RFC 9728) matches the server_url the client was initialized with. The server correctly advertises the full path URL as its resource identifier; the stripped base URL no longer matches.
The constraint mcp>=1.2.0,<2 allows 1.27.0 to be resolved, making this a silent regression for any user who upgrades.
Related: google-gemini/gemini-cli#20017 (same class of bug in a different MCP client)
Proposed Fix
Pass server_url.rstrip("/") directly to OAuthClientProvider (removing the path-stripping block).
Are you willing to submit a PR for this?
Bug Description
OAuth-authenticated MCP servers whose endpoint URL contains a path component
(e.g.
https://mcp.granola.ai/mcp) fail to connect due to a resourceidentifier mismatch introduced by MCP SDK 1.27.0's RFC 8707 validation.
Steps to Reproduce
mcpextra (pip install "hermes-agent[mcp]")Expected Behavior
The OAuth discovery flow completes and the connection succeeds.
Actual Behavior
The connection fails immediately with a resource identifier mismatch error:
Affected Component
Other: MCP Server Authorization (OAuth)
Messaging Platform (if gateway-related)
N/A – setup issue, gateway agnostic
Debug Report
Operating System
Ubuntu 24.04
Python Version
3.11.15
Hermes Version
v0.9.0 (2026.4.13)
Root Cause Analysis
build_oauth_auth()in tools/mcp_oauth.py strips the path from the server URL before constructing OAuthClientProvider:MCP SDK 1.27.0 added RFC 8707 resource validation (python-sdk PR #2069) which checks that the resource field in the server's Protected Resource Metadata (RFC 9728) matches the server_url the client was initialized with. The server correctly advertises the full path URL as its resource identifier; the stripped base URL no longer matches.
The constraint mcp>=1.2.0,<2 allows 1.27.0 to be resolved, making this a silent regression for any user who upgrades.
Related: google-gemini/gemini-cli#20017 (same class of bug in a different MCP client)
Proposed Fix
Pass
server_url.rstrip("/")directly to OAuthClientProvider (removing the path-stripping block).Are you willing to submit a PR for this?