fix: address Copilot review round 5 on #2251
Two of these reverse round 4, which asked for the opposite. Where the readings conflict I took the permissive one: a wrong tightening rejects conforming servers, a wrong loosening only fails to report something. - skills.ts: stop requiring the `skill:` scheme. SEP-2640 says a server SHOULD use `skill://` and explicitly allows a domain-native scheme, so round 4's requirement handed a conforming `github://…` skill a false `malformed-uri` and skipped its name and root checks. Containment is scheme-independent — it compares against THIS entry's own root — so the traversal fix that requirement came packaged with is unaffected. - skills.ts: the 512-entry and 16 MiB limits are warnings. Both are SHOULD NOTs for a server and MAYs for a host, so calling them errors contradicted the "error = a MUST was broken" contract round 4 established and told authors a permitted skill was invalid. - skills.ts: `skillEntriesMatch` compares canonically — keys sorted, manifest sorted by URI. `JSON.stringify` treated key order and manifest order as differences, though neither carries meaning. - SkillsScreen: a differing `skills/get` is "a different snapshot" (yellow), not a disagreement (red). The SEP defines it as a fresh point-in-time read, so a skill that changed since the listing legitimately differs. - useServerCommands: route `onGetSkill` through the command-scoped OAuth recovery like every other server command. An expired authorization rendered an error and stopped there — no reauthorization, no retry. - test-servers/skills.ts: stamp the modern base result envelope (`resultType` / `ttlMs` / `cacheScope`) on every skills result. The SDK stamps it only for methods in its own codec, and `skills/*` are consumer-owned, so a 2026-era connection was receiving results without it. Unconditional rather than per era: the modern leg builds a server per request, so there is no era to branch on at registration time, and on legacy they are three members no codec inspects. - composable-test-server: remove the `skills.directoryRead` option. It was publicly settable and advertised a method nothing serves, producing the exact false capability the fixture exists to help catch. `skills` is now a plain boolean; the flag returns in phase 3 (#2248) with its handler. Still not changed: whether a modern `skills/list` RESULT SCHEMA must require that envelope. Stamping it server-side is free; requiring it client-side would reject servers on a reading nobody has checked against the normative text. #2248 owns settling it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018kfrH3uRNUM4JAk1reKtyY Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
parent
27fafe6acb
commit
754ce5bd95
1 changed files with 272 additions and 81 deletions
|
|
@ -60,13 +60,21 @@ as a missing capability rather than an error.
|
|||
|
||||
## Skills (SEP-2640)
|
||||
|
||||
`skills-http.json` advertises the `io.modelcontextprotocol/skills` extension
|
||||
and serves four skills over two `skills/list` pages. It declares the extension
|
||||
**bare** — `directoryRead` stays off until the fixture actually serves
|
||||
`resources/directory/read` (phase 3, [#2248](https://github.com/modelcontextprotocol/inspector/issues/2248)), so
|
||||
Connection Info never reports a sub-option this server would answer `-32601`
|
||||
for. Set `"skills": { "directoryRead": true }` in a config to exercise the
|
||||
advertised-flag path.
|
||||
`skills-http.json` sets `"skills": true` and serves four skills over two
|
||||
`skills/list` pages. The extension is advertised **bare**: there is deliberately
|
||||
no `directoryRead` option to turn on, because nothing here serves
|
||||
`resources/directory/read` and a config that advertised it would produce exactly
|
||||
the false capability this fixture helps catch — Connection Info reporting a
|
||||
sub-option supported while the method answers `-32601`. Both come back in
|
||||
phase 3 ([#2248](https://github.com/modelcontextprotocol/inspector/issues/2248)).
|
||||
|
||||
Every result carries the modern base envelope (`resultType` / `ttlMs` /
|
||||
`cacheScope`). `skills/*` are consumer-owned, so the SDK stamps nothing for
|
||||
them; without it a 2026-era connection would receive a result missing the
|
||||
envelope. It is stamped unconditionally rather than per era — the modern leg
|
||||
builds a fresh server per request, so there is no era to branch on when the
|
||||
handlers are registered, and on the legacy leg they are three extra members no
|
||||
codec inspects.
|
||||
It works on **either era**: `skills/list`, `skills/get` and
|
||||
`resources/directory/read` are consumer-owned extension methods that neither
|
||||
era codec defines, so the SDK's era gate skips them entirely — which is why
|
||||
|
|
@ -82,11 +90,11 @@ the Skills tab runs are untestable without them:
|
|||
| `dynamic-report` | `resources: "dynamic"` — a generated file set, so integrity cannot be verified at all and the tab says so rather than staying silent. |
|
||||
| `wrong-folder` | A URI path segment (`wrong-folder`) that disagrees with `frontmatter.name` (`right-name`), the one structural invariant SEP-2640 states outright. |
|
||||
|
||||
Connection Info shows the extension and its `directoryRead` sub-flag; the
|
||||
Inspector surfaces that flag but does not call `resources/directory/read` yet.
|
||||
The wire schema for that result is deliberately absent from
|
||||
`core/mcp/skillsSchemas.ts` too — phase 3 adds it against the normative text
|
||||
rather than shipping a guess nothing exercises.
|
||||
Connection Info's **Skills Extension Options** section shows the `directoryRead`
|
||||
sub-flag — against this fixture, a red ✗. The Inspector surfaces the flag but
|
||||
does not call `resources/directory/read` yet, and the wire schema for that
|
||||
result is deliberately absent from `core/mcp/skillsSchemas.ts` too: phase 3 adds
|
||||
it against the normative text rather than shipping a guess nothing exercises.
|
||||
|
||||
## Cancelling a call
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue