I was trying to setup https://github.com/taylorwilsdon/google_workspace_mcp with EXTERNAL_OAUTH21_PROVIDER but got hit by the validation errors.
Bug 1: Resource metadata validation too strict — resource URI mismatch
oauth-protected-resource discovery failed for http://localhost:3011/.well-known/oauth-protected-resource: Resource metadata fetch failed: resource 'http://localhost:3011/' did not match expected resource 'http://localhost:3011/mcp' for http://localhost:3011/.well-known/oauth-protected-resource
Title: validate_resource_metadata! fails when OAuth Protected Resource resource field doesn't exactly match the MCP endpoint URL
Description:
When discovering OAuth protected resources via /.well-known/oauth-protected-resource, the validation fails if the resource field in the metadata response doesn't exactly match the
expected MCP endpoint URL.
For example, with google_workspace_mcp running on http://localhost:3011, the protected resource metadata returns resource: "http://localhost:3011/" (with trailing slash), but
ruby_llm-mcp expects "http://localhost:3011/mcp" (the actual MCP endpoint path). This causes discovery to fail with:
Resource metadata fetch failed: resource 'http://localhost:3011/' did not match expected resource 'http://localhost:3011/mcp'
Per RFC 9728, the resource field identifies the protected resource, which may differ from the specific endpoint path. The validation should be more lenient — e.g. checking that the
resource is a prefix of the endpoint URL, or comparing only the origin.
Bug 2: Server metadata validation too strict — issuer trailing slash mismatch
authorization server metadata discovery failed for https://accounts.google.com/.well-known/oauth-authorization-server: Server metadata fetch failed: issuer 'https://accounts.google.com' did not match expected issuer 'https://accounts.google.com/' for https://accounts.google.com/.well-known/oauth-authorization-server
Title: validate_server_metadata! fails when OAuth authorization server issuer has a trailing slash mismatch
Description:
When discovering OAuth authorization server metadata, the issuer validation fails due to a trailing slash mismatch. For example, Google's /.well-known/oauth-authorization-server
returns issuer: "https://accounts.google.com" (no trailing slash), but the expected issuer is "https://accounts.google.com/" (with trailing slash), causing:
Server metadata fetch failed: issuer 'https://accounts.google.com' did not match expected issuer 'https://accounts.google.com/'
This forces a fallback to /.well-known/openid-configuration, but that also fails if the same strict validation is applied.
The issuer comparison should normalize trailing slashes before comparing, as this is a common discrepancy between OAuth providers. Google is a major provider affected by this.
Current workaround:
# Fix auth in https://github.com/taylorwilsdon/google_workspace_mcp
# oauth-protected-resource discovery failed for http://localhost:3011/.well-known/oauth-protected-resource: Resource metadata fetch failed: resource 'http://localhost:3011/' did not match expected resource 'http://localhost:3011/mcp' for http://localhost:3011/.well-known/oauth-protected-resource
RubyLLM::MCP::Auth::Discoverer.class_eval do
def validate_resource_metadata!(*)
nil
end
end
# Fix authorization server metadata discovery failed for https://accounts.google.com/.well-known/oauth-authorization-server: Server metadata fetch failed: issuer 'https://accounts.google.com' did not match expected issuer 'https://accounts.google.com/' for https://accounts.google.com/.well-known/oauth-authorization-server
# Trying authorization server metadata discovery URL: https://accounts.google.com/.well-known/openid-configuration
# Fetching server metadata from https://accounts.google.com/.well-known/openid-configuration
RubyLLM::MCP::Auth::Discoverer.class_eval do
def validate_server_metadata!(*)
nil
end
end
The MCP server:
# https://github.com/taylorwilsdon/google_workspace_mcp?tab=readme-ov-file#configuration
# https://console.cloud.google.com/apis/credentials
export GOOGLE_OAUTH_CLIENT_ID=...
export GOOGLE_OAUTH_CLIENT_SECRET=...
export MCP_ENABLE_OAUTH21=true
export EXTERNAL_OAUTH21_PROVIDER=true
export WORKSPACE_MCP_STATELESS_MODE=true
export OAUTHLIB_INSECURE_TRANSPORT=1
export WORKSPACE_MCP_BASE_URI=http://localhost
export WORKSPACE_MCP_PORT=3011
export WORKSPACE_MCP_HOST=127.0.0.1
uvx --with "fastmcp==2.14.5" workspace-mcp --transport streamable-http --tools calendar
http://localhost:3011/.well-known/oauth-protected-resource
{
"resource": "http://localhost:3011/",
"authorization_servers": [
"https://accounts.google.com/"
],
"scopes_supported": [
"https://www.googleapis.com/auth/calendar",
"https://www.googleapis.com/auth/calendar.events",
"https://www.googleapis.com/auth/calendar.readonly",
"https://www.googleapis.com/auth/userinfo.email",
"https://www.googleapis.com/auth/userinfo.profile",
"openid"
],
"bearer_methods_supported": [
"header"
],
"resource_name": "Google Workspace MCP"
}
BTW thanks for 1.0.0 release ❤️
I was trying to setup https://github.com/taylorwilsdon/google_workspace_mcp with
EXTERNAL_OAUTH21_PROVIDERbut got hit by the validation errors.Bug 1: Resource metadata validation too strict — resource URI mismatch
Title: validate_resource_metadata! fails when OAuth Protected Resource resource field doesn't exactly match the MCP endpoint URL
Description:
When discovering OAuth protected resources via /.well-known/oauth-protected-resource, the validation fails if the resource field in the metadata response doesn't exactly match the
expected MCP endpoint URL.
For example, with google_workspace_mcp running on http://localhost:3011, the protected resource metadata returns resource: "http://localhost:3011/" (with trailing slash), but
ruby_llm-mcp expects "http://localhost:3011/mcp" (the actual MCP endpoint path). This causes discovery to fail with:
Resource metadata fetch failed: resource 'http://localhost:3011/' did not match expected resource 'http://localhost:3011/mcp'
Per RFC 9728, the resource field identifies the protected resource, which may differ from the specific endpoint path. The validation should be more lenient — e.g. checking that the
resource is a prefix of the endpoint URL, or comparing only the origin.
Bug 2: Server metadata validation too strict — issuer trailing slash mismatch
Title: validate_server_metadata! fails when OAuth authorization server issuer has a trailing slash mismatch
Description:
When discovering OAuth authorization server metadata, the issuer validation fails due to a trailing slash mismatch. For example, Google's /.well-known/oauth-authorization-server
returns issuer: "https://accounts.google.com" (no trailing slash), but the expected issuer is "https://accounts.google.com/" (with trailing slash), causing:
Server metadata fetch failed: issuer 'https://accounts.google.com' did not match expected issuer 'https://accounts.google.com/'
This forces a fallback to /.well-known/openid-configuration, but that also fails if the same strict validation is applied.
The issuer comparison should normalize trailing slashes before comparing, as this is a common discrepancy between OAuth providers. Google is a major provider affected by this.
Current workaround:
The MCP server:
http://localhost:3011/.well-known/oauth-protected-resource
{ "resource": "http://localhost:3011/", "authorization_servers": [ "https://accounts.google.com/" ], "scopes_supported": [ "https://www.googleapis.com/auth/calendar", "https://www.googleapis.com/auth/calendar.events", "https://www.googleapis.com/auth/calendar.readonly", "https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile", "openid" ], "bearer_methods_supported": [ "header" ], "resource_name": "Google Workspace MCP" }BTW thanks for 1.0.0 release ❤️