Protocol-gated tools (delete_repository) are listed based on the client's requested protocolVersion string, not the negotiated version

Open
#3,763 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 2 days

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
43/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
go
Domain
api, backend

Research direction

Start with pkg/inventory/tool_availability.go at the reported checks around lines 120, 136, 148–151, and 175; then read the pinned SDK implementation in mcp/shared.go around lines 674–686. Trace how initialization negotiates the session protocol version and how tool availability handles unknown versions. Done means delete_repository is omitted when the negotiated version is below the minimum, unknown requested strings do not qualify as newer, and the stated elicitation and read-only conditions still hold.

Written by the indexing model from the issue text.

Description

Describe the bug

delete_repository is meant to be available only to sessions on protocol ≥ 2026-07-28 with form elicitation. The availability check reads req.ProtocolVersion(). For a session started with initialize, that returns the version the client requested (InitializeParams.ProtocolVersion), not the version the server answered. The comparison is also a plain string compare. As a result:

  • A client that requests 2026-07-28 is negotiated down to 2025-11-25 (deliberate in go-sdk, since initialize is deprecated in 2026-07-28), yet tools/list includes delete_repository.
  • Any string that sorts after 2026-07-28, such as zzz, does the same.

Impact is low. By code reading (not tested), --read-only should still remove the tool and deletion still requires the elicitation confirmation. But the listed tool set doesn't match the protocol the session actually speaks.

Upstream context: go-sdk issue modelcontextprotocol/go-sdk#1258 (closed 2026-11-03 by go-sdk PR #1266) fixed the same requested-vs-negotiated confusion inside the SDK, through an unexported ServerSession.protocolVersion(). The public ServerRequest.ProtocolVersion() on go-sdk main still returns InitializeParams.ProtocolVersion. That fix isn't in a go-sdk release yet (latest v1.8.0, which this repo pins), so a go-sdk bump alone will not change this server's behaviour.

Code (main 99d6d650, unchanged since v2.1.0): pkg/inventory/tool_availability.go:120,136,175 (req.ProtocolVersion()), :148-151 (protocolVersion >= minimum, string compare). go-sdk v1.8.0 mcp/shared.go:674-686 (ServerRequest.ProtocolVersion).

Affected version

v2.1.0 (image sha256:f6056fc1…0f8a, commit 4bcdcdf8) and main nightly (image sha256:48bc16d0…338f, revision 99d6d650). stdio, --toolsets=all.

Steps to reproduce the behavior
  1. initialize:
    {"protocolVersion":"2026-07-28","capabilities":{"elicitation":{"form":{}}},"clientInfo":{"name":"t","version":"0"}}
    
    The result has protocolVersion: "2025-11-25". tools/list: 92 tools, including delete_repository.
  2. Same with "protocolVersion":"zzz","capabilities":{"elicitation":{}}. Negotiated 2025-11-25, 92 tools, including delete_repository.
  3. Same with "protocolVersion":"2025-11-25" and form elicitation: 91 tools, no delete_repository.
  4. "2026-07-28" without an elicitation capability: 91 tools, no delete_repository.
Expected vs actual behavior

Expected: availability follows the negotiated version (2025-11-25 in steps 1 and 2), so delete_repository is not listed. Unknown version strings are not treated as newer.

Actual: the requested string decides, and zzz counts as newer than 2026-07-28.

Suggested fix: gate on the negotiated version. Either have go-sdk expose it, or make ServerRequest.ProtocolVersion() return it (a follow-up to go-sdk #1266). Meanwhile, when there is no per-request _meta version, cap the session value to the initialize result's version. Compare against a list of known versions, not lexically.

Logs
requested 2026-07-28 + elicitation.form -> negotiated 2025-11-25, tools/list 92, delete_repository listed
requested zzz        + elicitation      -> negotiated 2025-11-25, tools/list 92, delete_repository listed
requested 2025-11-25 + elicitation.form -> negotiated 2025-11-25, tools/list 91
requested 2026-07-28, no elicitation    -> negotiated 2025-11-25, tools/list 91

Same on v2.1.0 and main.

Found during an independent audit of v2.1.0 on a throwaway org and private test repo. Prepared with AI assistance (Claude Code); reproduced by two independent test runs before filing.

Dominant language
Go
Stars
34.2k
Forks
5.3k
Avg merge
5d 18h
Merged PRs (30d)
13

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from github/github-mcp-server

All issues in github/github-mcp-server

Similar issues

More Go issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.