@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.
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +77 -0
- package/README.md +25 -1
- package/docs/contracts/mcp-cloud-scope.md +182 -0
- package/docs/contracts/mcp-phase-1-scope.md +195 -0
- package/docs/guidelines/agent-infra/mcp-request-signing.md +4 -0
- package/docs/mcp-server.md +164 -0
- package/docs/setup/mcp-cloud-endpoints.md +93 -0
- package/docs/setup/mcp-cloud-registry-listing.md +99 -0
- package/docs/setup/mcp-cloud-setup.md +152 -0
- package/docs/setup/mcp-r2-bootstrap.md +82 -0
- package/docs/setup/mcp-server-docker.md +97 -0
- package/package.json +1 -1
- package/scripts/agent-config +29 -0
- package/scripts/mcp_parity_smoke.py +146 -0
- package/scripts/mcp_server/__init__.py +13 -0
- package/scripts/mcp_server/__main__.py +12 -0
- package/scripts/mcp_server/metadata.py +75 -0
- package/scripts/mcp_server/prompts.py +305 -0
- package/scripts/mcp_server/requirements.txt +4 -0
- package/scripts/mcp_server/resources.py +201 -0
- package/scripts/mcp_server/server.py +269 -0
- package/scripts/mcp_server/tools.py +363 -0
- package/scripts/mcp_setup.sh +87 -0
- package/scripts/pack_mcp_content.py +274 -0
- package/scripts/readme_linter.py +1 -1
- package/scripts/skill_linter.py +7 -0
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.
|