chore(deps)(deps): bump github.com/mark3labs/mcp-go from 0.58.0 to 1.0.0 (#1275)

* chore(deps)(deps): bump github.com/mark3labs/mcp-go from 0.58.0 to 1.0.0

Bumps [github.com/mark3labs/mcp-go](https://github.com/mark3labs/mcp-go) from 0.58.0 to 1.0.0.
- [Release notes](https://github.com/mark3labs/mcp-go/releases)
- [Commits](https://github.com/mark3labs/mcp-go/compare/v0.58.0...v1.0.0)

---
updated-dependencies:
- dependency-name: github.com/mark3labs/mcp-go
  dependency-version: 1.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* fix(mcp): pad owns the protocol revision it advertises, not the library (TASK-2972)

mcp-go 1.0 moves LATEST_PROTOCOL_VERSION to 2026-07-28. `MetaPayload.
MCPProtocolVersion` was sourced from that constant, on the reasoning — written
in the comment — that doing so meant the value "never drifts from what
NewMCPServer actually advertises in the handshake".

1.0 falsified that, and in the direction the comment was guarding against. The
handshake answers through `mcp.NegotiateLegacyVersion`, which returns at most
LATEST_LEGACY_PROTOCOL_VERSION and CANNOT return the modern revision at all:
measured, a client asking for 2026-07-28 is told 2025-11-25, and a client that
sends nothing is told 2025-03-26. So the bump would have left the handshake
where it was and moved the meta document alone — publishing a claim to
negotiate a revision this server cannot negotiate.

The advertised revision is now a pad-owned literal. Moving it means reading the
new revision's delta against this server's surface first; a library bump must
not move it on its own.

The test that should have caught this was a tautology: it compared the payload
against the same constant the payload was built from, so it could not fail, and
it would have passed through this bump. Replaced with two assertions that each
catch what the other cannot — against the LITERAL, so moving pad's claim is a
deliberate edit visible in a diff, and against what the library's handshake
ACTUALLY answers, which is the property the old comment claimed and never had.
Both legs verified to fail when the constant is moved.

Refs: TASK-2972

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: xarmian <xarmian@gmail.com>
This commit is contained in:
dependabot[bot]
2026-09-09 14:25:08 -04:00
committed by GitHub
parent cbfc073ef1
commit 31d11e76ea
4 changed files with 66 additions and 19 deletions
+1 -1
View File
@@ -27,7 +27,7 @@ require (
github.com/google/uuid v1.6.0
github.com/gorilla/websocket v1.5.3
github.com/jackc/pgx/v5 v5.10.0
github.com/mark3labs/mcp-go v0.58.0
github.com/mark3labs/mcp-go v1.0.0
github.com/ory/fosite v0.49.0
github.com/pb33f/libopenapi v0.38.7
github.com/pquerna/otp v1.5.0
+2 -2
View File
@@ -339,8 +339,8 @@ github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/luna-duclos/instrumentedsql v1.1.3/go.mod h1:9J1njvFds+zN7y85EDhN9XNQLANWwZt2ULeIC8yMNYs=
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/mark3labs/mcp-go v0.58.0 h1:AWfBk8lgRR0KZYve7PaLbR2MIjpw1oK2eGpBApaNS+Q=
github.com/mark3labs/mcp-go v0.58.0/go.mod h1:+8WclSK1ZUweCP3hvktSji8n8ABG/95QaEkeVE/Uwas=
github.com/mark3labs/mcp-go v1.0.0 h1:CZqCzXwUiTOstkIdW1MyOZGuM+LaKMEJSu+ZYluN4DU=
github.com/mark3labs/mcp-go v1.0.0/go.mod h1:r2fW4o3wsoJ7IMsx1Wuq5xeP8PRGXPDfNveoGAYbb/s=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
+29 -10
View File
@@ -33,11 +33,24 @@ type MetaPayload struct {
ToolSurfaceStable bool `json:"tool_surface_stable"`
// MCPProtocolVersion is the latest MCP wire protocol revision this
// server can negotiate. Sourced from the underlying mcp-go library's
// LATEST_PROTOCOL_VERSION constant so the value never drifts from
// what NewMCPServer actually advertises in the handshake. Surfaced
// so consumers can detect feature support (e.g. RFC 8707 Resource
// Indicators land in the 2025-11-25 revision).
// server can negotiate. Surfaced so consumers can detect feature
// support (e.g. RFC 8707 Resource Indicators land in the 2025-11-25
// revision).
//
// It is a PAD-OWNED constant, not the library's LATEST_PROTOCOL_VERSION.
// It was the library's until mcp-go 1.0, on the reasoning that sourcing
// it there meant it "never drifts from what NewMCPServer actually
// advertises". 1.0 falsified that: LATEST_PROTOCOL_VERSION moved to
// 2026-07-28, while the handshake answers through
// mcp.NegotiateLegacyVersion, which returns at most
// LATEST_LEGACY_PROTOCOL_VERSION (2025-11-25) and cannot return the
// modern revision at all. Sourcing from LATEST would therefore have
// CAUSED the drift it was meant to prevent, and published a claim to
// negotiate a revision this server cannot negotiate.
//
// So the advertised revision is a claim pad makes deliberately. Moving
// it means reading the new revision's delta against this server's
// surface first; a library bump must not move it on its own.
MCPProtocolVersion string `json:"mcp_protocol_version"`
}
@@ -46,11 +59,17 @@ type MetaPayload struct {
// same reason serverInfo.version does — empty values confuse some
// clients that display them in their UI.
//
// MCPProtocolVersion is sourced from mcp.LATEST_PROTOCOL_VERSION, which
// is the maximum protocol revision the server can negotiate. If a
// client downgrades during initialize, the per-session negotiated
// version may be lower; the meta document reports the server's
// MCPProtocolVersion reports the maximum protocol revision this server can
// negotiate. If a client downgrades during initialize, the per-session
// negotiated version may be lower; the meta document reports the server's
// upper bound, not any specific session.
// AdvertisedMCPProtocolVersion is the MCP wire protocol revision pad claims
// to negotiate. It is deliberately a literal rather than a library constant —
// see MetaPayload.MCPProtocolVersion — and TestAdvertisedProtocolVersion pins
// it to what the library's handshake actually answers, so a bump that moves
// one and not the other fails instead of shipping a false claim.
const AdvertisedMCPProtocolVersion = "2025-11-25"
func BuildMetaPayload(padVersion string) MetaPayload {
if padVersion == "" {
padVersion = FallbackVersion
@@ -60,7 +79,7 @@ func BuildMetaPayload(padVersion string) MetaPayload {
CmdhelpVersion: CmdhelpVersion,
ToolSurfaceVersion: ToolSurfaceVersion,
ToolSurfaceStable: true,
MCPProtocolVersion: mcp.LATEST_PROTOCOL_VERSION,
MCPProtocolVersion: AdvertisedMCPProtocolVersion,
}
}
+34 -6
View File
@@ -27,13 +27,41 @@ func TestBuildMetaPayload_FallbackVersion(t *testing.T) {
if !got.ToolSurfaceStable {
t.Errorf("ToolSurfaceStable = false, want true")
}
if got.MCPProtocolVersion != mcp.LATEST_PROTOCOL_VERSION {
t.Errorf("MCPProtocolVersion = %q, want library LATEST %q",
got.MCPProtocolVersion, mcp.LATEST_PROTOCOL_VERSION)
if got.MCPProtocolVersion != AdvertisedMCPProtocolVersion {
t.Errorf("MCPProtocolVersion = %q, want %q",
got.MCPProtocolVersion, AdvertisedMCPProtocolVersion)
}
// Belt-and-braces: never empty, regardless of library state.
if got.MCPProtocolVersion == "" {
t.Errorf("MCPProtocolVersion is empty — library constant unset?")
}
// TestAdvertisedProtocolVersion is what replaced a tautology. The old
// assertion compared the payload against mcp.LATEST_PROTOCOL_VERSION while
// the payload was BUILT from it, so it could not fail — and when mcp-go 1.0
// moved that constant to 2026-07-28 it would have passed while pad published
// a claim to negotiate a revision it cannot negotiate.
//
// Two assertions, and each catches something the other cannot:
//
// - against the LITERAL string, so moving pad's claim is a deliberate edit
// that a reader sees in the diff rather than a consequence of a bump;
// - against what the library's handshake ACTUALLY answers, which is the
// property the old comment claimed and did not have. mcp-go answers
// initialize through NegotiateLegacyVersion, which returns at most
// LATEST_LEGACY_PROTOCOL_VERSION — so a client asking for the newest
// revision is told 2025-11-25, and that is the true upper bound the meta
// document is supposed to report.
func TestAdvertisedProtocolVersion(t *testing.T) {
if AdvertisedMCPProtocolVersion != "2025-11-25" {
t.Errorf("AdvertisedMCPProtocolVersion = %q, want the literal 2025-11-25 — "+
"moving pad's advertised revision needs the new revision's delta read "+
"against this server's surface first", AdvertisedMCPProtocolVersion)
}
// What a client asking for the newest revision is actually told.
handshake := mcp.NegotiateLegacyVersion(mcp.LATEST_PROTOCOL_VERSION)
if handshake != AdvertisedMCPProtocolVersion {
t.Errorf("the handshake answers %q but the meta document advertises %q; "+
"these must agree or the meta document is a false claim about what "+
"this server can negotiate", handshake, AdvertisedMCPProtocolVersion)
}
}