@cyanheads/mcp-ts-core 0.12.9 → 0.13.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.
Files changed (93) hide show
  1. package/AGENTS.md +11 -10
  2. package/CLAUDE.md +11 -10
  3. package/README.md +1 -1
  4. package/biome.json +1 -1
  5. package/changelog/0.13.x/0.13.0.md +48 -0
  6. package/changelog/template.md +7 -24
  7. package/dist/cli/init.js +2 -2
  8. package/dist/cli/init.js.map +1 -1
  9. package/dist/config/envValue.d.ts +18 -0
  10. package/dist/config/envValue.d.ts.map +1 -0
  11. package/dist/config/envValue.js +35 -0
  12. package/dist/config/envValue.js.map +1 -0
  13. package/dist/config/index.d.ts.map +1 -1
  14. package/dist/config/index.js +5 -7
  15. package/dist/config/index.js.map +1 -1
  16. package/dist/config/parseEnvConfig.d.ts +7 -0
  17. package/dist/config/parseEnvConfig.d.ts.map +1 -1
  18. package/dist/config/parseEnvConfig.js +9 -1
  19. package/dist/config/parseEnvConfig.js.map +1 -1
  20. package/dist/linter/validate.js +2 -2
  21. package/dist/linter/validate.js.map +1 -1
  22. package/framework-skills/README.md +40 -0
  23. package/{skills → framework-skills}/add-app-tool/SKILL.md +2 -2
  24. package/{skills → framework-skills}/add-resource/SKILL.md +2 -2
  25. package/{skills → framework-skills}/add-service/SKILL.md +2 -2
  26. package/{skills → framework-skills}/add-test/SKILL.md +2 -2
  27. package/{skills → framework-skills}/add-tool/SKILL.md +4 -4
  28. package/{skills → framework-skills}/api-config/SKILL.md +3 -1
  29. package/{skills → framework-skills}/api-context/SKILL.md +3 -3
  30. package/{skills → framework-skills}/api-linter/SKILL.md +4 -4
  31. package/{skills → framework-skills}/maintenance/SKILL.md +30 -21
  32. package/{skills → framework-skills}/orchestrations/SKILL.md +2 -2
  33. package/{skills → framework-skills}/orchestrations/workflows/field-test-fix.md +8 -8
  34. package/{skills → framework-skills}/orchestrations/workflows/fix-wrapup-release.md +5 -5
  35. package/{skills → framework-skills}/orchestrations/workflows/greenfield-build.md +11 -11
  36. package/{skills → framework-skills}/orchestrations/workflows/maintenance-release.md +12 -12
  37. package/{skills → framework-skills}/polish-docs-meta/SKILL.md +18 -10
  38. package/{skills → framework-skills}/polish-docs-meta/references/agent-protocol.md +1 -1
  39. package/{skills → framework-skills}/polish-docs-meta/references/readme.md +86 -70
  40. package/{skills → framework-skills}/release-pr-review/SKILL.md +2 -2
  41. package/{skills → framework-skills}/report-issue-framework/SKILL.md +25 -25
  42. package/{skills → framework-skills}/report-issue-local/SKILL.md +22 -24
  43. package/{skills → framework-skills}/setup/SKILL.md +10 -8
  44. package/package.json +8 -8
  45. package/scripts/check-framework-antipatterns.ts +1 -1
  46. package/scripts/check-skill-versions.ts +16 -9
  47. package/scripts/check-skills-sync.ts +64 -13
  48. package/scripts/clean-mcpb.ts +3 -3
  49. package/scripts/devcheck.ts +16 -13
  50. package/scripts/lint-packaging.ts +158 -24
  51. package/scripts/list-skills.ts +2 -2
  52. package/templates/.claude-plugin/plugin.json +5 -1
  53. package/templates/.env.example +1 -1
  54. package/templates/.github/CONTRIBUTING.md +4 -5
  55. package/templates/.github/ISSUE_TEMPLATE/bug_report.yml +5 -4
  56. package/templates/.github/ISSUE_TEMPLATE/config.yml +6 -1
  57. package/templates/.github/ISSUE_TEMPLATE/feature_request.yml +1 -2
  58. package/templates/AGENTS.md +15 -14
  59. package/templates/CLAUDE.md +15 -14
  60. package/templates/_.mcpbignore +1 -1
  61. package/templates/changelog/template.md +7 -24
  62. package/templates/package.json +3 -2
  63. package/templates/src/mcp-server/resources/definitions/echo-app-ui.app-resource.ts +1 -1
  64. package/skills/README.md +0 -38
  65. /package/{skills → framework-skills}/add-export/SKILL.md +0 -0
  66. /package/{skills → framework-skills}/add-prompt/SKILL.md +0 -0
  67. /package/{skills → framework-skills}/add-provider/SKILL.md +0 -0
  68. /package/{skills → framework-skills}/api-auth/SKILL.md +0 -0
  69. /package/{skills → framework-skills}/api-canvas/SKILL.md +0 -0
  70. /package/{skills → framework-skills}/api-errors/SKILL.md +0 -0
  71. /package/{skills → framework-skills}/api-mirror/SKILL.md +0 -0
  72. /package/{skills → framework-skills}/api-services/SKILL.md +0 -0
  73. /package/{skills → framework-skills}/api-services/references/graph.md +0 -0
  74. /package/{skills → framework-skills}/api-services/references/llm.md +0 -0
  75. /package/{skills → framework-skills}/api-services/references/speech.md +0 -0
  76. /package/{skills → framework-skills}/api-telemetry/SKILL.md +0 -0
  77. /package/{skills → framework-skills}/api-testing/SKILL.md +0 -0
  78. /package/{skills → framework-skills}/api-utils/SKILL.md +0 -0
  79. /package/{skills → framework-skills}/api-utils/references/formatting.md +0 -0
  80. /package/{skills → framework-skills}/api-utils/references/parsing.md +0 -0
  81. /package/{skills → framework-skills}/api-utils/references/security.md +0 -0
  82. /package/{skills → framework-skills}/api-workers/SKILL.md +0 -0
  83. /package/{skills → framework-skills}/code-simplifier/SKILL.md +0 -0
  84. /package/{skills → framework-skills}/design-mcp-server/SKILL.md +0 -0
  85. /package/{skills → framework-skills}/field-test/SKILL.md +0 -0
  86. /package/{skills → framework-skills}/git-wrapup/SKILL.md +0 -0
  87. /package/{skills → framework-skills}/polish-docs-meta/references/package-meta.md +0 -0
  88. /package/{skills → framework-skills}/polish-docs-meta/references/server-json.md +0 -0
  89. /package/{skills → framework-skills}/release-and-publish/SKILL.md +0 -0
  90. /package/{skills → framework-skills}/security-pass/SKILL.md +0 -0
  91. /package/{skills → framework-skills}/techniques/SKILL.md +0 -0
  92. /package/{skills → framework-skills}/techniques/references/outline-on-overflow.md +0 -0
  93. /package/{skills → framework-skills}/tool-defs-analysis/SKILL.md +0 -0
@@ -4,7 +4,7 @@ description: >
4
4
  Finalize documentation and project metadata for a ship-ready MCP server. Use after implementation is complete, tests pass, and devcheck is clean. Safe to run at any stage — each step checks current state and only acts on what still needs work.
5
5
  metadata:
6
6
  author: cyanheads
7
- version: "2.13"
7
+ version: "2.15"
8
8
  audience: external
9
9
  type: workflow
10
10
  ---
@@ -48,13 +48,17 @@ Capture: tool count, resource count, prompt count, service count, required env v
48
48
 
49
49
  ### 2. README.md
50
50
 
51
- Read `references/readme.md` for structure and conventions. If `README.md` doesn't exist, create it from scratch. If it exists, diff the current content against the audit — update tool/resource/prompt tables, env var lists, and descriptions to match the actual surface area. Don't rewrite sections that are already accurate.
51
+ **Read the gold standard first: the `pubmed-mcp-server` README** — https://github.com/cyanheads/pubmed-mcp-server/blob/main/README.md (or `../pubmed-mcp-server/README.md` when that repo is checked out beside this one). Mirror its structure, section order, heading forms, and density. Reuse its non-server-specific content as-is — the framework line under Features, and the Getting started / Configuration / Running the server / Development guide / Contributing boilerplate — and tune only what is server-specific: the header, the Overview description, the primitives and their Capability reference entries, the domain-specific and agent-friendly bullets, env vars, project structure. Then read `references/readme.md` for the conventions spelled out; where it and the pubmed README disagree, the README wins — note the discrepancy in your report rather than editing the reference.
52
+
53
+ If `README.md` doesn't exist, create it from scratch. If it exists, diff the current content against the audit — update tool/resource/prompt tables, env var lists, and descriptions to match the actual surface area. Don't restructure sections that are already accurate and already in the gold-standard shape.
54
+
55
+ **Every run is also a concision pass.** READMEs accrete: each release adds a bullet, and nobody removes one. Accurate is not the same as done — on every run, tighten what is already there, especially the Capability reference. Read `references/readme.md` § *Concision* for what to keep and what to cut. The bar is natural prose a human reads once, that still carries every fact a caller needs before the first call, and where every retained claim has been checked against the definition it describes.
52
56
 
53
57
  The bold header tagline (the `<b>` text inside the first `<p>`) must match the `package.json` `description`. The surface count is a nested `<div>` inside the same `<p>`, separated by `•`.
54
58
 
55
59
  ### 3. Agent Protocol (CLAUDE.md / AGENTS.md)
56
60
 
57
- Update the project's agent protocol file to reflect the actual server. Scope is the project-root `CLAUDE.md` / `AGENTS.md` only — **do not edit `skills/*/SKILL.md` or their `references/` files**. Those are external skill files synced from `@cyanheads/mcp-ts-core` and get overwritten on the next `maintenance` refresh.
61
+ Update the project's agent protocol file to reflect the actual server. Scope is the project-root `CLAUDE.md` / `AGENTS.md` only — **do not edit `framework-skills/*/SKILL.md` or their `references/` files**. Those are external skill files synced from `@cyanheads/mcp-ts-core` and get overwritten on the next `maintenance` refresh.
58
62
 
59
63
  Read `references/agent-protocol.md` for the full update checklist, then review the current file and address what's stale or missing:
60
64
 
@@ -169,7 +173,9 @@ Never hand-edit `CHANGELOG.md` when using this pattern — it's a build artifact
169
173
 
170
174
  ### 10. Plugin Metadata (Codex / Claude Code)
171
175
 
172
- `lint:packaging` (run by `devcheck`) now enforces the high-value subset automatically when these manifests are present: non-empty descriptions, and identity/install correctness — display fields (`name`, server key, `interface.displayName`) must be the **unscoped** machine name, while the `npx -y` install arg must be the full `package.json` `name` (scoped if scoped). Opt out per project with `"packaging": { "pluginManifests": false }` in `devcheck.config.json`. The checks below cover the fields the gate doesn't (version / repository / license sync, category, env vars).
176
+ `lint:packaging` (run by `devcheck`) now enforces the high-value subset automatically when these manifests are present: non-empty descriptions, identity/install correctness — display fields (`name`, server key, `interface.displayName`) must be the **unscoped** machine name, while the `npx -y` install arg must be the full `package.json` `name` (scoped if scoped) — and the env contract below (no `""` values; every `${user_config.*}` reference declared). Opt out per project with `"packaging": { "pluginManifests": false }` in `devcheck.config.json`. The checks below cover the fields the gate doesn't (version / repository / license sync, category, the wording of each option).
177
+
178
+ **How user-supplied values reach the server.** Neither client passes the user's shell environment through untouched, so an env entry of `"KEY": ""` is not a hint — it is the value the server receives, and the framework reads an empty string as unset. Claude Code prompts for values declared under `userConfig` at enable time and substitutes `${user_config.<option>}` into `env` (sensitive values go to the Keychain). Codex starts stdio servers with a whitelisted environment and forwards only the host variables named in `env_vars`. Mirror `manifest.json`'s `user_config` block: same options, same titles and descriptions.
173
179
 
174
180
  If `.codex-plugin/plugin.json` exists, verify it's populated and in sync with `package.json` and `server.json`:
175
181
 
@@ -182,9 +188,9 @@ If `.codex-plugin/plugin.json` exists, verify it's populated and in sync with `p
182
188
  - `interface.shortDescription` matches `package.json` `description`
183
189
  - `interface.category` is set to a meaningful category
184
190
 
185
- If `.codex-plugin/mcp.json` exists, verify the server-name key is the unscoped `package.json` `name`, the `npx -y` install arg is the full `package.json` `name`, and env vars include any required API keys from the server config schema.
191
+ If `.codex-plugin/mcp.json` exists, verify the server-name key is the unscoped `package.json` `name`, the `npx -y` install arg is the full `package.json` `name`, `env` carries only fixed values (`MCP_TRANSPORT_TYPE`), and `env_vars` lists every user-supplied variable from the server config schema (API keys, contact emails, instance URLs) so Codex forwards it from the user's environment.
186
192
 
187
- If `.claude-plugin/plugin.json` exists, apply the same checks: `name` (unscoped), `version`, `description`, `repository`, `license` from `package.json`. Verify the inline `mcpServers` entry key is the unscoped name, its `npx -y` install arg is the full `package.json` `name`, and env vars include any required API keys.
193
+ If `.claude-plugin/plugin.json` exists, apply the same checks: `name` (unscoped), `version`, `description`, `author`, `repository`, `license`, `keywords` from `package.json`, `$schema` set to `https://json.schemastore.org/claude-code-plugin-manifest.json`. Verify the inline `mcpServers` entry key is the unscoped name and its `npx -y` install arg is the full `package.json` `name`. Every user-supplied variable is declared under `userConfig` — `type: "string"`, `title`, `description`, `sensitive: true` for keys and tokens, and either `required: true` or `default: ""` so a blank answer reaches the server as empty rather than as the literal placeholder — and referenced from `env` as `"KEY": "${user_config.<option>}"`. Run `claude plugin validate .` after editing; the CLAUDE.md-at-root warning is expected, anything else is not.
188
194
 
189
195
  ### 11. MCPB Bundling Artifacts
190
196
 
@@ -207,7 +213,8 @@ If the project ships as an `.mcpb` bundle for Claude Desktop (check for `manifes
207
213
  - `manifest.json` `name` matches `package.json` name **without the npm scope prefix** (e.g. `bls-mcp-server`, not `@cyanheads/bls-mcp-server`); `description` matches `package.json`
208
214
  - `manifest.json` `author` is the full person object — `{ "name", "email", "url" }` — carrying the same identity as `package.json` `author` (name matches the LICENSE copyright holder, url is the author's site)
209
215
  - `manifest.json` `user_config` entries must include `title` and `type` fields — `mcpb pack` validates these
210
- - For each `user_config` entry referenced as `${user_config.X}` in `mcp_config.env`: if it's not `required: true`, set `"default": ""`. MCPB hosts (Claude Desktop included) pass the literal placeholder string through to the process when an optional field is left blank without a default — strict consumer validators (`z.email()`, `z.url()`, `.regex()`) then crash at lazy config load, exiting silently after `initialize`. Server-side: pair every optional env-backed strict-validator field with a `z.preprocess` that strips `${...}` placeholders to `undefined`.
216
+ - Every `user_config` entry is referenced from `mcp_config.env` as `"X": "${user_config.X}"`, and `mcp_config` carries no other `${…}` besides MCPB's own path placeholders (`${__dirname}`, `${HOME}`, …). The host substitutes nothing else: a declared option that is never referenced is collected and dropped, and `"X": "${X}"` reaches the server as that literal string. `lint:packaging` enforces both
217
+ - For each `user_config` entry referenced as `${user_config.X}` in `mcp_config.env`: if it's not `required: true`, set `"default": ""`. MCPB hosts (Claude Desktop included) pass the literal placeholder string through to the process when an optional field is left blank without a default — the `default` keeps that string out of the process. Server-side, the framework already treats a whole-value `${…}` placeholder the same as an empty string — unset — in both its own config and `parseEnvConfig`, so an optional field falls through to its default and a required one fails as missing rather than as a format error; a per-field `z.preprocess` guard for placeholders is redundant and can be dropped.
211
218
  - `server.json` env var `isRequired` must match the upstream API's actual requirement — if the API works without the value (rate-limited, DEMO_KEY fallback, polite pool), mark `isRequired: false` and describe the tradeoff in the description
212
219
  - Server description aligned across all surfaces: `package.json`, `manifest.json`, `server.json` (condensed, hard 100-char limit), README header `<p><b>`, and GitHub repo description (`gh repo edit --description`)
213
220
  - `package.json` `keywords` include baseline terms: `mcp`, `mcp-server`, `model-context-protocol`, `typescript`, `bun`, `stdio`, `streamable-http`, plus data-domain terms. GitHub repo topics (`gh repo edit --add-topic`) should match.
@@ -257,7 +264,8 @@ Both must pass clean.
257
264
  ## Checklist
258
265
 
259
266
  - [ ] Surface area audited — tool/resource/prompt/service inventory built
260
- - [ ] `README.md` accurate — tool/resource tables, config, descriptions match actual code
267
+ - [ ] `README.md` accurate — mirrors the `pubmed-mcp-server` gold-standard structure; Overview tables, Capability reference entries, config, and descriptions match actual code
268
+ - [ ] `README.md` concise — Capability reference entries are contract-shaped and within the bullet budget; nothing narrates mechanism the schema already carries; every retained claim verified against its definition
261
269
  - [ ] Agent protocol file accurate — no stale template content, real examples, structure matches reality
262
270
  - [ ] `.env.example` in sync with server config schema
263
271
  - [ ] `package.json` metadata complete (`description`, `mcpName`, `repository`, `author`, `keywords`, `engines`, `packageManager`)
@@ -266,8 +274,8 @@ Both must pass clean.
266
274
  - [ ] `bunfig.toml` present
267
275
  - [ ] Changelog current — either monolithic `CHANGELOG.md` (hand-edited, Keep a Changelog) or directory-based (`changelog/<minor>.x/<version>.md` + rollup regenerated and in sync)
268
276
  - [ ] `.codex-plugin/plugin.json` populated and in sync with `package.json` (if present)
269
- - [ ] `.codex-plugin/mcp.json` server name and env vars current (if present)
270
- - [ ] `.claude-plugin/plugin.json` populated and in sync with `package.json` (if present)
277
+ - [ ] `.codex-plugin/mcp.json` server name current; user-supplied variables in `env_vars`, none as `""` in `env` (if present)
278
+ - [ ] `.claude-plugin/plugin.json` populated and in sync with `package.json`; every user-supplied variable declared in `userConfig` and referenced as `${user_config.<option>}`, none as `""` in `env` (if present)
271
279
  - [ ] MCPB artifacts consistent (if `manifest.json` present) — version synced, env vars match `server.json`, `bundle` + `lint:packaging` scripts exist, README install badges present
272
280
  - [ ] `LICENSE` file present
273
281
  - [ ] `Dockerfile` OCI labels and runtime config accurate (if present)
@@ -54,7 +54,7 @@ If the server has a `server-config.ts`, check whether the Patterns section still
54
54
 
55
55
  ### 6. Update the Skills Table
56
56
 
57
- Check for server-specific skills added to `skills/` that aren't in the table yet. Add any missing entries. Remove framework skills the server doesn't use (rare — most are useful).
57
+ Check for server-specific skills added to `framework-skills/` that aren't in the table yet. Add any missing entries. Remove framework skills the server doesn't use (rare — most are useful).
58
58
 
59
59
  ### 7. Update the Commands Table
60
60
 
@@ -2,6 +2,20 @@
2
2
 
3
3
  Structure and content guide for creating or updating a README for an MCP server built on `@cyanheads/mcp-ts-core`. If a README already exists, use this as a reference to audit and improve it — don't blindly rewrite sections that are already accurate.
4
4
 
5
+ The reference implementation is the `pubmed-mcp-server` README — https://github.com/cyanheads/pubmed-mcp-server/blob/main/README.md. Read it in full before writing, mirror its structure, reuse its non-server-specific content, and treat it as authoritative wherever this file lags behind it.
6
+
7
+ ## Concision
8
+
9
+ A README is read once by a human deciding whether and how to use the server. It is not the changelog, not the schema, and not a proof that a feature works. Apply these on every pass, including re-runs over a README that is already accurate — accuracy is the floor, not the finish.
10
+
11
+ **Keep, always:** canonical identifiers (tool, resource, prompt, field, env var, and enum names, exactly as the code spells them); per-call caps and limits; input alternatives and which are required; the fields a caller branches on (discriminators, typed reasons, status values); feature flags and the env var that controls each; anything a caller must know before the first call. Brevity never earns semantic loss — if cutting a clause drops a fact from this list, the clause stays.
12
+
13
+ **Cut:** narration of how a guarantee is implemented ("so a value stays under the header it belongs to"); restated `.describe()` semantics — the schema carries them at call time; edge-case walkthroughs; the distinction between two similar values when the names already carry it; release-note accretion (a bullet that exists because a version added it, not because a reader needs it); marketing adjectives; a heading's intro sentence that repeats its Overview row.
14
+
15
+ **The test, per bullet:** would a reader lose a fact they need before their first call? If not, cut or merge. If a bullet needs more than two sentences, it is describing mechanism — keep the contract, drop the mechanism.
16
+
17
+ **Validate what stays.** Condensing is where wrong facts creep in — a merged bullet can silently combine two tools' limits or promote a default to a rule. Every identifier, cap, enum value, and default that survives the pass is checked against the definition file before the run ends. Never condense from memory of what the tool does; condense from the schema.
18
+
5
19
  ## Structure
6
20
 
7
21
  Use this section order. Omit sections that don't apply (e.g., skip Docker/Workers if the server doesn't deploy there).
@@ -13,14 +27,15 @@ Install badges ← one centered row — Claude Desktop,
13
27
  Framework badge ← solo spotlight row — `Built on @cyanheads/mcp-ts-core` (cyan-300 #67E8F9)
14
28
  [Public hosted callout if present] ← centered HTML block, directly under the Framework badge
15
29
  ---
16
- ## Tools ← grouping sentence → summary table → per-tool subsections
17
- ## Resources and prompts (if any) ← single combined table (Type / Name / Description)
18
- ## Features ← framework bullets + domain-specific bullets
30
+ ## Overview ← short description paragraph → `### Tools` / `### Resources` / `### Prompts` two-column tables
31
+ ## Capability reference ← one `###` entry per primitive, heading tagged `<sub>tool|resource|prompt</sub>`, contract-shaped bullets
32
+ ## Features ← one-sentence framework line + domain-specific bullets + agent-friendly output bullets
19
33
  ## Getting started ← hosted (if any), bunx/npx/docker configs, HTTP one-liner, prerequisites, install
20
34
  ## Configuration ← env var table + `.env.example` pointer
21
35
  ## Running the server ← dev, production, Workers/Docker
22
36
  ## Project structure ← directory/purpose table
23
37
  ## Development guide ← link to CLAUDE.md/AGENTS.md, key rules
38
+ ## Contributing ← issues only
24
39
  ## License ← one line
25
40
  ```
26
41
 
@@ -108,106 +123,90 @@ If a public hosted instance is available, **promote it to a top-level callout**
108
123
 
109
124
  Keep the full connection-config JSON block inside a `### Public Hosted Instance` subsection under Getting Started (covered below). This callout is just the visibility pointer.
110
125
 
111
- ### Tools
126
+ ### Overview
112
127
 
113
- This is the most important section — it tells humans and LLMs exactly what the server exposes. Three layers: a **grouping framing sentence**, a summary table, then per-tool subsections for tools with non-trivial behavior.
128
+ The first section after the header rule. Two parts: a short description paragraph, then one two-column table per primitive type. This is what a visitor reads to decide whether the server is for them, so it must scan in one screen.
114
129
 
115
- **Grouping framing sentence:** Lead with one sentence that explains how the tool surface is organized. Richer than a bare count — tells the reader what mental model to apply. Examples:
130
+ **Description paragraph:** two or three sentences — what the server sits on top of (the upstream APIs), what a user can do with it (the headline workflows, action verbs), and how it runs (transports, the hosted endpoint if any). Not a count, and not "an MCP server that…" framing.
116
131
 
117
- - "Seventeen tools grouped by shape — workflow helpers orchestrate common flows end-to-end, primitive tools expose fine-grained CRUD, and the instruction tool returns procedural guidance merged with live account state."
118
- - "Nine tools for working with PubMed and NCBI data:"
119
- - "Five tools covering project lifecycle — discovery, task CRUD, and team analytics."
132
+ **Primitive tables:** a `### Tools` table, then `### Resources` and `### Prompts` tables when the server has any. Omit a heading whose table would be empty, but keep a one-row table rather than folding it into another. Two columns, Name/Description, one-line descriptions — the detail lives in the Capability reference.
120
133
 
121
- If the tools aren't meaningfully grouped, a single sentence count ("Seven tools for working with Acme data:") is acceptable.
134
+ ```markdown
135
+ ## Overview
122
136
 
123
- **Summary table:**
137
+ An MCP server over the Acme v2 API. Search projects, manage tasks, and track team activity from any MCP client. Runs as a stdio process, a local Streamable HTTP server, or the public hosted endpoint above.
124
138
 
125
- ```markdown
126
- ## Tools
139
+ ### Tools
127
140
 
128
- Seven tools for working with Acme data:
141
+ | Tool | Description |
142
+ |:---|:---|
143
+ | `acme_search_projects` | Search projects by name, status, or team, with pagination and field selection |
144
+ | `acme_get_task` | Fetch one or more tasks by ID, with full or summary data |
129
145
 
130
- | Tool Name | Description |
131
- |:----------|:------------|
132
- | `acme_search_projects` | Search projects by name, status, or team. |
133
- | `acme_create_task` | Create a new task in a project. |
134
- | `acme_get_task` | Fetch one or more tasks by ID, with full or summary data. |
135
- ```
146
+ ### Resources
136
147
 
137
- **Per-tool subsections:**
148
+ | Resource | Description |
149
+ |:---|:---|
150
+ | `acme://projects/{projectId}` | Project details by ID |
138
151
 
139
- Below the table, add a `### tool_name` subsection for each tool that has meaningful detail beyond its one-line description. Include:
152
+ ### Prompts
140
153
 
141
- - Bullet list of key capabilities (what inputs it accepts, what filtering/pagination it supports, edge cases it handles)
142
- - Link to example file if one exists: `[View detailed examples](./examples/tool_name.md)`
143
- - Separate subsections with `---` horizontal rules
154
+ | Prompt | Description |
155
+ |:---|:---|
156
+ | `project_summary` | Summarize a project's status and open tasks |
157
+ ```
144
158
 
145
- ```markdown
146
- ### `acme_search_projects`
159
+ Derive every row from the actual definitions — real names and descriptions from the Zod schemas.
147
160
 
148
- Search for projects using free-text queries and filters.
161
+ If resource data is also reachable through tools, say so in one line under the Resources table; many MCP clients are tool-only and never surface resources. If a prompt has a design doc, link it in one line under the Prompts table.
149
162
 
150
- - Full-text search plus typed status/phase filters
151
- - Geographic proximity filtering by coordinates and distance
152
- - Pagination (up to 100 per page) and sorting
153
- - Field selection to limit response size
163
+ ### Capability reference
154
164
 
155
- [View detailed examples](./examples/acme_search_projects.md)
165
+ One `###` entry per primitive — every tool, resource, and prompt, in the same order as the Overview tables — with the heading tagged by type in a `<sub>` so a reader scanning headings can tell them apart without a section break. Entries are separated by `---` rules. No intro sentence under the heading — the Overview row already said what it does — go straight to bullets.
156
166
 
157
- ---
167
+ **Bullet density is contract shape, not changelog narration.** Three to six bullets covering: accepted inputs and per-call caps; the output's discriminating fields; the failure shape (typed reasons, per-item status); the knobs (filters, budgets, feature flags). Behavior a caller discovers from the schema at call time — field-by-field semantics, edge-case handling, the mechanism behind a guarantee — belongs in the definition's `.describe()` text, not here. An entry running past six bullets has started transcribing release notes.
158
168
 
159
- ### `acme_get_task`
169
+ ```markdown
170
+ ## Capability reference
160
171
 
161
- Fetch one or more tasks by ID, with full data or concise summaries.
172
+ ### `acme_search_projects` <sub>tool</sub>
162
173
 
163
- - Batch fetch up to 5 tasks at once
164
- - Full data includes subtasks, comments, attachments, and history
165
- - Partial success reporting when some tasks in a batch fail
166
- ```
174
+ - Free-text query plus typed `status` / `phase` filters; up to 100 per page, offset pagination
175
+ - Optional `fields` selection to trim the response
176
+ - Results carry `source` and `fetchedAt` so callers can reason about freshness
167
177
 
168
- Skip the per-tool subsection for simple tools where the table description says everything (e.g., an `acme_get_field_values` lookup tool).
178
+ ---
169
179
 
170
- ### Resources and Prompts (combined)
180
+ ### `acme_get_task` <sub>tool</sub>
171
181
 
172
- **Use a single combined table with a `Type` column** rather than separate `## Resources` and `## Prompts` sections. This is the shipping convention — it scales better when a server has only 1 or 2 of each, and co-locates related content.
182
+ - Up to 5 task IDs per call; `detail: "full"` adds subtasks, comments, attachments, and history
183
+ - Per-item `status` rows — a partial batch returns the resolved tasks alongside typed errors for the rest
173
184
 
174
- ```markdown
175
- ## Resources and prompts
185
+ ---
176
186
 
177
- | Type | Name | Description |
178
- |:---|:---|:---|
179
- | Resource | `acme://projects/{projectId}` | Project details by ID |
180
- | Resource | `acme://tasks/{taskId}` | Task details by ID |
181
- | Prompt | `project_summary` | Summarize a project's status and open tasks |
182
- ```
187
+ ### `acme://projects/{projectId}` <sub>resource</sub>
183
188
 
184
- Use singular ("Resource and prompt") if there's only one of each.
189
+ - Project record as `application/json` — name, status, owners, open task count
190
+ - `projectId` comes from `acme_search_projects`
185
191
 
186
- **Always include the tool-coverage note** directly under the table. Many MCP clients are tool-only and don't surface resources — this tells both the reader and downstream agents that the data is still reachable:
192
+ ---
187
193
 
188
- ```markdown
189
- All resource data is also reachable via tools. Large collections (`projects`, `tasks`) are not exposed as resources — use the `list` operation on the corresponding tool instead.
190
- ```
194
+ ### `project_summary` <sub>prompt</sub>
191
195
 
192
- If a prompt has an associated design doc or reference, link it in the same paragraph: `Design reference for the prompt: [\`docs/email-design-playbook.md\`](./docs/email-design-playbook.md).`
196
+ - Arguments: `projectId` required; `includeClosed` (`"true"` / `"false"`) optional
197
+ - Returns two messages — an assistant framing message and a user message carrying the summary request
198
+ ```
193
199
 
194
- Derive all tool/resource/prompt rows directly from the actual definitions. Use the real names and descriptions from the Zod schemas.
200
+ Link an examples file from an entry when one exists: `[View detailed examples](./examples/acme_search_projects.md)`.
195
201
 
196
202
  ### Features
197
203
 
198
- Three subsection groups: framework capabilities, domain-specific capabilities, then agent-friendly output design. Bullet lists, not prose.
204
+ A one-sentence framework line naming what a user gets from the framework (transports, auth, storage, observability — not how the code is organized; contributor facts belong in the Development guide), then two bullet groups: domain-specific capabilities, then agent-friendly output design.
199
205
 
200
206
  ```markdown
201
207
  ## Features
202
208
 
203
- Built on [`@cyanheads/mcp-ts-core`](https://www.npmjs.com/package/@cyanheads/mcp-ts-core):
204
-
205
- - Declarative tool, resource, and prompt definitions — single file per primitive, framework handles registration and validation
206
- - Unified error handling — handlers throw, framework catches, classifies, and formats
207
- - Pluggable auth: `none`, `jwt`, `oauth`
208
- - Swappable storage backends: `in-memory`, `filesystem`, `Supabase`, `Cloudflare KV/R2/D1`
209
- - Structured logging with optional OpenTelemetry tracing
210
- - STDIO and Streamable HTTP transports
209
+ Built on [`@cyanheads/mcp-ts-core`](https://www.npmjs.com/package/@cyanheads/mcp-ts-core): stdio and Streamable HTTP transports, pluggable auth (`none` / `jwt` / `oauth`), swappable storage (`in-memory`, `filesystem`, `Supabase`, `Cloudflare KV/R2/D1`), structured logging with optional OpenTelemetry tracing.
211
210
 
212
211
  Acme-specific:
213
212
 
@@ -483,6 +482,21 @@ See [`CLAUDE.md`/`AGENTS.md`](./CLAUDE.md) for development guidelines and archit
483
482
  - Wrap external API calls: validate raw → normalize to domain type → return output schema; never fabricate missing fields
484
483
  ```
485
484
 
485
+ ### Contributing
486
+
487
+ Issues only. Never write "pull requests are welcome" or any PR invitation — contributions arrive as issues, and `.github/CONTRIBUTING.md` says the same.
488
+
489
+ ```markdown
490
+ ## Contributing
491
+
492
+ Issues are welcome. Run checks and tests before submitting:
493
+
494
+ \`\`\`sh
495
+ bun run devcheck
496
+ bun run test
497
+ \`\`\`
498
+ ```
499
+
486
500
  ### License
487
501
 
488
502
  One line referencing the LICENSE file.
@@ -495,11 +509,13 @@ Apache-2.0 — see [LICENSE](LICENSE) for details.
495
509
 
496
510
  ## Principles
497
511
 
512
+ - **Gold standard first.** The `pubmed-mcp-server` README is the reference implementation; where it and this file disagree, the README wins.
498
513
  - **Accuracy over aspiration.** Only document what exists. Don't describe planned features as if they're implemented.
499
- - **Tools first.** The tool surface is the most important content. Lead with it.
514
+ - **Surface first.** The primitives are the most important content. The Overview leads with them.
500
515
  - **Tables over prose** for structured data (tools, config, directories). Scannable and diff-friendly.
501
- - **Two-layer tool docs.** Grouping sentence + summary table for quick scanning, per-tool subsections for detail. Skip subsections for trivial tools.
502
- - **Combined resources + prompts.** Single table with a `Type` column, not separate sections.
516
+ - **Overview + reference.** Overview tables for scanning; a Capability reference entry for every primitive, none skipped, with contract-shaped bullets rather than release-note narration.
517
+ - **Concise on every pass.** Re-runs tighten as well as correct; see § *Concision* for what survives a cut and what doesn't, and validate everything that survives.
518
+ - **One two-column table per primitive type.** Tools, resources, and prompts each get a small heading and a Name/Description table, even when a table has one row. No `Type` column — most servers are tool-heavy and many have no resources or prompts.
503
519
  - **Promote hosted instances.** If there's a public URL, put it in a top-level callout under the badges — not buried in Getting Started.
504
520
  - **Three install configs.** `bunx`, `npx`, `docker run` in that order. Each as a complete MCP-client JSON block.
505
521
  - **Real names from code.** Tool names, env vars, and URIs must match the source exactly. Copy from the definitions, don't paraphrase.
@@ -4,7 +4,7 @@ description: >
4
4
  Review pass on an open release PR (`release/<version>` → `main`) — the step between `git-wrapup` and `release-and-publish` when a project releases in gated release PR mode. Reads the PR's commit range through the `code-simplifier` lens plus a correctness review, verifies whatever an automated reviewer left on the PR, lands fixes as fixup commits autosquashed back into the stack, force-with-lease pushes the release branch, keeps the PR body in sync with what ships, and leaves one summary comment. The only agent role that both edits and commits — and it never tags, merges, touches `main`, or publishes.
5
5
  metadata:
6
6
  author: cyanheads
7
- version: "1.0"
7
+ version: "1.1"
8
8
  audience: external
9
9
  type: workflow
10
10
  ---
@@ -35,7 +35,7 @@ git log --oneline main..HEAD # the stack: work co
35
35
  git diff main...HEAD --stat
36
36
  ```
37
37
 
38
- Read `skills/code-simplifier/SKILL.md` in full. Read the changelog entry for this version (`changelog/<major.minor>.x/<version>.md`) — it is the claim the diff has to back.
38
+ Read `framework-skills/code-simplifier/SKILL.md` in full. Read the changelog entry for this version (`changelog/<major.minor>.x/<version>.md`) — it is the claim the diff has to back.
39
39
 
40
40
  ### 2. Establish the review range
41
41
 
@@ -4,7 +4,7 @@ description: >
4
4
  File a bug or feature request against @cyanheads/mcp-ts-core when you hit a framework issue. Use when a builder, utility, context method, or config behaves contrary to the documented API — not for server-specific application bugs.
5
5
  metadata:
6
6
  author: cyanheads
7
- version: "1.9"
7
+ version: "1.10"
8
8
  audience: external
9
9
  type: workflow
10
10
  ---
@@ -38,7 +38,7 @@ gh api 'repos/cyanheads/mcp-ts-core/issues/<number>/timeline' --paginate \
38
38
  --jq '.[] | select(.event=="cross-referenced") | .source.issue | "\(.repository.full_name)#\(.number) — \(.title)"'
39
39
  ```
40
40
 
41
- 5. **For documentation- or contract-shaped requests, audit all three doc layers first** — proposals to add reference docs, public-API conventions, attribute/event catalogs, or stability commitments often duplicate surface that already exists. Check `src/` for behavior, `docs/` for human-facing reference, and `skills/` for agent-facing reference. Skill files marked `audience: external` are the framework's public contract — treat them as authoritative when evaluating whether a documentation gap exists. Also verify the constants or types you'd reference aren't already exported from `@cyanheads/mcp-ts-core` or one of its subpaths.
41
+ 5. **For documentation- or contract-shaped requests, audit all three doc layers first** — proposals to add reference docs, public-API conventions, attribute/event catalogs, or stability commitments often duplicate surface that already exists. Check `src/` for behavior, `docs/` for human-facing reference, and `framework-skills/` for agent-facing reference. Skill files marked `audience: external` are the framework's public contract — treat them as authoritative when evaluating whether a documentation gap exists. Also verify the constants or types you'd reference aren't already exported from `@cyanheads/mcp-ts-core` or one of its subpaths.
42
42
 
43
43
  ## Writing Well-Structured Issues
44
44
 
@@ -213,7 +213,7 @@ gh issue create -R cyanheads/mcp-ts-core --template "Feature Request" --web
213
213
 
214
214
  ### CLI (non-interactive)
215
215
 
216
- Template below demonstrates the richer structure. Omit sections you don't need — simple requests don't require Flow / Design / Dependencies blocks.
216
+ The first three headings are the Feature Request form's own fields, in its order — `Use case` and `Proposed API` are required by the form, so a body without them does not satisfy it. Everything after `Alternatives considered` is supplemental; omit what you don't need — simple requests don't require Flow / Design / Dependencies blocks.
217
217
 
218
218
  ````bash
219
219
  gh issue create -R cyanheads/mcp-ts-core \
@@ -221,16 +221,16 @@ gh issue create -R cyanheads/mcp-ts-core \
221
221
  --label "enhancement" \
222
222
  --assignee "@me" \
223
223
  --body "$(cat <<'ISSUE'
224
- Concrete statement of what's currently missing or broken in the framework. Name the specific builder, utility, context method, or config field. Two or three sentences — the reader should know the gap before the end of the paragraph.
224
+ ### Use case
225
225
 
226
- Related: #N
227
-
228
- ## Proposal
226
+ One or two sentences: who hits this gap in the framework and why it matters. Name the specific builder, utility, context method, or config field. Kept short on purpose — a field that invites a paragraph gets padded with background and skipped by the next reader.
229
227
 
230
- What you want the framework to do, in one paragraph. Link external libraries on first mention: [lib name](https://github.com/owner/repo). Include a short justification — what this gives us that we don't have today.
228
+ Related: #N
231
229
 
232
230
  ### Proposed API
233
231
 
232
+ What you want the framework to do, then the API as a consumer would call it. Link external libraries on first mention: [lib name](https://github.com/owner/repo).
233
+
234
234
  ```ts
235
235
  import { withRetry } from '@cyanheads/mcp-ts-core/utils';
236
236
 
@@ -240,18 +240,9 @@ const result = await withRetry(() => fetchExternal(url), {
240
240
  });
241
241
  ```
242
242
 
243
- ### Flow (optional)
244
-
245
- Ordered steps — e.g. `trigger → resolve → fetch → degrade`. Useful when the change spans multiple phases or fallbacks.
246
-
247
- ### Design / Tradeoffs (optional)
248
-
249
- Philosophy: **one-line principle in bold.**
243
+ ### Alternatives considered
250
244
 
251
- | Option | Strengths | Weaknesses |
252
- |:---|:---|:---|
253
- | A | ... | ... |
254
- | B | ... | ... |
245
+ What you tried or evaluated instead, and why it didn't fit.
255
246
 
256
247
  ### Scope
257
248
 
@@ -264,13 +255,22 @@ Philosophy: **one-line principle in bold.**
264
255
  - What we're deliberately not doing
265
256
  - Adjacent work that belongs in a separate issue
266
257
 
267
- ### Dependencies (optional)
258
+ ### Flow (optional)
268
259
 
269
- - Depends on: owner/repo#N
260
+ Ordered steps — e.g. `trigger → resolve → fetch → degrade`. Useful when the change spans multiple phases or fallbacks.
270
261
 
271
- ### Alternatives considered
262
+ ### Design / Tradeoffs (optional)
272
263
 
273
- What you tried or evaluated instead, and why it didn't fit.
264
+ Philosophy: **one-line principle in bold.**
265
+
266
+ | Option | Strengths | Weaknesses |
267
+ |:---|:---|:---|
268
+ | A | ... | ... |
269
+ | B | ... | ... |
270
+
271
+ ### Dependencies (optional)
272
+
273
+ - Depends on: owner/repo#N
274
274
  ISSUE
275
275
  )"
276
276
  ````
@@ -293,8 +293,8 @@ gh issue list -R cyanheads/mcp-ts-core --author @me
293
293
  - [ ] Confirmed bug is in `@cyanheads/mcp-ts-core`, not server code
294
294
  - [ ] Running latest (or documented) framework version
295
295
  - [ ] Searched existing issues — no duplicate found
296
- - [ ] If documentation or contract enhancement: confirmed `src/`, `docs/`, `skills/`, and public exports don't already cover the surface
296
+ - [ ] If documentation or contract enhancement: confirmed `src/`, `docs/`, `framework-skills/`, and public exports don't already cover the surface
297
297
  - [ ] All secrets, credentials, and tokens redacted
298
298
  - [ ] Primary label assigned (`bug` / `enhancement` / `documentation`)
299
299
  - [ ] If bug: version, runtime, repro code, actual vs expected behavior included
300
- - [ ] If feature: Proposal and Scope sections present; Out of scope defined
300
+ - [ ] If feature: `Use case` and `Proposed API` present (the form's required fields), `Alternatives considered` third; Out of scope defined
@@ -4,7 +4,7 @@ description: >
4
4
  File a bug or feature request against this MCP server's own repo. Use for server-specific issues — tool logic, service integrations, config problems, or domain bugs that aren't caused by the framework.
5
5
  metadata:
6
6
  author: cyanheads
7
- version: "1.7"
7
+ version: "1.8"
8
8
  audience: external
9
9
  type: workflow
10
10
  ---
@@ -207,7 +207,7 @@ gh issue create --template "Feature Request" --web
207
207
 
208
208
  ### CLI (non-interactive)
209
209
 
210
- Template below demonstrates the richer structure. Omit sections you don't need — simple requests don't require Flow / Design / Dependencies blocks.
210
+ The first three headings are the Feature Request form's own fields, in its order — `Use case` and `Proposed behavior` are required by the form, so a body without them does not satisfy it. Everything after `Alternatives considered` is supplemental; omit what you don't need — simple requests don't require Flow / Design / Dependencies blocks.
211
211
 
212
212
  ````bash
213
213
  gh issue create \
@@ -215,34 +215,23 @@ gh issue create \
215
215
  --label "enhancement" \
216
216
  --assignee "@me" \
217
217
  --body "$(cat <<'ISSUE'
218
- Concrete statement of what's currently missing or broken. Name the specific tool, service, resource, or domain area. Two or three sentences — the reader should know the gap before the end of the paragraph.
218
+ ### Use case
219
219
 
220
- Related: #N
221
-
222
- ## Proposal
220
+ One or two sentences: who hits this gap and why it matters. Name the specific tool, service, resource, or domain area. Kept short on purpose — a field that invites a paragraph gets padded with background and skipped by the next reader.
223
221
 
224
- What you want the server to do, in one paragraph. Link external libraries or services on first mention: [lib name](https://github.com/owner/repo). Include a short justification — what this gives users that they don't have today.
222
+ Related: #N
225
223
 
226
224
  ### Proposed behavior
227
225
 
228
- Describe the new behavior or surface. For tool/resource changes, show example input/output or the new schema fields:
226
+ What you want the server to do, then the new behavior or surface. For tool/resource changes, show example input/output or the new schema fields. Link external libraries or services on first mention: [lib name](https://github.com/owner/repo).
229
227
 
230
228
  ```ts
231
229
  // Example: new input field or output shape
232
230
  ```
233
231
 
234
- ### Flow (optional)
235
-
236
- Ordered steps — e.g. `request → lookup → fallback → respond`. Useful when the change spans multiple phases or fallbacks.
237
-
238
- ### Design / Tradeoffs (optional)
239
-
240
- Philosophy: **one-line principle in bold.**
232
+ ### Alternatives considered
241
233
 
242
- | Option | Strengths | Weaknesses |
243
- |:---|:---|:---|
244
- | A | ... | ... |
245
- | B | ... | ... |
234
+ What you tried or evaluated instead, and why it didn't fit.
246
235
 
247
236
  ### Scope
248
237
 
@@ -255,14 +244,23 @@ Philosophy: **one-line principle in bold.**
255
244
  - What we're deliberately not doing
256
245
  - Adjacent work that belongs in a separate issue
257
246
 
247
+ ### Flow (optional)
248
+
249
+ Ordered steps — e.g. `request → lookup → fallback → respond`. Useful when the change spans multiple phases or fallbacks.
250
+
251
+ ### Design / Tradeoffs (optional)
252
+
253
+ Philosophy: **one-line principle in bold.**
254
+
255
+ | Option | Strengths | Weaknesses |
256
+ |:---|:---|:---|
257
+ | A | ... | ... |
258
+ | B | ... | ... |
259
+
258
260
  ### Dependencies (optional)
259
261
 
260
262
  - Depends on: cyanheads/mcp-ts-core#N (upstream framework change)
261
263
  - Depends on: owner/repo#N (other server work)
262
-
263
- ### Alternatives considered
264
-
265
- What you tried or evaluated instead, and why it didn't fit.
266
264
  ISSUE
267
265
  )"
268
266
  ````
@@ -306,4 +304,4 @@ gh issue close <number> --reason completed --comment "Fixed in <commit or PR>"
306
304
  - [ ] Title follows `type(scope): description` format
307
305
  - [ ] Primary label assigned (`bug` / `enhancement` / `documentation`)
308
306
  - [ ] If bug: version, runtime, repro steps, actual vs expected behavior included
309
- - [ ] If feature: Proposal and Scope sections present; Out of scope defined
307
+ - [ ] If feature: `Use case` and `Proposed behavior` present (the form's required fields), `Alternatives considered` third; Out of scope defined