Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
288 commits
Select commit Hold shift + click to select a range
92e485a
fix: address Copilot review round 21 — seed a nested object's own uni…
cliffhall Aug 26, 2026
0be450a
fix: address Copilot review round 22 — merge deep-link args with defa…
cliffhall Aug 26, 2026
4cea4e1
fix: address Copilot review round 23 — inherited constants, branch nu…
cliffhall Aug 26, 2026
1cebe71
fix(smoke): route the Chromium tier through ENGINE_SMOKES too
cliffhall Aug 26, 2026
54c5e12
fix: address Copilot review round 24 — a discriminator must be required
cliffhall Aug 26, 2026
ab3f8c7
fix: address Copilot review round 25 — names before constants, unrend…
cliffhall Aug 26, 2026
93bc7df
fix(smoke): assert the requested engine is the one launched; fix the …
cliffhall Aug 26, 2026
f31589a
fix: address Copilot review round 26 — a false property schema declin…
cliffhall Aug 26, 2026
c8c5442
fix: address Copilot review round 27 — unconstrained null branches, t…
cliffhall Aug 26, 2026
6ac45d9
fix: address Copilot review round 28 — the boolean schema form in a n…
cliffhall Aug 26, 2026
6aa25da
docs: distinguish the partial render from the empty one in the showcase
cliffhall Aug 26, 2026
d5a6de1
Merge branch 'v2/main' into v2/chore/2086-cross-browser-app-smokes
cliffhall Aug 26, 2026
86c143f
docs(smoke): point each smoke's on-demand example at its own command
cliffhall Aug 26, 2026
7db83b1
Merge remote-tracking branch 'origin/v2/chore/2086-cross-browser-app-…
cliffhall Aug 26, 2026
c913168
Merge branch 'v2/main' into v2/fix/2123-root-union-schemas
cliffhall Aug 26, 2026
67e7a4c
fix: address Copilot review round 30 — seed a read-only const for cal…
cliffhall Aug 26, 2026
c9162d0
fix: address Copilot review round 31 — proto-safe results, set-valued…
cliffhall Aug 26, 2026
00d9905
fix: address Copilot review round 32 — normalize before the type vote…
cliffhall Aug 26, 2026
ffa08d7
fix: address Copilot review round 33 — keep a cleared field cleared a…
cliffhall Aug 26, 2026
ba91db9
fix: address Copilot review round 34 — structured constants, non-requ…
cliffhall Aug 26, 2026
139563f
fix: address Copilot review round 35 — reseed on an in-place schema c…
cliffhall Aug 26, 2026
f78b541
fix: address Copilot review round 36 — re-derive the branch when the …
cliffhall Aug 26, 2026
85b030c
fix: address Copilot review round 37 — stale constants, inherited ans…
cliffhall Aug 26, 2026
ab85667
fix: address Copilot review round 38 — constants must agree, not just…
cliffhall Aug 26, 2026
d6e1b43
Merge branch 'v2/main' into v2/chore/2086-cross-browser-app-smokes
cliffhall Aug 26, 2026
4865195
fix: address Copilot review round 39 — identify branches by their sch…
cliffhall Aug 26, 2026
8f935ad
fix: address Copilot review round 40 — a required name counts as a field
cliffhall Aug 26, 2026
b0b252a
fix: address Copilot review round 41 — const does not demand a proper…
cliffhall Aug 26, 2026
2e22b5b
Merge branch 'v2/main' into v2/fix/2123-root-union-schemas
cliffhall Aug 26, 2026
e0ecf58
fix: address Copilot review round 42 — let an optional const be opted…
cliffhall Aug 26, 2026
bd114f8
Merge remote-tracking branch 'origin/v2/fix/2123-root-union-schemas' …
cliffhall Aug 26, 2026
8646a60
Merge pull request #2133 from modelcontextprotocol/v2/chore/2086-cros…
cliffhall Aug 26, 2026
f01ec80
Merge branch 'v2/main' into v2/fix/2123-root-union-schemas
cliffhall Aug 26, 2026
ca12561
Merge pull request #2137 from modelcontextprotocol/v2/fix/2123-root-u…
cliffhall Aug 26, 2026
b6ed507
chore(web): move App.tsx's module-level block into files (#2127)
cliffhall Aug 26, 2026
4b119c9
chore(web): address Copilot review on #2127
cliffhall Aug 26, 2026
78bad6a
Merge pull request #2149 from modelcontextprotocol/v2/chore/2127-app-…
cliffhall Aug 26, 2026
e42968b
chore(web): extract App.tsx's leaf hooks (#2128)
cliffhall Aug 26, 2026
edac58e
chore(web): address Copilot review on #2128
cliffhall Aug 26, 2026
2fca87c
chore(web): record the useProgressToasts return-type exception
cliffhall Aug 27, 2026
5c26da7
Merge pull request #2150 from modelcontextprotocol/v2/chore/2128-app-…
cliffhall Aug 27, 2026
104b3c0
chore(web): collapse App.tsx's six session refs into useSessionRef (#…
cliffhall Aug 27, 2026
dc026ac
chore(web): drop the double cast from the useSessionRef test fixture
cliffhall Aug 27, 2026
b6baa30
fix(scripts): make smoke:tui assert the TUI survives its first frame …
cliffhall Aug 27, 2026
bd7297d
fix(scripts): address Copilot review round 1 on #2147
cliffhall Aug 27, 2026
b7a73e7
fix(scripts): address Copilot review round 2 on #2147
cliffhall Aug 27, 2026
747f598
fix(scripts): disarm the first-paint deadline once the marker is seen…
cliffhall Aug 27, 2026
4af38c7
fix(scripts): don't arm a survival timer after the verdict is settled…
cliffhall Aug 27, 2026
e15dd8a
fix(scripts): make the test stubs drain, and the raw-mode guard testa…
cliffhall Aug 27, 2026
6c9c149
Merge pull request #2152 from modelcontextprotocol/v2/chore/2129-use-…
cliffhall Aug 27, 2026
c05d26e
Merge branch 'v2/main' into v2/fix/2147-smoke-tui-pty
cliffhall Aug 27, 2026
9cd0659
ci: run the coverage gate in a parallel job (#2159)
cliffhall Aug 27, 2026
9ddbec5
ci: rename the workflow to `CI`, and fix a README line this PR made s…
cliffhall Aug 27, 2026
833ad40
Merge pull request #2158 from modelcontextprotocol/v2/fix/2147-smoke-…
cliffhall Aug 27, 2026
20bf0f4
Merge branch 'v2/main' into v2/chore/2159-parallel-coverage-job
cliffhall Aug 27, 2026
ed38a5e
chore(web): extract App.tsx's OAuth recovery cluster into useOAuthRec…
cliffhall Aug 27, 2026
f62410a
chore(web): connected-flow smoke for the Tools, Resources and Prompts…
cliffhall Aug 27, 2026
88ae068
Merge pull request #2160 from modelcontextprotocol/v2/chore/2159-para…
cliffhall Aug 27, 2026
5f875e3
chore(web): address Copilot review on #2153
cliffhall Aug 27, 2026
d710f90
Merge branch 'v2/main' into v2/chore/2148-web-tab-smokes
cliffhall Aug 27, 2026
94f3b2f
Merge branch 'v2/main' into v2/chore/2153-use-oauth-recovery
cliffhall Aug 27, 2026
70fffa8
Merge pull request #2162 from modelcontextprotocol/v2/chore/2153-use-…
cliffhall Aug 27, 2026
23088e9
chore(web): address Copilot review on the tab smoke
cliffhall Aug 27, 2026
11a1bdf
Merge branch 'v2/main' into v2/chore/2148-web-tab-smokes
cliffhall Aug 27, 2026
02a56e8
chore(web): extract App.tsx's MCP Apps wiring into useMcpApps
cliffhall Aug 27, 2026
105f063
Merge pull request #2164 from modelcontextprotocol/v2/chore/2148-web-…
cliffhall Aug 27, 2026
0b64460
chore(scripts): rename the local pre-push gate off `ci`, and guard it…
cliffhall Aug 27, 2026
d79e96b
Merge branch 'v2/main' into v2/chore/2156-use-mcp-apps
cliffhall Aug 27, 2026
95db736
Merge pull request #2166 from modelcontextprotocol/v2/chore/2156-use-…
cliffhall Aug 27, 2026
b18b975
chore(scripts): treat an expression-built script name as forbidden to…
cliffhall Aug 27, 2026
fc83d2a
Merge remote-tracking branch 'origin/v2/main' into v2/chore/2146-rena…
cliffhall Aug 27, 2026
398d074
chore(scripts): scan only executable positions, and match on the expr…
cliffhall Aug 27, 2026
ed2070f
chore(web): extract App.tsx's connection lifecycle into useConnection…
cliffhall Aug 27, 2026
b8d3cfd
chore(scripts): parse the workflow instead of matching lines (#2146)
cliffhall Aug 27, 2026
8b02329
chore(scripts): walk the workflow schema's executable paths, and reso…
cliffhall Aug 27, 2026
005e4c6
chore(web): address Copilot review on #2154
cliffhall Aug 27, 2026
6d2806d
chore(scripts): make the browser rule kind-aware, cover container.env…
cliffhall Aug 27, 2026
c37e795
test(web): assert the deep-link 409 race actually reaches the connect…
cliffhall Aug 27, 2026
74aa94f
chore(scripts): detect a SMOKE_BROWSER assignment in any shell dialec…
cliffhall Aug 27, 2026
47b3c6f
chore(scripts): read a shell-expanded name as unreadable, and env key…
cliffhall Aug 27, 2026
53e773d
chore(scripts): stop the assignment capture at the closing quote (#2146)
cliffhall Aug 27, 2026
bc7abae
chore(scripts): accept a dynamic SetEnvironmentVariable argument as a…
cliffhall Aug 27, 2026
1a2a36f
feat(web): use the Ace JSON editor everywhere, and restore the raw-JS…
cliffhall Aug 27, 2026
2ead041
chore(scripts): scan the shell command template, and flag a multi-lin…
cliffhall Aug 27, 2026
c9fb461
fix(web): address Copilot review on the shared JSON editor
cliffhall Aug 27, 2026
0c0d5fa
chore(scripts): cover PowerShell's Env: drive, and correct two stale …
cliffhall Aug 27, 2026
b4083ee
fix(web): reject non-finite numbers, and keep the branch picker with …
cliffhall Aug 27, 2026
12c00d8
fix(web): re-apply the editor's accessible name, and correct the READ…
cliffhall Aug 27, 2026
5abe289
fix(web): seed Edit-and-replay from what replay sends, name each JSON…
cliffhall Aug 27, 2026
4e7537e
fix(web): validate the edited replay draft, not just its seed
cliffhall Aug 27, 2026
0e9069a
fix(web): reject a reshaped replay param, and forward a declared JSON…
cliffhall Aug 27, 2026
8f4aa7f
fix(web): reject drafts whose digits or types would not survive being…
cliffhall Aug 27, 2026
fcdc65b
fix(web): read the literal, not the parsed number; project cursors an…
cliffhall Aug 27, 2026
03bf9ec
fix(web): resolve the replay tool from the draft, and say why a draft…
cliffhall Aug 27, 2026
390e0c4
fix(web): stop the read-only viewer reformatting a payload into a dif…
cliffhall Aug 27, 2026
1b28fc8
fix(web): detect duplicate object keys, which JSON.parse drops silently
cliffhall Aug 27, 2026
8aa6f01
fix(web): reject a negative-zero literal, which loses its sign when s…
cliffhall Aug 27, 2026
684eb9c
fix(web): reject an underflowing literal, and route embedded JSON res…
cliffhall Aug 27, 2026
df53d71
Merge pull request #2167 from modelcontextprotocol/v2/chore/2146-rena…
cliffhall Aug 27, 2026
6bd2841
Merge branch 'v2/main' into v2/chore/2154-use-connection-lifecycle
cliffhall Aug 27, 2026
592446f
Merge branch 'v2/main' into v2/feat/2151-ace-json-editor
cliffhall Aug 27, 2026
7a3a30b
Merge pull request #2169 from modelcontextprotocol/v2/chore/2154-use-…
cliffhall Aug 28, 2026
ccd9908
Merge branch 'v2/main' into v2/feat/2151-ace-json-editor
cliffhall Aug 28, 2026
6bc3251
Merge pull request #2170 from modelcontextprotocol/v2/feat/2151-ace-j…
cliffhall Aug 28, 2026
00f1733
chore(web): extract App.tsx's server commands into useServerCommands
cliffhall Aug 28, 2026
5c7c518
chore(web): address Copilot review on #2155
cliffhall Aug 28, 2026
8535ae0
fix(core): say why a never-acknowledged subscriptions/listen ended
cliffhall Aug 28, 2026
f7fe4bc
test(web): make the harness's recovery wrapper actually recover
cliffhall Aug 28, 2026
71cd113
chore(web): fix a duplicated word in a moved comment
cliffhall Aug 28, 2026
9136ab6
fix(test-servers): describe and test after-first's resource-subscript…
cliffhall Aug 28, 2026
222b65d
Merge branch 'v2/main' into v2/chore/2155-use-server-commands
cliffhall Aug 28, 2026
2856f82
Merge pull request #2173 from modelcontextprotocol/v2/chore/2155-use-…
cliffhall Aug 28, 2026
31ce682
Merge branch 'v2/main' into v2/fix/2097-never-acknowledged-subscription
cliffhall Aug 28, 2026
37e156c
fix(web): surface failed resource subscribe/unsubscribe (#2174)
cliffhall Aug 28, 2026
4d69dbf
Merge pull request #2176 from modelcontextprotocol/v2/fix/2097-never-…
cliffhall Aug 28, 2026
9516299
fix(web): refuse a raw-JSON tool argument the schema would retype (#2…
cliffhall Aug 28, 2026
0425516
chore(web): collapse InspectorView's prop wall into domain bundles (#…
cliffhall Aug 28, 2026
667ec74
Merge pull request #2179 from modelcontextprotocol/v2/fix/2174-subscr…
cliffhall Aug 28, 2026
61f58f9
test(web): pin that a refused raw-JSON draft dispatches nothing (#2171)
cliffhall Aug 28, 2026
904cbf9
Merge branch 'v2/main' into v2/fix/2171-raw-json-no-coercion
cliffhall Aug 28, 2026
baff393
Merge pull request #2175 from modelcontextprotocol/v2/fix/2171-raw-js…
cliffhall Aug 28, 2026
0f845a3
fix(scripts): give the render-smoke overlap test room for process sta…
cliffhall Aug 28, 2026
7083c6c
docs(scripts): correct the attribution in the render-smoke margin com…
cliffhall Aug 28, 2026
2e4e76a
test(scripts): anchor the render-smoke overlap paint to the parent's …
cliffhall Aug 28, 2026
aacfef3
Merge branch 'v2/main' into v2/chore/2130-inspectorview-prop-bundles
cliffhall Aug 28, 2026
37add96
chore(web): address Copilot review on #2130
cliffhall Aug 28, 2026
e2de318
Merge pull request #2181 from modelcontextprotocol/v2/fix/2180-render…
cliffhall Aug 28, 2026
4e0f4e5
Merge branch 'v2/main' into v2/chore/2130-inspectorview-prop-bundles
cliffhall Aug 28, 2026
7ca753b
fix(auth): accept RFC 8414 metadata served at the OIDC well-known path
cliffhall Aug 28, 2026
65fd2b9
feat(auth): revoke OAuth tokens at the authorization server on clear …
cliffhall Aug 28, 2026
85c5206
fix: cancel a Streamable HTTP call by closing its stream (#2140)
cliffhall Aug 28, 2026
15f381c
test(auth): cover the no-window guard in getWebProxiedFetch (#2144)
cliffhall Aug 28, 2026
56d3c04
fix(test-servers): address review on the cancellation showcase
cliffhall Aug 28, 2026
1db1b9b
fix(auth): cover the CLI refresh path and tighten the well-known match
cliffhall Aug 28, 2026
0139fd7
chore(web): address Copilot's second review on #2130
cliffhall Aug 28, 2026
7f27d7e
fix(auth): address Copilot review round 1 on the RFC 7009 revocation …
cliffhall Aug 28, 2026
cd5dde8
test: drive the cancellation showcase through its checked-in config
cliffhall Aug 28, 2026
28c7a9f
fix(auth): cover the transport's own discovery, and only rewrite GETs
cliffhall Aug 28, 2026
4a24c48
fix(auth): address Copilot review round 2 on the RFC 7009 revocation …
cliffhall Aug 28, 2026
89d6af4
fix(auth): mirror the SDK's candidate policy in the compat probe loop
cliffhall Aug 28, 2026
039fc6f
fix(auth): release discarded probe bodies, report the redirected sour…
cliffhall Aug 28, 2026
781aa69
fix(auth): revoke every issuer-bound grant, not just the active one (…
cliffhall Aug 28, 2026
6c499f3
fix(auth): read enumerated issuers exactly, and stop the TUI tone goi…
cliffhall Aug 28, 2026
e9cd678
fix(auth): key grant dedup by issuer, and isolate per-slot read failu…
cliffhall Aug 28, 2026
56ac830
fix(auth): RFC-encode the Basic credential; make the TUI clear await …
cliffhall Aug 28, 2026
43c817c
fix(auth): bound the whole teardown, and scope the TUI clear to its s…
cliffhall Aug 28, 2026
5170cc4
fix(auth): close the fail-open issuer check and the remaining clear r…
cliffhall Aug 28, 2026
1661f09
fix(web): surface a failed OAuth clear instead of floating its reject…
cliffhall Aug 28, 2026
e2cbf0d
fix(web): lock the OAuth clear so a double click cannot run it twice …
cliffhall Aug 28, 2026
c0bcdc7
fix(tui): forward the clear promise from App, so AuthTab can actually…
cliffhall Aug 28, 2026
69fcdd3
fix(auth): clear before waiting on the network, not after (#2144)
cliffhall Aug 28, 2026
4429c0c
fix(auth): keep the failure path total, and align the docs with the n…
cliffhall Aug 28, 2026
a4ee263
fix(auth): refuse a grant whose authorization server cannot be establ…
cliffhall Aug 28, 2026
b9012da
fix: close three stale-completion holes from the round-16 suppressed …
cliffhall Aug 28, 2026
0ded02b
fix(auth): revoke with the registration bound to the grant, not the c…
cliffhall Aug 28, 2026
463227c
fix(auth): make snapshot-and-clear one atomic storage step (#2144)
cliffhall Aug 28, 2026
579a3ee
fix(auth): salvage a malformed fallback registration, and correct the…
cliffhall Aug 28, 2026
18fe354
Merge pull request #2182 from modelcontextprotocol/v2/chore/2130-insp…
cliffhall Aug 28, 2026
1f2e3e1
fix: address the four suppressed findings from review round 20 (#2144)
cliffhall Aug 28, 2026
2d34999
Merge branch 'v2/main' into v2/fix/2140-streamable-http-cancellation
cliffhall Aug 28, 2026
a5efb32
Merge pull request #2185 from modelcontextprotocol/v2/fix/2140-stream…
cliffhall Aug 28, 2026
5ba2fad
Merge branch 'v2/main' into v2/feat/2144-oauth-revocation
cliffhall Aug 28, 2026
94a6620
Merge branch 'v2/main' into v2/fix/2172-oidc-discovery-compat
cliffhall Aug 28, 2026
eede9c1
fix: use Node storage in the revocation e2e, and drop the now-dead st…
cliffhall Aug 28, 2026
c7b18ad
Merge remote-tracking branch 'origin/v2/feat/2144-oauth-revocation' i…
cliffhall Aug 28, 2026
499451a
Merge pull request #2186 from modelcontextprotocol/v2/feat/2144-oauth…
cliffhall Aug 28, 2026
2eeab05
Merge remote-tracking branch 'origin/v2/main' into v2/fix/2172-oidc-d…
cliffhall Aug 28, 2026
a3a440d
Merge commit '94a6620c' into v2/fix/2172-oidc-discovery-compat
cliffhall Aug 28, 2026
8c91ae8
Merge pull request #2184 from modelcontextprotocol/v2/fix/2172-oidc-d…
cliffhall Aug 29, 2026
73447c7
chore: extract AGENTS.md recipes into agent skills
cliffhall Aug 29, 2026
a51e62d
chore: address Copilot review round 1
cliffhall Aug 29, 2026
4520e6a
docs: state the gap the gate cannot cover
cliffhall Aug 29, 2026
ca68289
chore: address Copilot review round 2
cliffhall Aug 29, 2026
7e0bb8b
chore: address Copilot review round 3
cliffhall Aug 29, 2026
f74aa75
fix(web): terminate the five void-discarded OAuth recovery promises
cliffhall Aug 29, 2026
61c462a
chore(web): resolve the react-hooks findings the decomposition unmask…
cliffhall Aug 29, 2026
d05e76d
chore: address Copilot review round 4
cliffhall Aug 29, 2026
ecad587
fix(web): address Copilot review on the OAuth recovery failure arms
cliffhall Aug 29, 2026
75ab1b0
chore: address Copilot review round 5
cliffhall Aug 29, 2026
5050226
fix(core): read state stores during render instead of re-syncing in a…
cliffhall Aug 29, 2026
76b75d3
fix(web): scope the OAuth recovery restores to the attempt that made …
cliffhall Aug 29, 2026
c3c8a33
chore: address Copilot review round 6
cliffhall Aug 29, 2026
f610577
fix(core): key the snapshot cache on every input it derives from
cliffhall Aug 29, 2026
a46a8a6
fix(web): per-attempt snapshot ids, honest recovery copy, connect tea…
cliffhall Aug 29, 2026
09b8f0e
chore: address Copilot review round 7 (Windows .cmd shims)
cliffhall Aug 29, 2026
8f3619f
docs(core): correct the useStoreSnapshot caller contract
cliffhall Aug 29, 2026
5078a5b
chore: address Copilot review round 8
cliffhall Aug 29, 2026
d5ddaf8
fix(web): clear the step-up retry on redirect handoff; justify the voids
cliffhall Aug 29, 2026
b088b94
test(core): make the unsubscribe test actually verify unsubscription
cliffhall Aug 29, 2026
1634437
fix(web): give each EMA step-up attempt ownership of its command retry
cliffhall Aug 29, 2026
17068fc
chore: address Copilot review round 9
cliffhall Aug 29, 2026
6f2e1fa
fix(web): install a step-up's command retry only when its prompt opens
cliffhall Aug 29, 2026
23c59d7
chore: address Copilot review round 10
cliffhall Aug 29, 2026
97122b5
chore: address Copilot review round 11
cliffhall Aug 29, 2026
7d828bd
chore: address Copilot review round 12
cliffhall Aug 29, 2026
f13d415
chore: address Copilot review round 13
cliffhall Aug 29, 2026
0798ecf
chore: address Copilot review round 14
cliffhall Aug 29, 2026
3905cee
chore: address Copilot review round 15
cliffhall Aug 29, 2026
c26995b
chore: address Copilot review round 16
cliffhall Aug 29, 2026
1203246
chore: address Copilot review round 17
cliffhall Aug 29, 2026
d29bbbb
chore: address Copilot review round 18
cliffhall Aug 29, 2026
b91b746
chore: address Copilot review round 19
cliffhall Aug 29, 2026
a2ddece
chore: address Copilot review round 20
cliffhall Aug 29, 2026
3838764
Merge pull request #2193 from modelcontextprotocol/v2/fix/1955-hooks-…
cliffhall Aug 30, 2026
6af2edc
Merge branch 'v2/main' into v2/chore/2161-react-hooks-suppressions
cliffhall Aug 30, 2026
26fdc48
Merge branch 'v2/main' into v2/fix/2165-oauth-recovery-floating-promises
cliffhall Aug 30, 2026
1184792
Merge pull request #2191 from modelcontextprotocol/v2/chore/2161-reac…
cliffhall Aug 30, 2026
ba66d5f
Merge branch 'v2/main' into v2/fix/2165-oauth-recovery-floating-promises
cliffhall Aug 30, 2026
67abdf9
Merge branch 'v2/main' into v2/chore/2163-agent-skills
cliffhall Aug 30, 2026
9ced0fd
chore: lint core/react with eslint-plugin-react-hooks (#2192)
cliffhall Aug 30, 2026
37e8d85
Merge pull request #2190 from modelcontextprotocol/v2/fix/2165-oauth-…
cliffhall Aug 30, 2026
cc204e3
Merge branch 'v2/main' into v2/chore/2163-agent-skills
cliffhall Aug 30, 2026
7e6d6c0
chore: address Copilot review round 1 (#2192)
cliffhall Aug 30, 2026
94a71f4
chore: make the workflow skills model-invocable
cliffhall Aug 30, 2026
f8c1d0c
Merge remote-tracking branch 'origin/v2/chore/2163-agent-skills' into…
cliffhall Aug 30, 2026
546dacf
chore: address Copilot review round 2 (#2192)
cliffhall Aug 30, 2026
55578ac
chore: address Copilot review round 3 (#2192)
cliffhall Aug 30, 2026
26d70e0
chore: make issue-create and issue-triage model-invocable
cliffhall Aug 30, 2026
5bc5977
Merge branch 'v2/main' into v2/chore/2192-lint-core-react
cliffhall Aug 30, 2026
f95abb2
chore: tighten the testing skill's description
cliffhall Aug 30, 2026
21cb606
Merge pull request #2194 from modelcontextprotocol/v2/chore/2192-lint…
cliffhall Aug 30, 2026
d2a5e91
Merge branch 'v2/main' into v2/chore/2163-agent-skills
cliffhall Aug 30, 2026
463593b
Merge pull request #2189 from modelcontextprotocol/v2/chore/2163-agen…
cliffhall Aug 30, 2026
327c8d6
chore: consolidate shared toolchain devDependencies into the root pac…
cliffhall Aug 31, 2026
1f5c329
chore: consolidate duplicated runtime dependencies into the root pack…
cliffhall Aug 31, 2026
edef659
fix: pin the vitest trio exactly, and document the peer/transitive ex…
cliffhall Aug 31, 2026
613c494
docs: correct the scope claims in the toolchain rule
cliffhall Aug 31, 2026
e76e32c
docs: separate peer-constrained copies from unconstrained transitives
cliffhall Aug 31, 2026
f62cfba
chore: address Copilot review on #2200
cliffhall Aug 31, 2026
2a64c67
chore: address Copilot review round 2 on #2200
cliffhall Sep 1, 2026
5669903
chore: address Copilot review round 3 on #2200
cliffhall Sep 1, 2026
1d9659c
chore: address Copilot review round 4 on #2200
cliffhall Sep 1, 2026
2eb160d
Merge pull request #2200 from modelcontextprotocol/v2/chore/2195-cons…
cliffhall Sep 1, 2026
440d1aa
Merge remote-tracking branch 'origin/v2/main' into v2/chore/2196-cons…
cliffhall Sep 1, 2026
6dd43e7
docs: tune skill eval cases and document how to write them
cliffhall Sep 1, 2026
faada87
Merge pull request #2199 from modelcontextprotocol/v2/chore/2196-cons…
cliffhall Sep 1, 2026
a344225
docs: accept several skill names in skills:eval and re-aim overlappin…
cliffhall Sep 1, 2026
906e970
Merge branch 'v2/main' into v2/docs/2202-skill-eval-tuning
cliffhall Sep 1, 2026
50f3360
docs: address Copilot review round 1 on #2203
cliffhall Sep 1, 2026
880be3a
docs: address Copilot review round 2 on #2203
cliffhall Sep 1, 2026
104a05d
docs: address Copilot review round 3 on #2203
cliffhall Sep 1, 2026
4acab97
docs: address Copilot review round 4 on #2203
cliffhall Sep 1, 2026
ec2ef56
docs: address Copilot review round 5 on #2203
cliffhall Sep 1, 2026
5d35715
docs: address Copilot review round 6 on #2203
cliffhall Sep 1, 2026
0febaa0
docs: address Copilot review round 7 on #2203
cliffhall Sep 1, 2026
c66793b
docs: address Copilot review round 8 on #2203
cliffhall Sep 1, 2026
afca8fa
docs: address Copilot review round 9 on #2203
cliffhall Sep 1, 2026
efb0265
Merge pull request #2203 from modelcontextprotocol/v2/docs/2202-skill…
cliffhall Sep 1, 2026
fe35885
chore: bump version to 2.5.0 (#2213)
cliffhall Sep 1, 2026
d92a30f
chore: merge v2/main for the v2.5.0 milestone release
cliffhall Sep 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
287 changes: 287 additions & 0 deletions .claude/skills/board-ops/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,287 @@
---
name: board-ops
description: "gh recipes for the Inspector project boards — add a card, move its Status, set or re-score its Priority, delete a card, and recover from a deleted single-select option. Covers board #28 (v2) and board #11 (v1), their node/field/option IDs, and the option-deletion hazard."
disable-model-invocation: false
---

# Board operations

The rules about *what* a card's Status and Priority should be live in
[`AGENTS.md`](../../../AGENTS.md) under **Issue-driven Work Style**. This skill is
the *mechanics*: the exact `gh` calls, the IDs, and the ways the board can be
damaged.

Related: `/issue-create` (the five-step create flow), `/issue-triage` (sweeping
unboarded issues in, the priority rubric, the board audit).

## Which board

| Version label | Board | Owner | Has a Priority field? |
| --- | --- | --- | --- |
| `v2` | [#28](https://github.com/orgs/modelcontextprotocol/projects/28) | `modelcontextprotocol` | Yes |
| `v1` | [#11](https://github.com/orgs/modelcontextprotocol/projects/11) | `modelcontextprotocol` | **No** |

Both are **org** projects, so every command takes `--owner modelcontextprotocol`.
The two projects have their own field and option IDs and none of them are
interchangeable — a #28 id passed to #11 is rejected with "option Id does not
belong to the field", so the mistake is at least loud.

**Only issues go on a board — never PRs, never draft cards.** A PR is tracked
through the card of the issue it closes.

## V2 board (#28) IDs

The project node id and the field ids are stable. The **option** ids are **not** —
they are regenerated whenever a single-select field's option list is edited (see
the hazard below). If any option id here is rejected, re-fetch:

```sh
# Swap "Status" for "Priority" to fetch the other field's options.
gh project field-list 28 --owner modelcontextprotocol --format json \
| jq '.fields[] | select(.name=="Status") | .options'
```

| Thing | ID |
| --- | --- |
| Project node ID | `PVT_kwDOCt2Azc4BJVxt` |
| Status field ID | `PVTSSF_lADOCt2Azc4BJVxtzg5iI8c` |
| Priority field ID | `PVTSSF_lADOCt2Azc4BJVxtzg5iJE4` |

Status option IDs (`--single-select-option-id`) — **last verified 2026-08-01**.

| Status | Option ID | Means |
| --- | --- | --- |
| Incoming | `721a3d4c` | Arrived unboarded, awaiting review — **no milestone** |
| Todo | `fbdaf21e` | Approved (a milestone was assigned) |
| In Progress | `195df262` | Active work, whatever the surface |
| In Review | `159c8a02` | A PR is open |
| Done | `259d6aab` | **Shipped** — a merged PR, or a parent whose last sub-issue closed |

Priority option IDs — **last verified 2026-08-01**. Derive the level with the
rubric in `/issue-triage`; don't eyeball it.

| Priority | Option ID | Rubric total |
| --- | --- | --- |
| Urgent | `79628723` | 12+ |
| High | `0a877460` | 9–11 |
| Medium | `da944a9c` | 6–8 |
| Low | `d67ac7ce` | ≤5 |

## V1 board (#11) IDs

The v1 line takes security fixes only, so this board sees little traffic — but a
v1 issue still gets a card, and the same Incoming/Todo split applies.

| Thing | ID |
| --- | --- |
| Project node ID | `PVT_kwDOCt2Azc4BA5sz` |
| Status field ID | `PVTSSF_lADOCt2Azc4BA5szzgzkS-g` |

Status option IDs — **last verified 2026-08-01**.

| Status | Option ID |
| --- | --- |
| Incoming | `831820cf` |
| Todo | `f75ad846` |
| In Progress | `47fc9ee4` |
| In Review | `0439b2bf` |
| Done | `98236657` |

There is **no Priority field on this board** — the priority rubric is v2-only.
Don't try to set one here; the field id doesn't exist.

## Recipes

### Add a card and set its fields

```sh
# Prints the item id (PVTI_…); capture it.
ITEM_ID=$(gh project item-add 28 --owner modelcontextprotocol --url <issue-url> --format json --jq '.id')

# Status → Todo (an issue you filed through the create flow is approved by definition)
gh project item-edit --project-id PVT_kwDOCt2Azc4BJVxt --id "$ITEM_ID" \
--field-id PVTSSF_lADOCt2Azc4BJVxtzg5iI8c --single-select-option-id fbdaf21e

# Priority → Medium
gh project item-edit --project-id PVT_kwDOCt2Azc4BJVxt --id "$ITEM_ID" \
--field-id PVTSSF_lADOCt2Azc4BJVxtzg5iJE4 --single-select-option-id da944a9c
```

Each `item-edit` sets **one** field, so setting both takes two calls — there is
no combined form.

For an issue swept in at triage, the only difference is Status → **Incoming**
(`721a3d4c`) and that you do **not** set a milestone.

For **v1**, the same shape against board #11:

```sh
ITEM_ID=$(gh project item-add 11 --owner modelcontextprotocol --url <issue-url> --format json --jq '.id')
gh project item-edit --project-id PVT_kwDOCt2Azc4BA5sz --id "$ITEM_ID" \
--field-id PVTSSF_lADOCt2Azc4BA5szzgzkS-g --single-select-option-id f75ad846
```

### Move an existing card

Look the item id up by issue number rather than re-adding it. Keep `--limit`
above the board's item count (~265 as of 2026-08-01) — past it `item-list`
truncates **silently**, `select` matches nothing, and `item-edit --id ""` fails
with an opaque node-resolution error rather than saying the limit was too low.

⚠️ **Filter by repository, not by number alone.** These are **org** projects and
issue numbers are **repo-local**, so an unfiltered `select` can match another
repo's issue that happens to share the number — board #11 really does carry a
`modelcontextprotocol/servers` card — and then moves or deletes the wrong card,
or passes two ids at once (Copilot).

```sh
ITEM_ID=$(gh project item-list 28 --owner modelcontextprotocol --format json --limit 500 \
--jq '.items[] | select(.content.repository=="modelcontextprotocol/inspector"
and .content.number==<ISSUE_NUMBER>) | .id')
# e.g. Status → In Review, when its PR opens
gh project item-edit --project-id PVT_kwDOCt2Azc4BJVxt --id "$ITEM_ID" \
--field-id PVTSSF_lADOCt2Azc4BJVxtzg5iI8c --single-select-option-id 159c8a02
```

### Delete a card

**`Done` means the work shipped.** An issue closed as duplicate / won't fix /
not planned / obsolete / superseded shipped nothing, so its card is **deleted**,
not parked in Done:

```sh
ITEM_ID=$(gh project item-list 28 --owner modelcontextprotocol --format json --limit 500 \
--jq '.items[] | select(.content.repository=="modelcontextprotocol/inspector"
and .content.number==<ISSUE_NUMBER>) | .id')
gh project item-delete 28 --owner modelcontextprotocol --id "$ITEM_ID"
```

Deleting the card removes it from the board only — **the issue itself is
untouched**, keeps its labels and comments, and stays searchable and linkable
forever. Nothing is lost; the board simply stops claiming the work was
delivered. Done is read as the record of what a milestone actually delivered, so
a duplicate sitting there makes that record wrong in a way nobody can detect
later.

The close **reason** is the machine-readable form of the same distinction.
`gh issue close --reason` accepts only `completed` and `not planned`, so
**`duplicate` must be set through the API**:

```sh
gh api repos/modelcontextprotocol/inspector/issues/<N> -X PATCH \
-f state=closed -f state_reason=duplicate
```

(or "Mark as duplicate" in the web UI, which additionally records a
duplicate-of link).

## ⚠️ The option-deletion hazard

**Never add, rename, or remove an option on a single-select board field (Status
or Priority) with the `updateProjectV2Field` GraphQL mutation unless you pass
every existing option's `id`.** That mutation does a **full replace** of the
option list: resending options by name/color/description without their `id`s
makes GitHub **delete all existing options and mint new ones**, which **orphans
that field's value on every card on the board** *and* invalidates every option
id in the tables above. This has happened once, on Status (~197 items
reconstructed by inference).

Safe alternatives, in order of preference:

1. **Add or rename an option in the GitHub web UI** (Project → the field's
settings). This preserves the ids of untouched options.
⚠️ **Deleting is different, in the UI as much as in the API**: removing an
option blanks that field's value on every card that held it, with no undo and
no warning that says so.
2. If you must script it, first `gh api graphql` the current options **with their
`id`s**, then call `updateProjectV2Field` echoing back every existing option
**including its `id`**, appending only the new one.
`ProjectV2SingleSelectFieldOptionInput.id` is an optional `String`, so a mixed
list works. Verify afterward that no card lost its value — snapshot
`gh project item-list … --format json` before and after and diff; don't just
spot-check. Send those dumps to `$BOARD_TMP` too, for the reason above.

Both the `Incoming` Status option and the Urgent/High/Medium/Low Priority
options were added this way (#1891), with the before/after diff confirming all
264 cards kept their Status.

`gh project item-add` and `gh project item-edit` are always safe — they set a
card's value and never touch the field schema.

### Always snapshot before touching a field's options

One command, and it is the difference between a five-minute restore and
reconstructing statuses by inference:

⚠️ **Write it outside the repo.** [The boards are private](../issue-triage/SKILL.md),
so a snapshot is a full dump of item IDs and every card's Status and Priority.
Left in the working tree it is one `git add -A` away from being published in a
PR (Copilot).

```sh
BOARD_TMP=$(mktemp -d)
gh project item-list 28 --owner modelcontextprotocol --format json --limit 600 \
> "$BOARD_TMP/board-snapshot.json"
echo "snapshot: $BOARD_TMP/board-snapshot.json" # note the path; you need it to recover
```

### Recovering from a deleted option

This has happened twice — once via the API (~197 items, reconstructed by
inference) and once via the UI (the `Done` column, 247 items, restored from a
snapshot in minutes). With a snapshot the recovery is mechanical.

The recipe below is written for a deleted **Status** option. For a deleted
**Priority** option it is the same three steps with two substitutions: read
`.priority` instead of `.status` (`gh project item-list --format json` exposes
each single-select field under its lowercased name, so both keys are present),
and pass the Priority field id `PVTSSF_lADOCt2Azc4BJVxtzg5iJE4`.

```sh
# 0. Same temp dir the snapshot went to — keep every dump out of the worktree.
BOARD_TMP=${BOARD_TMP:-$(mktemp -d)}

# 1. Which cards lost their value, and what did they hold?
gh project item-list 28 --owner modelcontextprotocol --format json --limit 600 \
> "$BOARD_TMP/board-broken.json"
jq -r '[.items[]|select(.status==null)|.id]' "$BOARD_TMP/board-broken.json" \
> "$BOARD_TMP/lost-ids.json"
jq -r --slurpfile L "$BOARD_TMP/lost-ids.json" '($L[0]) as $lost
| [.items[] | select(.id as $i | $lost|index($i)) | .status // "(none)"]
| group_by(.) | map({s:.[0],c:length}) | .[] | "was \(.s): \(.c)"' \
"$BOARD_TMP/board-snapshot.json"

# 2. Recreate the option, echoing every surviving option's id (see above).
# NOTE: the recreated option gets a NEW id — the deleted one never comes back.

# 3. Re-apply it to the orphaned cards.
for id in $(jq -r '.[]' "$BOARD_TMP/lost-ids.json"); do
gh project item-edit --project-id PVT_kwDOCt2Azc4BJVxt --id "$id" \
--field-id PVTSSF_lADOCt2Azc4BJVxtzg5iI8c --single-select-option-id <NEW_OPTION_ID>
sleep 0.4
done
```

Step 1's grouping is the safety check: confirm the orphaned set is exactly the
cards that held the deleted option, so you don't overwrite a card someone
legitimately moved in the meantime.

Because the recreated option carries a **new id**, the tables above and every
reference to it must be updated in the same change — `grep` the old id across
the repo. The `Done` id has been `248a3910` and is now `259d6aab` for exactly
this reason.

## ⚠️ Two different "Priority" fields

An issue page shows two fields named Priority, and they are unrelated. **Ours is
the one under _Projects → Inspector V2_.**

| Where it appears | What it is | Ours? |
| --- | --- | --- |
| **Projects → Inspector V2 → Priority** | The **project board** field on #28 (`PVTSSF_lADOCt2Azc4BJVxtzg5iJE4`) | ✅ Yes |
| **Fields → Priority** (above _Projects_) | A GitHub **issue field**, `IFSS_kgDOAdAWeg`, defined at the **org** level and shared by every repo in it | ❌ No |

Nothing syncs them, in either direction, and they will happily disagree.
**Never delete the org-level field** — it belongs to the whole org. Don't set it
either; a value there is a *reporter's* opinion and feeds the rubric as a capped
+1 signal bonus and nothing more (see `/issue-triage`).
30 changes: 30 additions & 0 deletions .claude/skills/board-ops/evals/evals.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
[
{
"prompt": "Move the board card for issue 2189 to In Review.",
"expect": "board-ops"
},
{
"prompt": "How do I set the Priority field on a card in the v2 project board?",
"expect": "board-ops"
},
{
"prompt": "The project board rejected my Status option ID. How do I get the current ones?",
"expect": "board-ops"
},
{
"prompt": "I'm about to edit the options on one of the board's single-select fields. Should I do anything first?",
"expect": "board-ops"
},
{
"prompt": "Several cards lost their Priority value after the field was edited. How do I put it back?",
"expect": "board-ops"
},
{
"prompt": "Explain the difference between TCP and UDP.",
"expect": null
},
{
"prompt": "What year was the first Moon landing?",
"expect": null
}
]
Loading
Loading