@event4u/agent-config 1.36.1 → 1.38.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,7 +6,7 @@
6
6
  },
7
7
  "metadata": {
8
8
  "description": "Shared agent configuration \u2014 skills for AI coding tools (Claude Code, Augment, Cursor, Cline, Windsurf, Gemini CLI).",
9
- "version": "1.36.1"
9
+ "version": "1.38.0"
10
10
  },
11
11
  "plugins": [
12
12
  {
package/CHANGELOG.md CHANGED
@@ -318,6 +318,83 @@ our recommendation order, not its support status.
318
318
  users" tension without removing any path that an existing user
319
319
  might rely on.
320
320
 
321
+ ## [1.38.0](https://github.com/event4u-app/agent-config/compare/1.37.0...1.38.0) (2026-05-11)
322
+
323
+ ### Features
324
+
325
+ * **mcp:** add cloud setup tasks + operator README ([c5aebba](https://github.com/event4u-app/agent-config/commit/c5aebba37a608d0a41b1586acacdb055996a961d))
326
+ * **scripts:** MCP content packer + cloud parity smoke ([e0d132a](https://github.com/event4u-app/agent-config/commit/e0d132afb487b720386bd54b68e10f1a342d6b0c))
327
+
328
+ ### Documentation
329
+
330
+ * **readme:** surface hosted Remote MCP as zero-install option ([de6161e](https://github.com/event4u-app/agent-config/commit/de6161e3660b81a460f057bc46c1b75e6fe8693c))
331
+ * **mcp:** add A0-cloud invariant 8 — ingress protection via edge cache + platform rate-limit ([c4b9371](https://github.com/event4u-app/agent-config/commit/c4b9371da2db55958bca29a7d10291626d13782f))
332
+ * **mcp:** drop archived-roadmap refs from stable contracts ([15418de](https://github.com/event4u-app/agent-config/commit/15418de5a65c3cd5968bbeecc20ed5ad5c4a4958))
333
+ * **mcp:** surface experimental hosted-MCP channel ([cecae08](https://github.com/event4u-app/agent-config/commit/cecae08ad647c7e28931e7328047fdef5ca3d3a3))
334
+ * **setup:** MCP cloud endpoints, R2 bootstrap, registry listing ([7cb3341](https://github.com/event4u-app/agent-config/commit/7cb334110ff940d3703ada013ef5163c899d96b2))
335
+ * **mcp:** add A0-cloud contract + cross-links (Phase 1 of cloudflare-mcp-hosting) ([2fc5084](https://github.com/event4u-app/agent-config/commit/2fc50845c3b194e861b54f82c852ba4bb9fc406a))
336
+ * **roadmap:** add Cloudflare-hosted MCP roadmap, archive distribution ([fd1c437](https://github.com/event4u-app/agent-config/commit/fd1c437ea8a918eebc8604ee7958d8c842c7aac8))
337
+
338
+ ### CI
339
+
340
+ * **deploy-mcp-worker:** release-tag triggered Worker deploy ([4297514](https://github.com/event4u-app/agent-config/commit/4297514b80457852511ad90674f4d633a75a92bf))
341
+
342
+ ### Chores
343
+
344
+ * **linter:** raise README overloaded threshold to 750 lines ([1e3fbb7](https://github.com/event4u-app/agent-config/commit/1e3fbb7c649398ba56bc32677c7b588131f7e949))
345
+ * **mcp:** mark dev content.json stub with explanatory _comment ([8f6c7ff](https://github.com/event4u-app/agent-config/commit/8f6c7ffe493b72ccb2d0ec66121a9d32d0b2fe8c))
346
+ * **roadmap:** archive road-to-cloudflare-mcp-hosting (100% complete) ([99e07f9](https://github.com/event4u-app/agent-config/commit/99e07f92293e62841ff87f315e41c5ceabd7b277))
347
+ * **workers/mcp:** scaffold TypeScript Cloudflare Worker ([447e071](https://github.com/event4u-app/agent-config/commit/447e071984f86fc084058d05f22d0e0a7c936a5e))
348
+
349
+ Tests: 2679 (+0 since 1.37.0)
350
+
351
+ ## [1.37.0](https://github.com/event4u-app/agent-config/compare/1.36.1...1.37.0) (2026-05-10)
352
+
353
+ ### Features
354
+
355
+ * **mcp:** add Phase 6 F3 stdio Docker bundle ([acd5e47](https://github.com/event4u-app/agent-config/commit/acd5e47a56b9fb42f57751771087c6b73759d3d5))
356
+ * **mcp:** add Phase 6 F1 identity metadata ([f4700ff](https://github.com/event4u-app/agent-config/commit/f4700ff1f093611220c08fba75c29d12ed57110c))
357
+ * **mcp:** add Phase 4 tool layer with lint_skills and chat_history_append ([fe02108](https://github.com/event4u-app/agent-config/commit/fe0210817e46f4d1710b0d96b7a176c872fc5545))
358
+ * **cli:** expose mcp:setup + mcp:run via ./agent-config ([bf7ff65](https://github.com/event4u-app/agent-config/commit/bf7ff65ab040b482d5f4e716a78148e95ba3bc7f))
359
+ * **mcp:** expose rules, guidelines, contexts as resources ([21d85c5](https://github.com/event4u-app/agent-config/commit/21d85c5142a35dade1129f835821c72944442ead))
360
+ * **mcp:** full skill + command coverage with pagination + hot-reload ([126c976](https://github.com/event4u-app/agent-config/commit/126c976f30e7bf3b714f8b72131b53fcc3e07878))
361
+ * **mcp:** add experimental stdio MCP server exposing 5 stack-agnostic skills ([8e692cf](https://github.com/event4u-app/agent-config/commit/8e692cfbdc14e67f178b11068773d50dd199b4ab))
362
+
363
+ ### Bug Fixes
364
+
365
+ * **agents-md:** revert MCP pointer to keep root under 3000-char cap ([02bed8e](https://github.com/event4u-app/agent-config/commit/02bed8edb13fdcae369bac3843a836c01dc04248))
366
+ * **lint:** emit valid JSON when no skill/rule files changed ([caef1cb](https://github.com/event4u-app/agent-config/commit/caef1cb91def6089cad3ba3d2fd7c728b39731d0))
367
+ * **mcp:** relocate Phase 1 smoke transcript out of agents/roadmaps/ ([addd7c2](https://github.com/event4u-app/agent-config/commit/addd7c2ac4aa7a6527fb9e750ed38d02f1cd51bc))
368
+ * **mcp:** drop roadmap link from Phase 1 scope contract ([ca3c2e8](https://github.com/event4u-app/agent-config/commit/ca3c2e89b6c5ebf06cbc6a55883cf3cf1fbd015a))
369
+
370
+ ### Documentation
371
+
372
+ * **contracts:** amend MCP scope contract for Phase 6 F1 + F3 ([45989c5](https://github.com/event4u-app/agent-config/commit/45989c53d6c9b361ad29b4214984db6cff8f5b5f))
373
+ * **contracts:** amend MCP scope contract for Phase 4 tool allowlist ([87c9622](https://github.com/event4u-app/agent-config/commit/87c9622d165d783a5b1f8c266035791cafbf3ab9))
374
+ * **roadmap:** mark MCP Phase 3 + Phase 5 done ([9ec9494](https://github.com/event4u-app/agent-config/commit/9ec9494be18b6634dcf4383af921b54f283c86ff))
375
+ * **mcp:** canonical MCP server setup guide ([4fd149f](https://github.com/event4u-app/agent-config/commit/4fd149f0b1c6e6b009d2bdd3b4ea80759e31055d))
376
+ * **roadmap:** mark MCP Phase 2 (B1-B5) done + extend scope contract ([5ea1c56](https://github.com/event4u-app/agent-config/commit/5ea1c56d027f432f9c950e8b35805ab91758fd26))
377
+ * **roadmap:** mark MCP Phase 1 (A1–A7) done + record stdio smoke transcript ([aaf8332](https://github.com/event4u-app/agent-config/commit/aaf833292aba530bdeae138fa2255b4576fe699c))
378
+ * **mcp:** add Phase 1 scope contract (experimental, read-only) ([2fa275e](https://github.com/event4u-app/agent-config/commit/2fa275eec70c02741b76abef2b6356c7d0d1c6a7))
379
+
380
+ ### Tests
381
+
382
+ * **mcp:** cover Phase 6 F1 identity metadata ([d3f79ef](https://github.com/event4u-app/agent-config/commit/d3f79eff30f61914fe09667693b41e2ed8c29855))
383
+ * **mcp:** cover Phase 4 tool layer ([217c4ab](https://github.com/event4u-app/agent-config/commit/217c4ab2ed1041006e1ac3102369b8c1569f3653))
384
+ * **mcp:** cover Phase 2 — full coverage, pagination, hot-reload ([f93c019](https://github.com/event4u-app/agent-config/commit/f93c0199adc558119be614fadd677cf37c8c2d5a))
385
+ * **mcp:** make loader tests run when mcp SDK is absent ([8378621](https://github.com/event4u-app/agent-config/commit/8378621be8ec24ccba59be10c49a4384abdc335f))
386
+ * **mcp:** cover Phase 1 loader + import-surface guard + server handlers ([f4fee8b](https://github.com/event4u-app/agent-config/commit/f4fee8b899b0163ea2bfe7099ffa9221b70bf488))
387
+
388
+ ### Chores
389
+
390
+ * **roadmap:** close road-to-mcp-server at 100%, defer F4 to distribution ([0127991](https://github.com/event4u-app/agent-config/commit/01279913f3b2a5caa1eb65f8a7b07a2f841d41af))
391
+ * **roadmap:** defer Phase 6 F2 to road-to-mcp-distribution ([b5e0be7](https://github.com/event4u-app/agent-config/commit/b5e0be7473296bfd5381dc1ace9bc99ae79f5090))
392
+ * **roadmap:** mark MCP Phase 4 (D1-D4) complete ([8c342c8](https://github.com/event4u-app/agent-config/commit/8c342c8508f17133d71528b16d727d5c3c56acfd))
393
+ * **mcp:** add task mcp:setup for one-line install ([ae1f6f9](https://github.com/event4u-app/agent-config/commit/ae1f6f9d355dd5a782fdadb5e67929552caab5ed))
394
+ * ignore .venv-mcp/ for MCP server work ([8bd44d4](https://github.com/event4u-app/agent-config/commit/8bd44d49e359021a000a989bfd7ae7f6f48800db))
395
+
396
+ Tests: 2679 (+58 since 1.36.1)
397
+
321
398
  ## [1.36.1](https://github.com/event4u-app/agent-config/compare/1.36.0...1.36.1) (2026-05-10)
322
399
 
323
400
  ### Refactoring
package/README.md CHANGED
@@ -90,6 +90,30 @@ Install directly in your agent for global, cross-project use:
90
90
  → [Full getting started guide](docs/getting-started.md) ·
91
91
  [More examples & expected behavior](docs/showcase.md)
92
92
 
93
+ ### Remote MCP — zero install
94
+
95
+ Skills, commands, rules, and guidelines are also served as a hosted MCP
96
+ endpoint. No clone, no `task mcp:setup`, no Python venv — point any
97
+ MCP-capable client (Claude Desktop, Cursor, Zed, Continue, hosted agents)
98
+ at:
99
+
100
+ ```
101
+ https://agent-config-mcp.event4u.workers.dev
102
+ ```
103
+
104
+ Verify it's live:
105
+
106
+ ```bash
107
+ curl https://agent-config-mcp.event4u.workers.dev
108
+ # → { "ok": true, "name": "agent-config-mcp", "release_key": "v…", … }
109
+ ```
110
+
111
+ Read-only, identity-stable per release. Client config snippets and URL
112
+ shapes (latest vs. pinned `/v<X.Y.Z>`) live in
113
+ [`docs/setup/mcp-cloud-endpoints.md`](docs/setup/mcp-cloud-endpoints.md).
114
+ Operator setup (account, R2, secrets) — [`docs/setup/mcp-cloud-setup.md`](docs/setup/mcp-cloud-setup.md).
115
+ Experimental — A0-cloud contract in [`docs/contracts/mcp-cloud-scope.md`](docs/contracts/mcp-cloud-scope.md).
116
+
93
117
  ### Optional: persistent agent memory
94
118
 
95
119
  `agent-config` integrates with [`@event4u/agent-memory`](https://www.npmjs.com/package/@event4u/agent-memory)
@@ -109,7 +133,7 @@ Install in the same project (dev-only):
109
133
  npm install --save-dev @event4u/agent-memory
110
134
  ```
111
135
 
112
- → [Memory contract & retrieval API](docs/contracts/agent-memory-contract.md) (beta)
136
+ → [Memory contract & retrieval API](docs/contracts/agent-memory-contract.md) (beta) · [Built-in MCP server](docs/mcp-server.md) (experimental — local stdio access from Claude Desktop / Cursor / Zed / Continue, install with `task mcp:setup`)
113
137
 
114
138
  ---
115
139
 
@@ -0,0 +1,182 @@
1
+ ---
2
+ stability: experimental
3
+ ---
4
+
5
+ # MCP Server — Cloud Scope (A0-cloud Hard Contract)
6
+
7
+ > **Status:** Active · covers `workers/mcp/` (TypeScript Cloudflare
8
+ > Worker bridge), MVP-1 surface. Extends — does **not** supersede —
9
+ > [`mcp-phase-1-scope.md`](mcp-phase-1-scope.md), which retains
10
+ > exclusive ownership of `scripts/mcp_server/` (local stdio).
11
+ > **Stability:** experimental — not linked from README, AGENTS.md, or
12
+ > `docs/architecture.md`. Internal index reference only per `STABILITY.md`.
13
+
14
+ ## Purpose
15
+
16
+ Locks the **execution-safety boundary** for the hosted MCP Worker. Any
17
+ code under `workers/mcp/` must satisfy this contract verbatim. The
18
+ local stdio kernel and the hosted Worker are two distinct surfaces; a
19
+ deviation in one is **not** authorized by a precedent in the other.
20
+
21
+ The Worker IS the bridge described in
22
+ [`mcp-request-signing § Appendix`](../guidelines/agent-infra/mcp-request-signing.md#appendix--http-bridge-stdio-kernel-pattern-reference)
23
+ — but with two material differences from the appendix pattern: (1) no
24
+ spawned stdio child (content is read from a release-pinned R2 blob,
25
+ not a sub-process), and (2) no HMAC for MVP-1 (content is OSS and
26
+ read-only; the appendix pattern's `verifyRequest` is deferred to MVP-2
27
+ alongside auth).
28
+
29
+ ## In-scope (MVP-1)
30
+
31
+ - **Transport:** HTTP + SSE (Cloudflare Worker `fetch` handler). The
32
+ local stdio kernel is out-of-scope for this contract and stays
33
+ governed by `mcp-phase-1-scope.md`.
34
+ - **MCP primitives:** `prompts/list` + `prompts/get` + `resources/list`
35
+ + `resources/read` — read-only, parity with the local stdio surface.
36
+ - **Source data:** release-pinned content blob in R2 under the key
37
+ shape `releases/v<X.Y.Z>-<sha>/` (immutable per release). The blob
38
+ bundles `.agent-src/skills/<name>/SKILL.md`,
39
+ `.agent-src/commands/**/*.md`, and `docs/guidelines/` (the same
40
+ projection the local kernel reads). Never reads `.agent-src.uncompressed/`.
41
+ - **Identity surface:** `serverInfo.version` reads from a Worker-
42
+ bundled constant, `_meta.packageVersion` reads from a
43
+ `wrangler.toml` env var, `_meta.skillSetSignature` reads from a
44
+ **prebaked manifest JSON** shipped with the content blob. The
45
+ Worker never computes the signature at runtime.
46
+ - **URL shape:** two pinned shapes only —
47
+ `mcp.<host>/v<X.Y.Z>/sse` (immutable, cache TTL 1 h) and
48
+ `mcp.<host>/latest/sse` (pointer, cache TTL 5 min). The `latest`
49
+ pointer is repointed atomically by the release pipeline after a
50
+ green smoke run; pre-smoke failures leave it on the previous
51
+ release.
52
+ - **Pagination + hot-reload parity:** `prompts/list` paginates with
53
+ `nextCursor` the same way the stdio kernel does; the Worker has no
54
+ hot-reload because the content blob is immutable per release —
55
+ the **release** is the cache-bust event.
56
+ - **Deprecated tool stubs:** `tools/list` returns exactly two entries,
57
+ `lint_skills` and `chat_history_append`, both with
58
+ `deprecated: true` and a description pointing to the local stdio
59
+ server. `tools/call` against either returns `isError=true` with a
60
+ message naming the local-stdio successor. No other tool name is
61
+ reachable.
62
+
63
+ ## Out-of-scope (MVP-1)
64
+
65
+ - **Tool execution.** `lint_skills` and `chat_history_append` are
66
+ exposed as deprecated stubs only — no TS port, no FS access, no
67
+ shell, no Python runtime in the Worker. Restoration is the
68
+ Phase-7-DEFERRED block of the roadmap, gated on a real consumer ask
69
+ plus a multi-tenant security review.
70
+ - **`.agent-settings.yml` exposure.** Consumer-machine config, never
71
+ surfaced as a resource. The Worker has no access to consumer FS at
72
+ any layer.
73
+ - **Agent memory** — separate MCP server, different roadmap.
74
+ - **Chat history persistence** — the local kernel writes to
75
+ `agents/.agent-chat-history`; the Worker has no equivalent. Listed
76
+ as a deprecated stub per above.
77
+ - **Authentication / multi-tenancy.** MVP-1 is open (OSS content,
78
+ read-only). Bearer / CF Access / HMAC moves to MVP-2 alongside
79
+ tool restoration.
80
+ - **Network egress from the Worker** beyond an **explicit subrequest
81
+ allowlist** — see invariants below.
82
+
83
+ ## A0-cloud invariants
84
+
85
+ The Worker code must satisfy all of:
86
+
87
+ 1. **Origin allowlist** — `fetch()` calls from the Worker are limited
88
+ to R2 (content read) and an explicit observability sink (optional).
89
+ No calls to consumer infrastructure, no calls to upstream LLM
90
+ APIs, no calls to `api.github.com`, no DNS-based egress. Enforced
91
+ in `wrangler.toml` via Worker-level network policies.
92
+ 2. **R2 write boundary** — the Worker never writes to R2. The release
93
+ pipeline writes under `releases/v<X.Y.Z>-<sha>/` and atomically
94
+ repoints `releases/latest.txt`; the Worker only reads.
95
+ 3. **Per-versioned-URL immutability** — for any
96
+ `mcp.<host>/v<X.Y.Z>/sse`, the response body is deterministic for
97
+ the lifetime of the deployment. Patch fixes ship a new version key;
98
+ the existing key is never rewritten. R2 eventual consistency is
99
+ handled by the unique-key-per-release shape.
100
+ 4. **Cache-TTL policy** — pinned URLs cache at the edge for 1 h
101
+ (safe because immutable); `latest` caches for 5 min (bounded
102
+ staleness window after a repoint). No client may rely on `latest`
103
+ for reproducibility — that is what the pinned URL is for.
104
+ 5. **Prebaked signature** — `skillSetSignature` is computed once by
105
+ the release pipeline against the worktree at the tag and stored in
106
+ `releases/v<X.Y.Z>-<sha>/manifest.json`. The Worker reads, never
107
+ computes. Any signature drift at runtime is a contract violation.
108
+ 6. **No consumer code execution.** No `eval`, no dynamic import of
109
+ content, no shelling out, no spawning a runtime. The Worker is a
110
+ read-and-route function.
111
+ 7. **Single deployment per release.** One `wrangler deploy` per tag.
112
+ Concurrent deployments are not supported; the release pipeline
113
+ serializes through `release: published` + `workflow_dispatch`
114
+ hotfix paths.
115
+ 8. **Ingress protection = edge cache + platform rate limit.** MVP-1
116
+ is auth-less by design; the public surface is shielded by two
117
+ layers Cloudflare provides without code: (a) edge caching per
118
+ invariant 4 (1 h on pinned URLs, 5 min on `latest`) absorbs
119
+ read-loop traffic before it reaches the Worker, and (b)
120
+ Cloudflare's account-level anti-abuse + DDoS shielding caps
121
+ per-IP burst on `*.workers.dev`. These two together **are** the
122
+ MVP-1 auth surrogate. **Promotion triggers** — any of these
123
+ flips HMAC (currently MVP-2 §Out-of-scope) from deferred to
124
+ active before the wake-up triggers below would otherwise fire:
125
+ sustained 429 spikes from origin (cache miss storm), Workers
126
+ request-cost line item exceeding the free-tier budget for two
127
+ consecutive billing periods, or a CVE-class abuse report
128
+ against the endpoint. A per-Worker `[[unsafe.bindings]]`
129
+ rate-limiter in `wrangler.toml` is **not** configured in MVP-1
130
+ — adding one is a contract amendment, not a free hand.
131
+
132
+ ## Deprecated tool stub contract
133
+
134
+ `tools/list` returns:
135
+
136
+ ```json
137
+ [
138
+ {
139
+ "name": "lint_skills",
140
+ "description": "Deprecated on hosted MCP — use the local stdio server (scripts/mcp_server/) which retains this tool. See road-to-cloudflare-mcp-hosting Phase 7 for restoration triggers.",
141
+ "deprecated": true
142
+ },
143
+ {
144
+ "name": "chat_history_append",
145
+ "description": "Deprecated on hosted MCP — filesystem-bound, local-only. Use the local stdio server.",
146
+ "deprecated": true
147
+ }
148
+ ]
149
+ ```
150
+
151
+ `tools/call` against either name returns `isError=true` with the same
152
+ deprecation message. No other tool name is reachable.
153
+
154
+ ## MVP-2 wake-up triggers
155
+
156
+ The Phase-7 deferred items in the roadmap (tool restoration, history
157
+ persistence, auth) wake up only when **all** of these fire:
158
+
159
+ - A named consumer (internal or external) requests hosted lint or
160
+ history.
161
+ - A security review has approved the validation layer for
162
+ `lint_skills` (URI regex allowlist, size limits, timeout,
163
+ concurrency cap).
164
+ - An auth model has been selected (bearer vs. CF Access vs. HMAC).
165
+ - The server stability label has been promoted from *experimental*
166
+ to *beta*.
167
+
168
+ ## Revision policy
169
+
170
+ This contract is **experimental** — breaking changes are allowed in
171
+ any release with a CHANGELOG note. Promotion to `beta` requires at
172
+ least one shipped client connecting to the hosted endpoint end-to-end
173
+ without a contract amendment.
174
+
175
+ ## See also
176
+
177
+ - [`mcp-phase-1-scope.md`](mcp-phase-1-scope.md) — local-stdio kernel
178
+ contract (sibling, not parent).
179
+ - [`STABILITY.md`](../../STABILITY.md) — stability policy for
180
+ `docs/contracts/`.
181
+ - [`mcp-request-signing § Appendix`](../guidelines/agent-infra/mcp-request-signing.md#appendix--http-bridge-stdio-kernel-pattern-reference)
182
+ — bridge pattern reference (the Worker is a flavor of this).
@@ -0,0 +1,195 @@
1
+ ---
2
+ stability: experimental
3
+ ---
4
+
5
+ # MCP Server — Phase 1–6 Scope (A0 Hard Contract)
6
+
7
+ > **Status:** Active · covers Phase 1 (A1–A7) + Phase 2 (B1–B5) +
8
+ > Phase 3 (C1–C4) + Phase 4 (D1–D4) + Phase 6 F1/F3 of
9
+ > `road-to-mcp-server.md`. Phase 6 F2 (SSE transport) is owned by
10
+ > [`mcp-cloud-scope.md`](mcp-cloud-scope.md) — the hosted Cloudflare
11
+ > Worker bridge — and remains out of scope here. This contract retains
12
+ > exclusive ownership of `scripts/mcp_server/` (local stdio).
13
+ > **Stability:** experimental — not linked from README, AGENTS.md, or
14
+ > `docs/architecture.md`. Internal index reference only per `STABILITY.md`.
15
+
16
+ ## Purpose
17
+
18
+ Locks the **execution-safety boundary** for the MCP server through
19
+ Phase 2. Any code under `scripts/mcp_server/` must satisfy this
20
+ contract verbatim. Deviation → not Phase 1/2; promote to a follow-up
21
+ phase with its own design-call gate.
22
+
23
+ ## In-scope (Phase 1 + Phase 2)
24
+
25
+ - Transport: **stdio**. No SSE, no HTTP, no WebSocket.
26
+ - MCP primitives: **`prompts/list`** + **`prompts/get`** — read-only.
27
+ - Source data: **`.agent-src/skills/<name>/SKILL.md`** and
28
+ **`.agent-src/commands/**/*.md`** (compressed projections, never the
29
+ uncompressed source-of-truth tree).
30
+ - Loaded set (Phase 2): every well-formed skill + command under
31
+ `.agent-src/` (Phase 1 hand-picked set retained as a smoke fixture
32
+ in `prompts.py::PHASE_1_SKILLS`).
33
+ - **Pagination** (B4): cursor-based `nextCursor` on `prompts/list`,
34
+ default `page_size=100`. Cursor is an opaque stringified offset.
35
+ - **Hot-reload** (B5): `PromptCache` re-scans on mtime / path-set
36
+ change before each `prompts/list` response. No background thread,
37
+ no inotify, no debounce — the request itself is the rate-limiter.
38
+ - **Frontmatter validation** (B3): entries missing `name` or
39
+ `description` are skipped with a stderr warning at boot; malformed
40
+ files do not crash the server.
41
+ - Process lifetime: one server per project, launched per-client by the
42
+ consumer (Claude Desktop, Zed, Continue) at MCP-config time.
43
+
44
+ ## Out-of-scope (Phase 1 + Phase 2)
45
+
46
+ - **`tools/*` beyond the Phase 4 allowlist** — only the two
47
+ built-in tools listed below in *Phase 4 amendment* are reachable.
48
+ Any other name raises `ValueError`. `work_engine` is not exposed.
49
+ - **`resources/*` beyond rules / guidelines / contexts** — no model
50
+ outputs, no roadmaps, no chat history surfaced as resources.
51
+ - **Filesystem writes outside the Phase 4 write allowlist** — the only
52
+ writable targets are `agents/.agent-chat-history` and
53
+ `.agent-chat-history` under `<consumer_root>`. No log files, no
54
+ telemetry writes, no `.work-state.json` mutation.
55
+ - **Direct shell execution from `mcp_server/*`** — modules under
56
+ `scripts/mcp_server/` do not `import subprocess`, `os.system`, or
57
+ `os.popen` directly. Project helpers that internally spawn shells
58
+ (`skill_linter`'s `--changed` git mode, etc.) may be called only via
59
+ read-only wrappers that bypass those code paths.
60
+ - **Network egress** — the server does not call external APIs;
61
+ the AI Council, anthropic SDK, and openai SDK are not imported by
62
+ any module under `scripts/mcp_server/`.
63
+ - **Authentication / multi-tenancy** — single-process, single-project.
64
+ Multi-tenant SSE is Phase 6 (F2).
65
+
66
+ ## Static guarantees enforced by tests
67
+
68
+ `tests/test_mcp_server.py` asserts the boundary at unit level:
69
+
70
+ 1. `prompts/list` returns the full skills + commands set with
71
+ `skill.<name>` and `command.<name>` wire-name prefixes.
72
+ 2. `prompts/get` returns a non-empty `messages[].content.text` body
73
+ matching the SKILL.md / command-file body (frontmatter stripped).
74
+ 3. `prompts/get` for an unknown name raises `ValueError` (no silent
75
+ fallback to filesystem scan).
76
+ 4. `scripts.mcp_server.prompts` imports cleanly without `subprocess`,
77
+ `os.system`, `os.popen`, or any `requests` / `httpx` call.
78
+ 5. `prompts/list` paginates with `nextCursor` and pages do not
79
+ overlap.
80
+ 6. `PromptCache` re-scans on mtime change (hot-reload).
81
+ 7. Malformed frontmatter is skipped with an error line, not crashed.
82
+
83
+ A future regression that adds a `tools/*` handler outside the
84
+ allowlist or writes outside the Phase 4 write allowlist fails the
85
+ import-surface + behaviour assertions and the contract review in code
86
+ review.
87
+
88
+ ## Phase 4 amendment — tool allowlist (D1–D4)
89
+
90
+ Phase 4 lifts the read-only line for **exactly** the two built-in
91
+ tools registered in `scripts/mcp_server/tools.py::ALLOWLIST`. Every
92
+ other tool name is unreachable: `tools/call` against an unlisted name
93
+ returns `isError=True`.
94
+
95
+ | Tool name | Mode | Side effects |
96
+ |---|---|---|
97
+ | `lint_skills` | read-only | Wraps `scripts.skill_linter.lint_file`. Never spawns `git` (no `--changed`). Returns the same JSON shape as `scripts/skill_linter.py --format json`. |
98
+ | `chat_history_append` | path-scoped write | Wraps `scripts.chat_history.append`. Writes are allowed only when the resolved target is `agents/.agent-chat-history` or `.agent-chat-history` under `<consumer_root>`. `dry_run=True` validates the payload without touching the filesystem. |
99
+
100
+ **Path-scoping invariant** — any tool that writes must resolve its
101
+ target through `_validate_in_tree_path` before the underlying writer
102
+ runs. Escapes (absolute paths outside the root, relative paths that
103
+ resolve outside, or filenames not in the write allowlist) raise
104
+ `ValueError` and surface as `isError=True` in `tools/call`.
105
+
106
+ **Boot-time enumeration** — `run_stdio` prints one stderr line
107
+ listing the registered tool names so operators see the surface at
108
+ launch. Adding a tool to `ALLOWLIST` is a code-review event; no
109
+ settings flag can enable an unlisted tool.
110
+
111
+ Additional tool tests in `tests/test_mcp_server.py`:
112
+
113
+ 8. `tools/list` returns exactly the allowlisted names.
114
+ 9. `tools/call` against a valid `dry_run` payload returns
115
+ `isError=False` with a JSON-serialized result.
116
+ 10. `tools/call` with a path escape returns `isError=True` referencing
117
+ the escape — no exception propagates past the handler.
118
+ 11. `tools/call` against an unknown tool name returns `isError=True`.
119
+ 12. `scripts.mcp_server.tools` does not import `subprocess`,
120
+ `os.system`, `os.popen`, or any HTTP client directly.
121
+
122
+ ## Phase 6 amendment — identity metadata + Docker bundle (F1, F3)
123
+
124
+ Phase 6 adds **observability** and **packaging** without changing the
125
+ A0 wire surface. F2 (SSE transport) is explicitly deferred — see
126
+ status header.
127
+
128
+ ### F1 — Identity metadata
129
+
130
+ Three values surface at server boot, written to **stderr** in a single
131
+ `mcp-server: identity …` line (the canonical surface — the high-level
132
+ MCP SDK builds `serverInfo` with a fixed field set, so wire-surface
133
+ lift waits on SDK support):
134
+
135
+ - **`serverVersion`** — hand-maintained SemVer in
136
+ `scripts/mcp_server/__init__.py::__version__`. Bumps on
137
+ **wire-surface** changes only: new tool, new resource MIME type,
138
+ protocol-level break. Does **not** bump for content edits inside
139
+ `.agent-src/`.
140
+ - **`packageVersion`** — read from `package.json::version` at boot.
141
+ Bumps on every agent-config bundle release; build-ID semantics, not
142
+ a stability signal.
143
+ - **`skillSetSignature`** — first 12 hex chars of the SHA-256 over the
144
+ joined sorted `(path, mtime)` tuples of `PromptCache` and
145
+ `ResourceCache`. **Not a version** — a content fingerprint. Auto-
146
+ updates with every `task sync`; intended for cache-key /
147
+ reproducibility use, never for SemVer-style compatibility claims.
148
+
149
+ Implementation: `scripts/mcp_server/metadata.py`. The signature is
150
+ deterministic for a given snapshot of the loaded file set; any mtime
151
+ change invalidates it.
152
+
153
+ ### F3 — Stdio Docker bundle
154
+
155
+ `docker/mcp-server/Dockerfile` ships a stdio-only image. The contract:
156
+
157
+ - **No HTTP / SSE listener** in the image. Stdio is the only wire.
158
+ - The image embeds `scripts/mcp_server/`, the two tool dependencies
159
+ (`scripts/skill_linter.py`, `scripts/chat_history.py`),
160
+ `.agent-src/`, `docs/guidelines/`, and `package.json`. Nothing
161
+ outside the COPY-listed paths reaches the runtime stage.
162
+ - The image runs as a non-root user (`mcp:mcp`); host volumes mounted
163
+ for `chat_history_append` writes must be writable by that uid/gid.
164
+ - The A0 contract from Phase 1–4 transfers verbatim — the import-
165
+ surface guard tests run identically inside and outside the image.
166
+
167
+ Operator documentation: `docs/setup/mcp-server-docker.md`. The image
168
+ does not introduce a new tool, resource type, or protocol surface.
169
+
170
+ ### What Phase 6 explicitly does **not** add
171
+
172
+ - **No HTTP/SSE transport**, native or otherwise. F2 is deferred to
173
+ the successor roadmap; revival is gated on a real consumer ask, and
174
+ the locked design is the bridge pattern from
175
+ [`mcp-request-signing § Appendix`](../guidelines/agent-infra/mcp-request-signing.md#appendix--http-bridge-stdio-kernel-pattern-reference)
176
+ — never a native SSE server inside `scripts/mcp_server/`.
177
+ - **No new tools** beyond the Phase 4 allowlist.
178
+ - **No multi-tenancy** — the Docker image is single-tenant, one
179
+ process per stdio session. Multi-tenancy lives with the future
180
+ bridge, not the kernel.
181
+
182
+ ## Revision policy
183
+
184
+ This contract is **experimental** — breaking changes are allowed in any
185
+ release with a CHANGELOG note. Promotion to `beta` follows the same
186
+ gate as Phase 1 itself: at least one shipped client renders Phase 1
187
+ prompts end-to-end without a contract amendment.
188
+
189
+ ## See also
190
+
191
+ - [`mcp-cloud-scope.md`](mcp-cloud-scope.md) — hosted Worker contract
192
+ (sibling, not child). Extends the bridge pattern from
193
+ [`mcp-request-signing § Appendix`](../guidelines/agent-infra/mcp-request-signing.md#appendix--http-bridge-stdio-kernel-pattern-reference)
194
+ for multi-tenant SSE.
195
+ - [`STABILITY.md`](STABILITY.md) — stability policy for `docs/contracts/`.
@@ -194,3 +194,7 @@ out-of-scope until a consumer surfaces a tenancy requirement.
194
194
  starts here; the upstream link is the authoritative source.
195
195
  - `road-to-ruflo-adoption.md` **P2.1** — landed this appendix; full
196
196
  bridge fork stays out-of-scope unless the dual trigger fires.
197
+ - [`mcp-cloud-scope.md`](../../contracts/mcp-cloud-scope.md) —
198
+ operationalizes this pattern as a TypeScript Cloudflare Worker (no
199
+ spawned stdio child; R2 blob replaces the child process). HMAC
200
+ `verifyRequest` is deferred to MVP-2 alongside auth.