Thanks to visit codestin.com
Credit goes to github.com

Skip to content

fix(coderd): accept RFC 9728 resource metadata with array-valued resource - #28592

Merged
f0ssel merged 1 commit into
mainfrom
fix/mcp-oauth2-resource-array
Aug 26, 2026
Merged

fix(coderd): accept RFC 9728 resource metadata with array-valued resource#28592
f0ssel merged 1 commit into
mainfrom
fix/mcp-oauth2-resource-array

Conversation

@f0ssel

@f0ssel f0ssel commented Aug 25, 2026

Copy link
Copy Markdown
Member

GitLab's official MCP server returns "resource" as a JSON array in its /.well-known/oauth-protected-resource document, while RFC 9728 §2 defines it as a string. Coder's OAuth2 auto-discovery failed to decode the response (json: cannot unmarshal array into Go struct field protectedResourceMetadata.resource of type string), blocking zero-config oauth2 DCR against GitLab.

This makes protectedResourceMetadata.Resource tolerate both a single string and an array of strings.

Part of CODAGT-570. The other blocker in that issue (GitLab replying 204 to notifications/initialized) was already fixed by the migration from mark3labs/mcp-go to modelcontextprotocol/go-sdk, whose streamable-HTTP client accepts 204.

Investigation notes

CODAGT-570 reported two independent incompatibilities with GitLab CE's /api/v4/mcp server:

  1. 204 vs 202 on notifications/initialized (blocked all auth modes): the bundled mark3labs/mcp-go client only accepted 200/202 for notification POSTs. That library has since been removed entirely; coderd/x/chatd/mcpclient now uses github.com/modelcontextprotocol/go-sdk v1.7.0, which accepts both 204 and 202 (and only warns on other codes in non-strict mode, which is the only mode reachable from Coder). No further change needed.
  2. RFC 9728 resource array (blocked zero-config oauth2 DCR): Coder's own parser in coderd/mcp.go declared Resource string. This lives outside the MCP library, so the SDK migration did not fix it. Fixed here with a custom UnmarshalJSON accepting string or array of strings. The field is only decoded, never consumed downstream, so behavior is otherwise unchanged.

Generated by Coder Agents on behalf of @f0ssel.

…urce

GitLab's official MCP server returns "resource" as a JSON array in its
/.well-known/oauth-protected-resource document, while RFC 9728 defines
it as a string. Coder's OAuth2 auto-discovery failed to decode the
array, blocking zero-config oauth2 DCR against GitLab. Tolerate both a
single string and an array of strings.

Part of CODAGT-570. The other half of that issue (204 responses to
notifications) was already fixed by the migration to
modelcontextprotocol/go-sdk.
@linear-code

linear-code Bot commented Aug 25, 2026

Copy link
Copy Markdown

CODAGT-570

@f0ssel
f0ssel marked this pull request as ready for review August 25, 2026 19:34
@f0ssel
f0ssel requested review from ibetitsmike and removed request for ibetitsmike August 25, 2026 19:38
@f0ssel

f0ssel commented Aug 25, 2026

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🎉

Reviewed commit: d5e2e29160

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@f0ssel
f0ssel requested a review from ibetitsmike August 25, 2026 19:47
@f0ssel f0ssel assigned mafredri and unassigned mafredri Aug 25, 2026
@f0ssel
f0ssel requested a review from mafredri August 25, 2026 19:47
@f0ssel
f0ssel merged commit 50f3631 into main Aug 26, 2026
55 of 56 checks passed
@f0ssel
f0ssel deleted the fix/mcp-oauth2-resource-array branch August 26, 2026 16:27
@github-actions

Copy link
Copy Markdown
Contributor

Cherry-pick PR created: #28647

@github-actions github-actions Bot locked and limited conversation to collaborators Aug 26, 2026

f0ssel commented Aug 27, 2026

Copy link
Copy Markdown
Member Author

Live verification against GitLab CE 19.0.1

Ran this branch against the exact setup from CODAGT-570: gitlab/gitlab-ce:19.0.1-ce.0 in Docker with an mcp-scoped root PAT.

Both quirks reproduced with curl:

  • initialize → 200, "Official GitLab MCP Server" v19.0.1
  • notifications/initialized → HTTP 204
  • /.well-known/oauth-protected-resource"resource": ["…/api/v4/mcp", "…/api/v4/orbit/mcp"] (array)

Gap 1 (204 handshake), fixed by the earlier modelcontextprotocol/go-sdk migration: mcpclient.ConnectAll with auth_type: api_key (Bearer PAT) connected and enumerated all 17 GitLab tools (gitlab__create_issue, gitlab__create_merge_request, gitlab__search, …).

Gap 2 (resource array), fixed by this PR: the real POST /mcp-servers handler with auth_type: oauth2 and no client fields succeeded end-to-end via a throwaway test on a coderdtest server: discovery parsed the array metadata and DCR registered a client at GitLab's /oauth/register (auth_url=…/oauth/authorize, token_url=…/oauth/token).

Negative control: same test with coderd/mcp.go reverted to origin/main reproduced the exact error from the issue:

protected resource discovery: discover protected resource metadata:
decode JSON from http://127.0.0.1:8929/.well-known/oauth-protected-resource:
json: cannot unmarshal array into Go struct field protectedResourceMetadata.resource of type string

Together with the SDK migration, this PR fully resolves CODAGT-570.


Generated by Coder Agents on behalf of @f0ssel.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants