Summary
netclaw mcp auth <server> fails for Google Workspace MCP servers when the server permits unauthenticated MCP initialization and catalog discovery.
Instead of opening an OAuth authorization URL, Netclaw initializes the candidate connection, discovers the tools, then calls McpOAuthFlowBroker.BeginCommit. Because no OAuth callback occurred and no authorization code was delivered, TryBeginCommit rejects the flow with:
Authorization can no longer publish. Start a new MCP authorization attempt.
The CLI then reports only:
Starting OAuth authorization for 'google-docs'...
Error: MCP OAuth connection initialization failed. Check daemon logs for details.
This was reproduced with both Google Docs and Google Drive MCP servers, so it appears to be a generic explicit-reauthorization lifecycle issue rather than a Docs-specific failure.
Environment
netclaw 0.27.0-beta.2
commit 124f7a1263214f55c10ce01dbf422dfe96e93a0f
Windows / PowerShell 7
netclaw update reports this as the current release.
Configuration shape
Google Docs:
Transport: http
URL: https://docsmcp.googleapis.com/mcp/v1
OAuthClientId: configured
OAuthScope: https://www.googleapis.com/auth/documents https://www.googleapis.com/auth/documents.readonly
Google Drive is similarly configured with https://drivemcp.googleapis.com/mcp/v1 and the same pre-registered client ID.
Both servers report connected before explicit authorization:
google-docs connected (2 tools)
google-drive connected (8 tools)
Reproduction
-
Configure either Google Workspace MCP endpoint as an HTTP server with OAuthClientId.
-
Start Netclaw. The server connects and its tool catalog is discovered.
-
Run:
netclaw mcp auth google-docs
-
Observe that no browser authorization flow starts and the CLI reports connection initialization failure.
-
The same result occurs with:
netclaw mcp auth google-drive
Daemon log
MCP server 'google-docs' does not declare catalog notification support; catalog polling remains active
MCP server 'google-docs' exposes 2 tool(s) not granted to any audience: read_doc, update_doc.
MCP server 'google-docs' replacement failed; generation 1 remains connected
Netclaw.Daemon.Mcp.McpOAuthOperationException: Authorization can no longer publish. Start a new MCP authorization attempt.
at Netclaw.Daemon.Mcp.McpOAuthFlowBroker.BeginCommit(McpOAuthFlow flow)
at Netclaw.Daemon.Mcp.McpClientManager.BuildAndPublishCandidateAsync(...)
Explicit MCP OAuth candidate failed for server 'google-docs' during connection initialization (provider status (null))
Root cause analysis
In the installed source, BuildAndPublishCandidateAsync performs the following sequence:
- Creates the OAuth-enabled MCP client.
- Initializes the connection and reads the tool/prompt catalogs.
- Calls
_flowBroker.BeginCommit(authorizationFlow).
Source: McpClientManager.cs.
TryBeginCommit requires _codeDelivered == true. That flag is set only when the local OAuth callback delivers an authorization code.
Source: McpOAuthFlowBroker.cs and TryBeginCommit.
Google's MCP endpoint permits initialization/catalog discovery without first producing an OAuth challenge. Consequently, the SDK never invokes the interactive authorization callback, _codeDelivered remains false, and BeginCommit rejects the otherwise successfully initialized candidate.
Google interoperability gaps discovered during diagnosis
These are related and may warrant either inclusion in this fix or separate issues.
Pre-registered client secret cannot be configured
Google documents creating a Web application OAuth client and configuring both its client ID and client secret for the Google Docs MCP server:
https://developers.google.com/workspace/docs/api/guides/configure-mcp-server#configure-mcp-client
McpServerEntry currently exposes OAuthClientId but no configured OAuth client-secret field:
https://github.com/netclaw-dev/netclaw/blob/124f7a1263214f55c10ce01dbf422dfe96e93a0f/src/Netclaw.Configuration/McpServerEntry.cs
Moreover, when OAuthClientId is configured, BuildOAuthOptions explicitly supplies a null client secret:
ClientId = entry.OAuthClientId ?? identity.ClientId,
ClientSecret = entry.OAuthClientId is null ? identity.ClientSecret : null,
Source:
|
private ClientOAuthOptions BuildOAuthOptions( |
|
McpServerEntry entry, |
|
McpOAuthTokenCache cache, |
|
McpOAuthFlow? authorizationFlow) |
|
{ |
|
var identity = _credentialStore.GetIdentity(cache); |
|
return new ClientOAuthOptions |
|
{ |
|
RedirectUri = BuildRedirectUri(), |
|
ClientId = entry.OAuthClientId ?? identity.ClientId, |
|
ClientSecret = entry.OAuthClientId is null ? identity.ClientSecret : null, |
|
Scopes = ParseScopes(entry.OAuthScope), |
|
TokenCache = cache, |
|
|
|
AuthorizationCallbackHandler = CreateAuthorizationCallbackHandler(authorizationFlow), |
|
|
|
// DynamicClientRegistration is deliberately left unset. McpOAuthClientRegistrar |
|
// owns registration because the SDK hard-codes client_secret_post and cannot |
|
// register against public-client-only servers (csharp-sdk#1611). A non-null |
|
// ClientId here short-circuits the SDK's registration path entirely. |
|
}; |
This means Netclaw cannot currently represent Google's documented confidential-client configuration.
Redirect URI
Netclaw uses:
http://127.0.0.1:<daemon-port>/api/mcp/oauth/callback
Source:
|
private Uri BuildRedirectUri() |
|
=> new($"http://127.0.0.1:{_daemonConfig.Port}/api/mcp/oauth/callback"); |
That exact URI must be added to the Google Web application's authorized redirect URIs.
Documented scopes
Google currently documents four scopes for Docs MCP:
https://www.googleapis.com/auth/drive.readonly
https://www.googleapis.com/auth/drive.file
https://www.googleapis.com/auth/documents.readonly
https://www.googleapis.com/auth/documents
Source: https://developers.google.com/workspace/docs/api/guides/configure-mcp-server#configure-consent-screen
The missing Drive scopes do not cause the immediate BeginCommit failure, but may affect document discovery/access after OAuth succeeds.
Expected behavior
netclaw mcp auth should proactively perform OAuth discovery and produce an authorization request even when MCP initialization/catalog discovery succeeds anonymously. It should not treat successful anonymous initialization as completion of an explicit authorization attempt.
For Google Workspace compatibility, a pre-registered confidential client should also support securely configured client-secret material.
Suggested acceptance criteria
- Explicit authorization opens/prints an OAuth authorization URL when the protected resource requires OAuth, even if MCP initialization succeeds without a challenge.
- Candidate publication occurs only after the explicit flow has delivered and exchanged an authorization code.
- Reauthorization works when the currently published generation remains connected.
- Google Docs and Google Drive MCP endpoints complete authentication successfully.
- Pre-registered OAuth clients can securely provide both client ID and client secret where required.
- Regression coverage includes an MCP endpoint that allows anonymous initialization/catalog discovery but requires OAuth for protected operations.
Summary
netclaw mcp auth <server>fails for Google Workspace MCP servers when the server permits unauthenticated MCP initialization and catalog discovery.Instead of opening an OAuth authorization URL, Netclaw initializes the candidate connection, discovers the tools, then calls
McpOAuthFlowBroker.BeginCommit. Because no OAuth callback occurred and no authorization code was delivered,TryBeginCommitrejects the flow with:The CLI then reports only:
This was reproduced with both Google Docs and Google Drive MCP servers, so it appears to be a generic explicit-reauthorization lifecycle issue rather than a Docs-specific failure.
Environment
netclaw updatereports this as the current release.Configuration shape
Google Docs:
Google Drive is similarly configured with
https://drivemcp.googleapis.com/mcp/v1and the same pre-registered client ID.Both servers report connected before explicit authorization:
Reproduction
Configure either Google Workspace MCP endpoint as an HTTP server with
OAuthClientId.Start Netclaw. The server connects and its tool catalog is discovered.
Run:
Observe that no browser authorization flow starts and the CLI reports connection initialization failure.
The same result occurs with:
Daemon log
Root cause analysis
In the installed source,
BuildAndPublishCandidateAsyncperforms the following sequence:_flowBroker.BeginCommit(authorizationFlow).Source:
McpClientManager.cs.TryBeginCommitrequires_codeDelivered == true. That flag is set only when the local OAuth callback delivers an authorization code.Source:
McpOAuthFlowBroker.csandTryBeginCommit.Google's MCP endpoint permits initialization/catalog discovery without first producing an OAuth challenge. Consequently, the SDK never invokes the interactive authorization callback,
_codeDeliveredremains false, andBeginCommitrejects the otherwise successfully initialized candidate.Google interoperability gaps discovered during diagnosis
These are related and may warrant either inclusion in this fix or separate issues.
Pre-registered client secret cannot be configured
Google documents creating a Web application OAuth client and configuring both its client ID and client secret for the Google Docs MCP server:
https://developers.google.com/workspace/docs/api/guides/configure-mcp-server#configure-mcp-client
McpServerEntrycurrently exposesOAuthClientIdbut no configured OAuth client-secret field:https://github.com/netclaw-dev/netclaw/blob/124f7a1263214f55c10ce01dbf422dfe96e93a0f/src/Netclaw.Configuration/McpServerEntry.cs
Moreover, when
OAuthClientIdis configured,BuildOAuthOptionsexplicitly supplies a null client secret:Source:
netclaw/src/Netclaw.Daemon/Mcp/McpClientManager.cs
Lines 1405 to 1425 in 124f7a1
This means Netclaw cannot currently represent Google's documented confidential-client configuration.
Redirect URI
Netclaw uses:
Source:
netclaw/src/Netclaw.Daemon/Mcp/McpClientManager.cs
Lines 1445 to 1446 in 124f7a1
That exact URI must be added to the Google Web application's authorized redirect URIs.
Documented scopes
Google currently documents four scopes for Docs MCP:
Source: https://developers.google.com/workspace/docs/api/guides/configure-mcp-server#configure-consent-screen
The missing Drive scopes do not cause the immediate
BeginCommitfailure, but may affect document discovery/access after OAuth succeeds.Expected behavior
netclaw mcp authshould proactively perform OAuth discovery and produce an authorization request even when MCP initialization/catalog discovery succeeds anonymously. It should not treat successful anonymous initialization as completion of an explicit authorization attempt.For Google Workspace compatibility, a pre-registered confidential client should also support securely configured client-secret material.
Suggested acceptance criteria