@event4u/agent-config 1.36.1 → 1.37.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.37.0"
10
10
  },
11
11
  "plugins": [
12
12
  {
package/CHANGELOG.md CHANGED
@@ -318,6 +318,53 @@ 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.37.0](https://github.com/event4u-app/agent-config/compare/1.36.1...1.37.0) (2026-05-10)
322
+
323
+ ### Features
324
+
325
+ * **mcp:** add Phase 6 F3 stdio Docker bundle ([acd5e47](https://github.com/event4u-app/agent-config/commit/acd5e47a56b9fb42f57751771087c6b73759d3d5))
326
+ * **mcp:** add Phase 6 F1 identity metadata ([f4700ff](https://github.com/event4u-app/agent-config/commit/f4700ff1f093611220c08fba75c29d12ed57110c))
327
+ * **mcp:** add Phase 4 tool layer with lint_skills and chat_history_append ([fe02108](https://github.com/event4u-app/agent-config/commit/fe0210817e46f4d1710b0d96b7a176c872fc5545))
328
+ * **cli:** expose mcp:setup + mcp:run via ./agent-config ([bf7ff65](https://github.com/event4u-app/agent-config/commit/bf7ff65ab040b482d5f4e716a78148e95ba3bc7f))
329
+ * **mcp:** expose rules, guidelines, contexts as resources ([21d85c5](https://github.com/event4u-app/agent-config/commit/21d85c5142a35dade1129f835821c72944442ead))
330
+ * **mcp:** full skill + command coverage with pagination + hot-reload ([126c976](https://github.com/event4u-app/agent-config/commit/126c976f30e7bf3b714f8b72131b53fcc3e07878))
331
+ * **mcp:** add experimental stdio MCP server exposing 5 stack-agnostic skills ([8e692cf](https://github.com/event4u-app/agent-config/commit/8e692cfbdc14e67f178b11068773d50dd199b4ab))
332
+
333
+ ### Bug Fixes
334
+
335
+ * **agents-md:** revert MCP pointer to keep root under 3000-char cap ([02bed8e](https://github.com/event4u-app/agent-config/commit/02bed8edb13fdcae369bac3843a836c01dc04248))
336
+ * **lint:** emit valid JSON when no skill/rule files changed ([caef1cb](https://github.com/event4u-app/agent-config/commit/caef1cb91def6089cad3ba3d2fd7c728b39731d0))
337
+ * **mcp:** relocate Phase 1 smoke transcript out of agents/roadmaps/ ([addd7c2](https://github.com/event4u-app/agent-config/commit/addd7c2ac4aa7a6527fb9e750ed38d02f1cd51bc))
338
+ * **mcp:** drop roadmap link from Phase 1 scope contract ([ca3c2e8](https://github.com/event4u-app/agent-config/commit/ca3c2e89b6c5ebf06cbc6a55883cf3cf1fbd015a))
339
+
340
+ ### Documentation
341
+
342
+ * **contracts:** amend MCP scope contract for Phase 6 F1 + F3 ([45989c5](https://github.com/event4u-app/agent-config/commit/45989c53d6c9b361ad29b4214984db6cff8f5b5f))
343
+ * **contracts:** amend MCP scope contract for Phase 4 tool allowlist ([87c9622](https://github.com/event4u-app/agent-config/commit/87c9622d165d783a5b1f8c266035791cafbf3ab9))
344
+ * **roadmap:** mark MCP Phase 3 + Phase 5 done ([9ec9494](https://github.com/event4u-app/agent-config/commit/9ec9494be18b6634dcf4383af921b54f283c86ff))
345
+ * **mcp:** canonical MCP server setup guide ([4fd149f](https://github.com/event4u-app/agent-config/commit/4fd149f0b1c6e6b009d2bdd3b4ea80759e31055d))
346
+ * **roadmap:** mark MCP Phase 2 (B1-B5) done + extend scope contract ([5ea1c56](https://github.com/event4u-app/agent-config/commit/5ea1c56d027f432f9c950e8b35805ab91758fd26))
347
+ * **roadmap:** mark MCP Phase 1 (A1–A7) done + record stdio smoke transcript ([aaf8332](https://github.com/event4u-app/agent-config/commit/aaf833292aba530bdeae138fa2255b4576fe699c))
348
+ * **mcp:** add Phase 1 scope contract (experimental, read-only) ([2fa275e](https://github.com/event4u-app/agent-config/commit/2fa275eec70c02741b76abef2b6356c7d0d1c6a7))
349
+
350
+ ### Tests
351
+
352
+ * **mcp:** cover Phase 6 F1 identity metadata ([d3f79ef](https://github.com/event4u-app/agent-config/commit/d3f79eff30f61914fe09667693b41e2ed8c29855))
353
+ * **mcp:** cover Phase 4 tool layer ([217c4ab](https://github.com/event4u-app/agent-config/commit/217c4ab2ed1041006e1ac3102369b8c1569f3653))
354
+ * **mcp:** cover Phase 2 — full coverage, pagination, hot-reload ([f93c019](https://github.com/event4u-app/agent-config/commit/f93c0199adc558119be614fadd677cf37c8c2d5a))
355
+ * **mcp:** make loader tests run when mcp SDK is absent ([8378621](https://github.com/event4u-app/agent-config/commit/8378621be8ec24ccba59be10c49a4384abdc335f))
356
+ * **mcp:** cover Phase 1 loader + import-surface guard + server handlers ([f4fee8b](https://github.com/event4u-app/agent-config/commit/f4fee8b899b0163ea2bfe7099ffa9221b70bf488))
357
+
358
+ ### Chores
359
+
360
+ * **roadmap:** close road-to-mcp-server at 100%, defer F4 to distribution ([0127991](https://github.com/event4u-app/agent-config/commit/01279913f3b2a5caa1eb65f8a7b07a2f841d41af))
361
+ * **roadmap:** defer Phase 6 F2 to road-to-mcp-distribution ([b5e0be7](https://github.com/event4u-app/agent-config/commit/b5e0be7473296bfd5381dc1ace9bc99ae79f5090))
362
+ * **roadmap:** mark MCP Phase 4 (D1-D4) complete ([8c342c8](https://github.com/event4u-app/agent-config/commit/8c342c8508f17133d71528b16d727d5c3c56acfd))
363
+ * **mcp:** add task mcp:setup for one-line install ([ae1f6f9](https://github.com/event4u-app/agent-config/commit/ae1f6f9d355dd5a782fdadb5e67929552caab5ed))
364
+ * ignore .venv-mcp/ for MCP server work ([8bd44d4](https://github.com/event4u-app/agent-config/commit/8bd44d49e359021a000a989bfd7ae7f6f48800db))
365
+
366
+ Tests: 2679 (+58 since 1.36.1)
367
+
321
368
  ## [1.36.1](https://github.com/event4u-app/agent-config/compare/1.36.0...1.36.1) (2026-05-10)
322
369
 
323
370
  ### Refactoring
package/README.md CHANGED
@@ -109,7 +109,7 @@ Install in the same project (dev-only):
109
109
  npm install --save-dev @event4u/agent-memory
110
110
  ```
111
111
 
112
- → [Memory contract & retrieval API](docs/contracts/agent-memory-contract.md) (beta)
112
+ → [Memory contract & retrieval API](docs/contracts/agent-memory-contract.md) (beta) · [Built-in MCP server](docs/mcp-server.md) (experimental — read-only access from Claude Desktop / Cursor / Zed / Continue, install with `task mcp:setup`)
113
113
 
114
114
  ---
115
115
 
@@ -0,0 +1,190 @@
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 deferred to
10
+ > [`road-to-mcp-distribution.md`](../../agents/roadmaps/road-to-mcp-distribution.md)
11
+ > and remains out of scope here.
12
+ > **Stability:** experimental — not linked from README, AGENTS.md, or
13
+ > `docs/architecture.md`. Internal index reference only per `STABILITY.md`.
14
+
15
+ ## Purpose
16
+
17
+ Locks the **execution-safety boundary** for the MCP server through
18
+ Phase 2. Any code under `scripts/mcp_server/` must satisfy this
19
+ contract verbatim. Deviation → not Phase 1/2; promote to a follow-up
20
+ phase with its own design-call gate.
21
+
22
+ ## In-scope (Phase 1 + Phase 2)
23
+
24
+ - Transport: **stdio**. No SSE, no HTTP, no WebSocket.
25
+ - MCP primitives: **`prompts/list`** + **`prompts/get`** — read-only.
26
+ - Source data: **`.agent-src/skills/<name>/SKILL.md`** and
27
+ **`.agent-src/commands/**/*.md`** (compressed projections, never the
28
+ uncompressed source-of-truth tree).
29
+ - Loaded set (Phase 2): every well-formed skill + command under
30
+ `.agent-src/` (Phase 1 hand-picked set retained as a smoke fixture
31
+ in `prompts.py::PHASE_1_SKILLS`).
32
+ - **Pagination** (B4): cursor-based `nextCursor` on `prompts/list`,
33
+ default `page_size=100`. Cursor is an opaque stringified offset.
34
+ - **Hot-reload** (B5): `PromptCache` re-scans on mtime / path-set
35
+ change before each `prompts/list` response. No background thread,
36
+ no inotify, no debounce — the request itself is the rate-limiter.
37
+ - **Frontmatter validation** (B3): entries missing `name` or
38
+ `description` are skipped with a stderr warning at boot; malformed
39
+ files do not crash the server.
40
+ - Process lifetime: one server per project, launched per-client by the
41
+ consumer (Claude Desktop, Zed, Continue) at MCP-config time.
42
+
43
+ ## Out-of-scope (Phase 1 + Phase 2)
44
+
45
+ - **`tools/*` beyond the Phase 4 allowlist** — only the two
46
+ built-in tools listed below in *Phase 4 amendment* are reachable.
47
+ Any other name raises `ValueError`. `work_engine` is not exposed.
48
+ - **`resources/*` beyond rules / guidelines / contexts** — no model
49
+ outputs, no roadmaps, no chat history surfaced as resources.
50
+ - **Filesystem writes outside the Phase 4 write allowlist** — the only
51
+ writable targets are `agents/.agent-chat-history` and
52
+ `.agent-chat-history` under `<consumer_root>`. No log files, no
53
+ telemetry writes, no `.work-state.json` mutation.
54
+ - **Direct shell execution from `mcp_server/*`** — modules under
55
+ `scripts/mcp_server/` do not `import subprocess`, `os.system`, or
56
+ `os.popen` directly. Project helpers that internally spawn shells
57
+ (`skill_linter`'s `--changed` git mode, etc.) may be called only via
58
+ read-only wrappers that bypass those code paths.
59
+ - **Network egress** — the server does not call external APIs;
60
+ the AI Council, anthropic SDK, and openai SDK are not imported by
61
+ any module under `scripts/mcp_server/`.
62
+ - **Authentication / multi-tenancy** — single-process, single-project.
63
+ Multi-tenant SSE is Phase 6 (F2).
64
+
65
+ ## Static guarantees enforced by tests
66
+
67
+ `tests/test_mcp_server.py` asserts the boundary at unit level:
68
+
69
+ 1. `prompts/list` returns the full skills + commands set with
70
+ `skill.<name>` and `command.<name>` wire-name prefixes.
71
+ 2. `prompts/get` returns a non-empty `messages[].content.text` body
72
+ matching the SKILL.md / command-file body (frontmatter stripped).
73
+ 3. `prompts/get` for an unknown name raises `ValueError` (no silent
74
+ fallback to filesystem scan).
75
+ 4. `scripts.mcp_server.prompts` imports cleanly without `subprocess`,
76
+ `os.system`, `os.popen`, or any `requests` / `httpx` call.
77
+ 5. `prompts/list` paginates with `nextCursor` and pages do not
78
+ overlap.
79
+ 6. `PromptCache` re-scans on mtime change (hot-reload).
80
+ 7. Malformed frontmatter is skipped with an error line, not crashed.
81
+
82
+ A future regression that adds a `tools/*` handler outside the
83
+ allowlist or writes outside the Phase 4 write allowlist fails the
84
+ import-surface + behaviour assertions and the contract review in code
85
+ review.
86
+
87
+ ## Phase 4 amendment — tool allowlist (D1–D4)
88
+
89
+ Phase 4 lifts the read-only line for **exactly** the two built-in
90
+ tools registered in `scripts/mcp_server/tools.py::ALLOWLIST`. Every
91
+ other tool name is unreachable: `tools/call` against an unlisted name
92
+ returns `isError=True`.
93
+
94
+ | Tool name | Mode | Side effects |
95
+ |---|---|---|
96
+ | `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`. |
97
+ | `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. |
98
+
99
+ **Path-scoping invariant** — any tool that writes must resolve its
100
+ target through `_validate_in_tree_path` before the underlying writer
101
+ runs. Escapes (absolute paths outside the root, relative paths that
102
+ resolve outside, or filenames not in the write allowlist) raise
103
+ `ValueError` and surface as `isError=True` in `tools/call`.
104
+
105
+ **Boot-time enumeration** — `run_stdio` prints one stderr line
106
+ listing the registered tool names so operators see the surface at
107
+ launch. Adding a tool to `ALLOWLIST` is a code-review event; no
108
+ settings flag can enable an unlisted tool.
109
+
110
+ Additional tool tests in `tests/test_mcp_server.py`:
111
+
112
+ 8. `tools/list` returns exactly the allowlisted names.
113
+ 9. `tools/call` against a valid `dry_run` payload returns
114
+ `isError=False` with a JSON-serialized result.
115
+ 10. `tools/call` with a path escape returns `isError=True` referencing
116
+ the escape — no exception propagates past the handler.
117
+ 11. `tools/call` against an unknown tool name returns `isError=True`.
118
+ 12. `scripts.mcp_server.tools` does not import `subprocess`,
119
+ `os.system`, `os.popen`, or any HTTP client directly.
120
+
121
+ ## Phase 6 amendment — identity metadata + Docker bundle (F1, F3)
122
+
123
+ Phase 6 adds **observability** and **packaging** without changing the
124
+ A0 wire surface. F2 (SSE transport) is explicitly deferred — see
125
+ status header.
126
+
127
+ ### F1 — Identity metadata
128
+
129
+ Three values surface at server boot, written to **stderr** in a single
130
+ `mcp-server: identity …` line (the canonical surface — the high-level
131
+ MCP SDK builds `serverInfo` with a fixed field set, so wire-surface
132
+ lift waits on SDK support):
133
+
134
+ - **`serverVersion`** — hand-maintained SemVer in
135
+ `scripts/mcp_server/__init__.py::__version__`. Bumps on
136
+ **wire-surface** changes only: new tool, new resource MIME type,
137
+ protocol-level break. Does **not** bump for content edits inside
138
+ `.agent-src/`.
139
+ - **`packageVersion`** — read from `package.json::version` at boot.
140
+ Bumps on every agent-config bundle release; build-ID semantics, not
141
+ a stability signal.
142
+ - **`skillSetSignature`** — first 12 hex chars of the SHA-256 over the
143
+ joined sorted `(path, mtime)` tuples of `PromptCache` and
144
+ `ResourceCache`. **Not a version** — a content fingerprint. Auto-
145
+ updates with every `task sync`; intended for cache-key /
146
+ reproducibility use, never for SemVer-style compatibility claims.
147
+
148
+ Implementation: `scripts/mcp_server/metadata.py`. The signature is
149
+ deterministic for a given snapshot of the loaded file set; any mtime
150
+ change invalidates it.
151
+
152
+ ### F3 — Stdio Docker bundle
153
+
154
+ `docker/mcp-server/Dockerfile` ships a stdio-only image. The contract:
155
+
156
+ - **No HTTP / SSE listener** in the image. Stdio is the only wire.
157
+ - The image embeds `scripts/mcp_server/`, the two tool dependencies
158
+ (`scripts/skill_linter.py`, `scripts/chat_history.py`),
159
+ `.agent-src/`, `docs/guidelines/`, and `package.json`. Nothing
160
+ outside the COPY-listed paths reaches the runtime stage.
161
+ - The image runs as a non-root user (`mcp:mcp`); host volumes mounted
162
+ for `chat_history_append` writes must be writable by that uid/gid.
163
+ - The A0 contract from Phase 1–4 transfers verbatim — the import-
164
+ surface guard tests run identically inside and outside the image.
165
+
166
+ Operator documentation: `docs/setup/mcp-server-docker.md`. The image
167
+ does not introduce a new tool, resource type, or protocol surface.
168
+
169
+ ### What Phase 6 explicitly does **not** add
170
+
171
+ - **No HTTP/SSE transport**, native or otherwise. F2 is deferred to
172
+ the successor roadmap; revival is gated on a real consumer ask, and
173
+ the locked design is the bridge pattern from
174
+ [`mcp-request-signing § Appendix`](../guidelines/agent-infra/mcp-request-signing.md#appendix--http-bridge-stdio-kernel-pattern-reference)
175
+ — never a native SSE server inside `scripts/mcp_server/`.
176
+ - **No new tools** beyond the Phase 4 allowlist.
177
+ - **No multi-tenancy** — the Docker image is single-tenant, one
178
+ process per stdio session. Multi-tenancy lives with the future
179
+ bridge, not the kernel.
180
+
181
+ ## Revision policy
182
+
183
+ This contract is **experimental** — breaking changes are allowed in any
184
+ release with a CHANGELOG note. Promotion to `beta` follows the same
185
+ gate as Phase 1 itself: at least one shipped client renders Phase 1
186
+ prompts end-to-end without a contract amendment.
187
+
188
+ ## See also
189
+
190
+ - [`STABILITY.md`](STABILITY.md) — stability policy for `docs/contracts/`.
@@ -0,0 +1,156 @@
1
+ # MCP Server
2
+
3
+ > Status: **experimental** — Phase 1 + 2 + 3 shipped. No `tools/*` primitive yet (Phase 4, deferred behind a design call).
4
+
5
+ `agent-config` ships a built-in [Model Context Protocol](https://modelcontextprotocol.io)
6
+ server that exposes the package's read-only governance surface to MCP-aware
7
+ clients (Claude Desktop, Cursor, Zed, Continue, Codex via MCP). Two channels
8
+ coexist:
9
+
10
+ - **File projection** — `task generate-tools` writes `.claude/`, `.cursor/`,
11
+ `.clinerules/`, `.windsurfrules`. Used by Aider, Cline, Windsurf, Gemini CLI.
12
+ - **MCP server** — `scripts/mcp_server/` exposes the same content over
13
+ JSON-RPC. Used by clients that speak MCP natively.
14
+
15
+ The MCP server **never executes engine code, never writes files, never spawns
16
+ shells**. It is a read-only instructional surface — see
17
+ [`docs/contracts/mcp-phase-1-scope.md`](contracts/mcp-phase-1-scope.md).
18
+
19
+ ## What the server exposes
20
+
21
+ | Primitive | URIs | Source | Count (this package) |
22
+ |---|---|---|---|
23
+ | `prompts/list` + `prompts/get` | `skill.<name>`, `command.<name>` | `.agent-src/skills/`, `.agent-src/commands/` | 174 skills + 104 commands |
24
+ | `resources/list` + `resources/read` | `rule://<stem>` | `.agent-src/rules/` | 60 rules |
25
+ | ↳ | `guideline://<relpath>` | `docs/guidelines/` | 69 guidelines |
26
+ | ↳ | `context://<relpath>` | `.agent-src/contexts/` | 31 contexts |
27
+
28
+ All resources are served with `mimeType: text/markdown`. Pagination is
29
+ cursor-based (default page size: 100). Hot-reload triggers automatically on
30
+ file mtime changes — edit a rule, reissue `resources/list`, see the update.
31
+
32
+ ## Setup — one-line install
33
+
34
+ ```bash
35
+ task mcp:setup # maintainer / dev repo
36
+ ./agent-config mcp:setup # consumer projects (uses the package CLI wrapper)
37
+ ```
38
+
39
+ Either form creates `.venv-mcp/` (Python 3.11+), installs the `mcp` SDK, and
40
+ prints the client config snippet. Run once per checkout.
41
+
42
+ If you do not have `task` or the CLI wrapper available:
43
+
44
+ ```bash
45
+ bash scripts/mcp_setup.sh
46
+ ```
47
+
48
+ ## Running the server
49
+
50
+ ```bash
51
+ task mcp:run # maintainer / dev repo
52
+ ./agent-config mcp:run # consumer projects
53
+ ```
54
+
55
+ Both forms launch `python -m scripts.mcp_server` over stdio against the
56
+ local `.venv-mcp/`. Use these for ad-hoc smoke tests; long-running clients
57
+ (Claude Desktop, Cursor, Zed, Continue) launch the server themselves via
58
+ the config snippets below.
59
+
60
+ ## Client configuration
61
+
62
+ ### Claude Desktop
63
+
64
+ Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS)
65
+ or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):
66
+
67
+ ```json
68
+ {
69
+ "mcpServers": {
70
+ "agent-config": {
71
+ "command": "/absolute/path/to/agent-config/.venv-mcp/bin/python",
72
+ "args": ["-m", "scripts.mcp_server"],
73
+ "cwd": "/absolute/path/to/agent-config"
74
+ }
75
+ }
76
+ }
77
+ ```
78
+
79
+ Restart Claude Desktop. The skills, commands, rules, guidelines, and contexts
80
+ appear under the connector dropdown.
81
+
82
+ ### Cursor
83
+
84
+ `~/.cursor/mcp.json` (or `<repo>/.cursor/mcp.json`):
85
+
86
+ ```json
87
+ {
88
+ "mcpServers": {
89
+ "agent-config": {
90
+ "command": "/absolute/path/to/agent-config/.venv-mcp/bin/python",
91
+ "args": ["-m", "scripts.mcp_server"],
92
+ "cwd": "/absolute/path/to/agent-config"
93
+ }
94
+ }
95
+ }
96
+ ```
97
+
98
+ ### Zed
99
+
100
+ `~/.config/zed/settings.json`:
101
+
102
+ ```json
103
+ {
104
+ "context_servers": {
105
+ "agent-config": {
106
+ "command": {
107
+ "path": "/absolute/path/to/agent-config/.venv-mcp/bin/python",
108
+ "args": ["-m", "scripts.mcp_server"]
109
+ },
110
+ "settings": {}
111
+ }
112
+ }
113
+ }
114
+ ```
115
+
116
+ ### Continue (`continue.dev`)
117
+
118
+ `~/.continue/config.yaml`:
119
+
120
+ ```yaml
121
+ mcpServers:
122
+ - name: agent-config
123
+ command: /absolute/path/to/agent-config/.venv-mcp/bin/python
124
+ args: ["-m", "scripts.mcp_server"]
125
+ cwd: /absolute/path/to/agent-config
126
+ ```
127
+
128
+ ## Smoke test
129
+
130
+ After configuring a client, run a manual stdio handshake to verify the server
131
+ boots cleanly:
132
+
133
+ ```bash
134
+ ./agent-config mcp:run < /dev/null
135
+ # Expect stderr: "mcp-server: loaded N prompts (0 warnings)" and
136
+ # "mcp-server: loaded 160 resources (0 warnings)"
137
+ ```
138
+
139
+ ## Troubleshooting
140
+
141
+ | Symptom | Fix |
142
+ |---|---|
143
+ | Client shows no prompts | Confirm the `cwd` points at the repo root (where `.agent-src/` lives), not at `scripts/`. |
144
+ | `ModuleNotFoundError: mcp` | Re-run `task mcp:setup`. The MCP runtime is isolated in `.venv-mcp/` — the project's base Python 3.9 deliberately does not see it. |
145
+ | Stale prompts after editing | Hot-reload triggers on mtime; touch the file or reissue `resources/list`. |
146
+ | Client refuses to start the server | Check the client's log for the full command. Most clients require **absolute** paths in `command` and `cwd`. |
147
+
148
+ ## Scope
149
+
150
+ - **In scope:** read-only prompts + resources, pagination, hot-reload, stdio
151
+ transport, free-tier client compatibility.
152
+ - **Out of scope (Phase 4+):** `tools/*` primitive, SSE / HTTP transport,
153
+ cloud distribution, signed payloads. Tracked in
154
+ [`agents/roadmaps/road-to-mcp-server.md`](../agents/roadmaps/road-to-mcp-server.md).
155
+
156
+ ← [Architecture](architecture.md) · [MCP config generation (consumer side)](mcp.md)
@@ -0,0 +1,97 @@
1
+ # MCP server — Docker (stdio bundle)
2
+
3
+ Phase-6 F3 ships `docker/mcp-server/Dockerfile`: a stdio-only image of
4
+ the agent-config MCP server, pinned to the same `mcp` + `PyYAML`
5
+ versions the test suite runs against. No HTTP / SSE transport — that
6
+ lives in [`road-to-mcp-distribution.md`](../../agents/roadmaps/road-to-mcp-distribution.md)
7
+ under its own A0 amendment.
8
+
9
+ ## Build
10
+
11
+ Build context is the **repo root**, not `docker/mcp-server/` — the
12
+ `COPY` lines reference paths relative to the project root.
13
+
14
+ ```bash
15
+ docker build -f docker/mcp-server/Dockerfile -t agent-config-mcp:local .
16
+ ```
17
+
18
+ Tag conventions:
19
+
20
+ - `:local` — your machine, current working tree
21
+ - `:vX.Y.Z` — pinned to `package.json::version` at release time
22
+ - `:latest` — most recent release (avoid in MCP client configs; pin)
23
+
24
+ ## Run (stdio)
25
+
26
+ The image speaks MCP over **stdin / stdout**. `docker run` must be
27
+ invoked with `-i` (interactive stdin) — without it the server has
28
+ nothing to read and exits silently.
29
+
30
+ ```bash
31
+ docker run --rm -i agent-config-mcp:local
32
+ ```
33
+
34
+ You should see, on **stderr**:
35
+
36
+ ```
37
+ mcp-server: loaded 278 prompts (0 warnings)
38
+ mcp-server: loaded 160 resources (0 warnings)
39
+ mcp-server: registered 2 tools: ['chat_history_append', 'lint_skills']
40
+ mcp-server: identity serverVersion=0.1.0 packageVersion=1.36.1 skillSetSignature=<12-hex>
41
+ ```
42
+
43
+ The fourth line is the F1 identity surface — see
44
+ [`mcp-phase-1-scope.md § Phase 6`](../contracts/mcp-phase-1-scope.md)
45
+ for semantics.
46
+
47
+ ## Wire into an MCP client
48
+
49
+ ```jsonc
50
+ // .mcp.json (or your client's equivalent)
51
+ {
52
+ "mcpServers": {
53
+ "agent-config": {
54
+ "command": "docker",
55
+ "args": ["run", "--rm", "-i", "agent-config-mcp:vX.Y.Z"]
56
+ }
57
+ }
58
+ }
59
+ ```
60
+
61
+ ## Volume mounts (`chat_history_append`)
62
+
63
+ The `chat_history_append` tool writes to
64
+ `agents/.agent-chat-history` **inside the container**. For writes to
65
+ survive container lifecycle, mount the host directory:
66
+
67
+ ```bash
68
+ docker run --rm -i \
69
+ -v "$(pwd)/agents/.agent-chat-history:/app/agents/.agent-chat-history" \
70
+ agent-config-mcp:local
71
+ ```
72
+
73
+ Without the mount the tool still succeeds (path-scope check passes
74
+ inside the container), but the appended JSONL evaporates when the
75
+ container exits. The `lint_skills` tool is read-only and needs no
76
+ mount.
77
+
78
+ ## Security posture
79
+
80
+ The image inherits the A0 contract verbatim — see
81
+ [`mcp-phase-1-scope.md`](../contracts/mcp-phase-1-scope.md):
82
+
83
+ - No `subprocess`, `os.system`, `requests`, `httpx`, or `urllib`
84
+ imports anywhere on the MCP wire surface (enforced by
85
+ `test_no_unsafe_imports_in_*` tests).
86
+ - Tools allowlist is hardcoded in `scripts/mcp_server/tools.py`. The
87
+ container cannot grow new tools at runtime.
88
+ - Image runs as a non-root user (`mcp:mcp`). Mounted host paths must
89
+ be writable by uid/gid `999` or you'll see permission errors.
90
+ - No HTTP listener — there is no network attack surface. Stdin/stdout
91
+ only.
92
+
93
+ ## Size
94
+
95
+ The runtime stage is `python:3.11-slim` + the pinned deps + the
96
+ `.agent-src/` content. Expect ~150-200 MB; the builder stage is
97
+ discarded.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@event4u/agent-config",
3
- "version": "1.36.1",
3
+ "version": "1.37.0",
4
4
  "description": "Shared agent configuration \u2014 skills, rules, commands, guidelines, and templates for AI coding tools",
5
5
  "license": "MIT",
6
6
  "private": false,
@@ -44,6 +44,10 @@ Commands:
44
44
  mcp:render Render mcp.json → .cursor/mcp.json, .windsurf/mcp.json
45
45
  (pass --claude-desktop to also write user-scope config)
46
46
  mcp:check Dry-run mcp:render; exit non-zero if targets are stale
47
+ mcp:setup Create .venv-mcp/ and install the mcp SDK
48
+ (one-line MCP server onboarding; idempotent)
49
+ mcp:run Run the built-in MCP server over stdio
50
+ (requires `mcp:setup` first; see docs/mcp-server.md)
47
51
  roadmap:progress Regenerate agents/roadmaps-progress.md from open roadmaps
48
52
  roadmap:progress-check Fail if agents/roadmaps-progress.md is stale (for CI)
49
53
  hooks:install Install the pre-commit roadmap-progress hook
@@ -97,6 +101,8 @@ Examples:
97
101
  ./agent-config mcp:render
98
102
  ./agent-config mcp:render --claude-desktop
99
103
  ./agent-config mcp:check
104
+ ./agent-config mcp:setup
105
+ ./agent-config mcp:run
100
106
  ./agent-config roadmap:progress
101
107
  ./agent-config hooks:install
102
108
  ./agent-config keys:install-anthropic
@@ -198,6 +204,27 @@ cmd_mcp_check() {
198
204
  exec python3 "$script" --check "$@"
199
205
  }
200
206
 
207
+ cmd_mcp_setup() {
208
+ local script
209
+ script="$(resolve_script "scripts/mcp_setup.sh")" || return 1
210
+ exec bash "$script" "$@"
211
+ }
212
+
213
+ # Run the built-in stdio MCP server. The server module ships inside the
214
+ # package (PACKAGE_ROOT/scripts/mcp_server/), but the venv is created by
215
+ # `mcp_setup.sh` at CWD — keeping consumer projects in control of where
216
+ # the SDK install lives. PYTHONPATH points at PACKAGE_ROOT so the
217
+ # `scripts.mcp_server` import resolves regardless of CWD.
218
+ cmd_mcp_run() {
219
+ local venv_py="$CONSUMER_ROOT/.venv-mcp/bin/python"
220
+ if [[ ! -x "$venv_py" ]]; then
221
+ echo "❌ agent-config: .venv-mcp/ not found at $CONSUMER_ROOT/.venv-mcp" >&2
222
+ echo " Run \`./agent-config mcp:setup\` first to create it." >&2
223
+ exit 1
224
+ fi
225
+ exec env PYTHONPATH="$PACKAGE_ROOT" "$venv_py" -m scripts.mcp_server "$@"
226
+ }
227
+
201
228
  cmd_roadmap_progress() {
202
229
  require_python3
203
230
  local script
@@ -484,6 +511,8 @@ main() {
484
511
  case "$cmd" in
485
512
  mcp:render) cmd_mcp_render "$@" ;;
486
513
  mcp:check) cmd_mcp_check "$@" ;;
514
+ mcp:setup) cmd_mcp_setup "$@" ;;
515
+ mcp:run) cmd_mcp_run "$@" ;;
487
516
  roadmap:progress) cmd_roadmap_progress "$@" ;;
488
517
  roadmap:progress-check) cmd_roadmap_progress_check "$@" ;;
489
518
  hooks:install) cmd_hooks_install "$@" ;;
@@ -0,0 +1,13 @@
1
+ """MCP server for agent-config — Phase 1 MVP.
2
+
3
+ Exposes a hand-picked subset of `.agent-src/skills/` as MCP `prompts`
4
+ over stdio. Read-only and instructional per the A0 execution-safety
5
+ boundary in `agents/roadmaps/road-to-mcp-server.md`. No `tools`
6
+ primitive, no engine spawn, no shell execution.
7
+
8
+ Stability: experimental. Contract: `docs/contracts/mcp-phase-1-scope.md`.
9
+ """
10
+ from __future__ import annotations
11
+
12
+ __version__ = "0.1.0"
13
+ SERVER_NAME = "agent-config"
@@ -0,0 +1,12 @@
1
+ """Entrypoint — `python -m scripts.mcp_server`.
2
+
3
+ Required by Claude Desktop / Zed / Continue stdio-server config.
4
+ The wrapper forwards to `server.main()`; keep this file flat so
5
+ crash tracebacks point at server.py, not the bootstrap.
6
+ """
7
+ from __future__ import annotations
8
+
9
+ from .server import main
10
+
11
+ if __name__ == "__main__":
12
+ main()