Which version line?
v2 — current (@modelcontextprotocol/inspector@latest)
Which client?
All / shared core
Inspector version
2.6.0
Node version
v24.21.0
Operating system (and browser, for the web client)
macOS 26.6.2, Chrome 153.0.8010.37
Transport
Streamable HTTP
MCP server under inspection
Server: authenticated production MCP server using the SEP-2640 Skills extension
Protocol era: Modern (2026-07-28)
OAuth: yes
The server declares io.modelcontextprotocol/skills and implements:
skills/list
skills/get
resources/directory/read
Steps to reproduce
- Run Inspector 2.6.0.
- Configure a Streamable HTTP server that implements protocol version
2026-07-28.
- Have the server declare the
io.modelcontextprotocol/skills extension.
- Return a valid Modern
skills/list response containing:
resultType: "complete"
ttlMs
cacheScope
skills
- Connect with Protocol Era → Modern.
- Open the Skills tab.
The same problem can be reproduced with Inspector's own Skills integration fixture after correcting its Modern connection setup:
versionNegotiation: eraToVersionNegotiation(
modern ? "modern" : "legacy",
)
The existing test instead sets protocolEra on MCPServerConfig. That field does not configure InspectorClient's SDK negotiation, so the test's purported Modern leg actually negotiates Legacy.
Expected behavior
The SDK should validate the raw Modern resultType, and Inspector should validate the decoded extension result.
A conforming response should populate the Skills tab.
Actual behavior
Inspector rejects the response:
Invalid result for skills/list: resultType: Invalid input: expected "complete"
Equivalent failures occur for the other Skills extension methods:
Invalid result for skills/get: resultType: Invalid input: expected "complete"
Invalid result for resources/directory/read: resultType: Invalid input: expected "complete"
Logs, errors, or screenshots
Diagnosis
The server's raw JSON-RPC response does contain the required discriminator:
{
"jsonrpc": "2.0",
"id": 0,
"result": {
"resultType": "complete",
"ttlMs": 0,
"cacheScope": "private",
"skills": [],
"nextCursor": "..."
}
}
The TypeScript SDK 2.0.0 Modern codec:
- Validates
resultType on the raw response.
- Rejects a missing or unsupported discriminator.
- Copies the result and deletes
resultType.
- Passes that decoded result to Inspector's supplied schema.
Inspector's extension schemas then require the already-consumed field again:
export const ModernListSkillsResultSchema =
ListSkillsResultSchema.extend({
resultType: z.literal("complete"),
ttlMs: z.int().min(0),
cacheScope: z.enum(["public", "private"]),
});
Consequently, no valid Modern response can satisfy both layers: omitting resultType fails SDK decoding, while including it succeeds in SDK decoding and then fails Inspector's post-decoding schema.
Existing-test gap
inspectorClient-skills.test.ts intends to exercise both eras, but its connection helper puts protocolEra in the server configuration instead of passing versionNegotiation to the InspectorClient options.
After fixing that setup without changing the production schemas, the real-transport suite produces eight Modern failures covering:
skills/list
- managed Skills pagination
skills/get
resources/directory/read
- whole-catalog verification
All fail with the corresponding resultType validation error.
Already prototyped a fix?
Suggested fix
Keep resultType mandatory on the wire, with validation owned by the SDK's Modern codec.
Do not require the wire-only discriminator again in Inspector's schemas, because those schemas receive the decoded representation:
export const ModernListSkillsResultSchema =
ListSkillsResultSchema.extend({
ttlMs: z.int().min(0),
cacheScope: z.enum(["public", "private"]),
});
export const ModernGetSkillEnvelopeSchema =
GetSkillEnvelopeSchema;
export const ModernDirectoryReadResultSchema =
DirectoryReadResultSchema;
This preserves the intentional behavior:
- The SDK still strictly requires
resultType: "complete" on Modern wire responses.
- Inspector still requires
ttlMs and cacheScope for Modern skills/list.
skills/get and resources/directory/read retain their SEP-2640 caching semantics.
The integration test should also pass the intended negotiation mode explicitly and assert the negotiated era:
const connected = new InspectorClient(
{ type: "streamable-http", url },
{
environment: { transport: createTransportNode },
versionNegotiation: eraToVersionNegotiation(
modern ? "modern" : "legacy",
),
},
);
expect(connected.getProtocolEra()).toBe(era);
Prototype validation
Codex produced and reviewed a local prototype at my request. Nothing was pushed or submitted upstream.
Observed validation:
- Unmodified schemas plus corrected Modern test setup:
- Proposed schema fix plus corrected test setup:
- Focused unit tests:
- Full web validation:
- 344 test files passed
- 6,459 tests passed
- formatting, lint, TypeScript build, and Vite build passed
Prompt used for the prototype
Investigate why Inspector 2.6.0 rejects valid Modern SEP-2640 responses with Invalid result for skills/list: resultType: Invalid input. Preserve the intentional requirement that Modern wire responses contain resultType: "complete". Trace the TypeScript SDK 2.0.0 decoding pipeline before changing the Inspector schemas. Verify whether the SDK validates and consumes resultType before applying caller-provided schemas. Audit skills/list, skills/get, and resources/directory/read for the same layering problem. Correct the Skills real-transport integration test so it genuinely negotiates both Legacy and Modern, assert the negotiated era, reproduce the failure on unmodified production schemas, implement the smallest fix at the correct layer, and run the focused and full web validation suites. Do not push or open a pull request.
Before you submit
Which version line?
v2 — current (
@modelcontextprotocol/inspector@latest)Which client?
All / shared core
Inspector version
2.6.0
Node version
v24.21.0
Operating system (and browser, for the web client)
macOS 26.6.2, Chrome 153.0.8010.37
Transport
Streamable HTTP
MCP server under inspection
Server: authenticated production MCP server using the SEP-2640 Skills extension
Protocol era: Modern (
2026-07-28)OAuth: yes
The server declares
io.modelcontextprotocol/skillsand implements:skills/listskills/getresources/directory/readSteps to reproduce
2026-07-28.io.modelcontextprotocol/skillsextension.skills/listresponse containing:resultType: "complete"ttlMscacheScopeskillsThe same problem can be reproduced with Inspector's own Skills integration fixture after correcting its Modern connection setup:
The existing test instead sets
protocolEraonMCPServerConfig. That field does not configureInspectorClient's SDK negotiation, so the test's purported Modern leg actually negotiates Legacy.Expected behavior
The SDK should validate the raw Modern
resultType, and Inspector should validate the decoded extension result.A conforming response should populate the Skills tab.
Actual behavior
Inspector rejects the response:
Equivalent failures occur for the other Skills extension methods:
Logs, errors, or screenshots
Diagnosis
The server's raw JSON-RPC response does contain the required discriminator:
{ "jsonrpc": "2.0", "id": 0, "result": { "resultType": "complete", "ttlMs": 0, "cacheScope": "private", "skills": [], "nextCursor": "..." } }The TypeScript SDK 2.0.0 Modern codec:
resultTypeon the raw response.resultType.Inspector's extension schemas then require the already-consumed field again:
Consequently, no valid Modern response can satisfy both layers: omitting
resultTypefails SDK decoding, while including it succeeds in SDK decoding and then fails Inspector's post-decoding schema.Existing-test gap
inspectorClient-skills.test.tsintends to exercise both eras, but its connection helper putsprotocolErain the server configuration instead of passingversionNegotiationto theInspectorClientoptions.After fixing that setup without changing the production schemas, the real-transport suite produces eight Modern failures covering:
skills/listskills/getresources/directory/readAll fail with the corresponding
resultTypevalidation error.Already prototyped a fix?
Suggested fix
Keep
resultTypemandatory on the wire, with validation owned by the SDK's Modern codec.Do not require the wire-only discriminator again in Inspector's schemas, because those schemas receive the decoded representation:
This preserves the intentional behavior:
resultType: "complete"on Modern wire responses.ttlMsandcacheScopefor Modernskills/list.skills/getandresources/directory/readretain their SEP-2640 caching semantics.The integration test should also pass the intended negotiation mode explicitly and assert the negotiated era:
Prototype validation
Codex produced and reviewed a local prototype at my request. Nothing was pushed or submitted upstream.
Observed validation:
Prompt used for the prototype
Before you submit