@cyanheads/mcp-ts-core 0.5.0 → 0.5.2

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.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Agent Protocol
2
2
 
3
- **Package:** `@cyanheads/mcp-ts-core` · **Version:** 0.5.0
3
+ **Package:** `@cyanheads/mcp-ts-core` · **Version:** 0.5.2
4
4
  **npm:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) · **Docker:** [ghcr.io/cyanheads/mcp-ts-core](https://ghcr.io/cyanheads/mcp-ts-core)
5
5
 
6
6
  > **Developer note:** Never assume. Read related files and docs before making changes. Read full file content for context. Never edit a file before reading it.
@@ -199,7 +199,7 @@ export const myTool = tool('my_tool', {
199
199
 
200
200
  **Form-client safety:** Form-based MCP clients (MCP Inspector, web UIs) send optional object fields with empty-string inner values instead of `undefined`. Don't reject with `.min(1)` on optional fields — guard for meaningful values in the handler (`if (input.dateRange?.minDate && input.dateRange?.maxDate)`). Test with both omitted and empty-value payloads.
201
201
 
202
- **`format`**: Maps output to MCP `content[]` — the only field most LLM clients (Claude Code, VS Code Copilot, Cursor, Windsurf) forward to the model. `structuredContent` (from `output`) is for programmatic use and is not reliably shown to the LLM. **Make `format()` content-complete** — render all data the model needs to reason about the result, not just a count or title. Omit for JSON stringify fallback. Additional formatters: `markdown()` (builder), `diffFormatter` (async), `tableFormatter`, `treeFormatter` from `/utils`.
202
+ **`format`**: Maps output to MCP `content[]` — the only field most LLM clients (Claude Code, VS Code Copilot, Cursor, Windsurf) forward to the model. `structuredContent` (from `output`) is for programmatic use and is not reliably shown to the LLM. **Make `format()` content-complete** — render all data the model needs to reason about the result, not just a count or title. Enforced at lint time: every terminal field in `output` must appear in `format()`'s rendered text (via sentinel injection), or startup fails with a `format-parity` error. If a field shouldn't be shown to the model, remove it from the output schema. Omit `format` for JSON stringify fallback. Additional formatters: `markdown()` (builder), `diffFormatter` (async), `tableFormatter`, `treeFormatter` from `/utils`.
203
203
 
204
204
  **Task tools:** Add `task: true` for long-running async operations. Framework manages lifecycle: creates task → returns ID immediately → runs handler in background with `ctx.progress` → stores result/error → `ctx.signal` for cancellation. See `add-tool` skill for full example.
205
205
 
@@ -464,14 +464,12 @@ Detailed method signatures, options, and examples live in skill files. Read the
464
464
  | `add-export` | `skills/add-export/SKILL.md` | Add a new subpath export |
465
465
  | `design-mcp-server` | `skills/design-mcp-server/SKILL.md` | Design tool surface, resources, and service layer for a new server |
466
466
  | `setup` | `skills/setup/SKILL.md` | Initialize a new consumer server from the template |
467
- | `devcheck` | `skills/devcheck/SKILL.md` | Run lint, format, typecheck, security checks |
468
467
  | `polish-docs-meta` | `skills/polish-docs-meta/SKILL.md` | Finalize docs, README, metadata, and agent protocol for shipping |
469
468
  | `report-issue-framework` | `skills/report-issue-framework/SKILL.md` | File a bug or feature request against `@cyanheads/mcp-ts-core` via `gh` CLI |
470
469
  | `report-issue-local` | `skills/report-issue-local/SKILL.md` | File a bug or feature request against this server's own repo via `gh` CLI |
471
470
  | `release` | `skills/release/SKILL.md` | Version bump, changelog, publish workflow |
472
471
  | `maintenance` | `skills/maintenance/SKILL.md` | Dependency updates, housekeeping tasks |
473
472
  | `migrate-mcp-ts-template` | `skills/migrate-mcp-ts-template/SKILL.md` | Migrate legacy template fork to package dependency |
474
- | `walkthrough-init` | `skills/walkthrough-init/SKILL.md` | Trace and audit the agent onboarding instruction chain |
475
473
 
476
474
  ---
477
475
 
package/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  <div align="center">
7
7
 
8
- [![Version](https://img.shields.io/badge/Version-0.5.0-blue.svg?style=flat-square)](./CHANGELOG.md) [![MCP Spec](https://img.shields.io/badge/MCP%20Spec-2025--11--25-8A2BE2.svg?style=flat-square)](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/docs/specification/2025-11-25/changelog.mdx) [![MCP SDK](https://img.shields.io/badge/MCP%20SDK-^1.29.0-green.svg?style=flat-square)](https://modelcontextprotocol.io/) [![License](https://img.shields.io/badge/License-Apache%202.0-orange.svg?style=flat-square)](./LICENSE)
8
+ [![Version](https://img.shields.io/badge/Version-0.5.2-blue.svg?style=flat-square)](./CHANGELOG.md) [![MCP Spec](https://img.shields.io/badge/MCP%20Spec-2025--11--25-8A2BE2.svg?style=flat-square)](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/docs/specification/2025-11-25/changelog.mdx) [![MCP SDK](https://img.shields.io/badge/MCP%20SDK-^1.29.0-green.svg?style=flat-square)](https://modelcontextprotocol.io/) [![License](https://img.shields.io/badge/License-Apache%202.0-orange.svg?style=flat-square)](./LICENSE)
9
9
 
10
10
  [![TypeScript](https://img.shields.io/badge/TypeScript-^6.0.3-3178C6.svg?style=flat-square)](https://www.typescriptlang.org/) [![Bun](https://img.shields.io/badge/Bun-v1.3.2-blueviolet.svg?style=flat-square)](https://bun.sh/)
11
11
 
@@ -39,7 +39,7 @@ That's a complete MCP server. Every tool call is automatically logged with durat
39
39
  - **Unified Context** — handlers receive a single `ctx` object with `ctx.log` (request-scoped logging), `ctx.state` (tenant-scoped storage), `ctx.elicit` (user prompting), `ctx.sample` (LLM completion), and `ctx.signal` (cancellation).
40
40
  - **Inline auth** — `auth: ['scope']` on definitions. No wrapper functions. Framework checks scopes before calling your handler.
41
41
  - **Task tools** — `task: true` flag for long-running operations. Framework manages the full lifecycle (create, poll, progress, complete/fail/cancel).
42
- - **Definition linter** — `validateDefinitions()` checks tools, resources, and prompts against MCP spec at startup. Name format, schema structure, `.describe()` presence, JSON Schema serializability, auth scope validity, annotation coherence, and URI template–params alignment. Also available as a standalone CLI (`lint:mcp`) and devcheck step.
42
+ - **Definition linter** — `validateDefinitions()` checks tools, resources, and prompts against MCP spec at startup. Name format, schema structure, `.describe()` presence, JSON Schema serializability, auth scope validity, annotation coherence, URI template–params alignment, and **format-parity** (every field in a tool's `output` must be rendered by `format()` — verified via sentinel injection, since most LLM clients only forward `content[]` to the model). Also available as a standalone CLI (`lint:mcp`) and devcheck step.
43
43
  - **Structured error handling** — Handlers throw freely; the framework catches, classifies, and formats. Error factories (`notFound()`, `validationError()`, `serviceUnavailable()`, etc.) for precise control when the code matters. Auto-classification from plain `Error` messages when it doesn't.
44
44
  - **Multi-backend storage** — `in-memory`, `filesystem`, `Supabase`, `Cloudflare D1/KV/R2`. Swap providers via env var without changing tool logic. Cursor pagination, batch ops, TTL, tenant isolation.
45
45
  - **Pluggable auth** — `none`, `jwt`, or `oauth` modes. JWT with local secret or OAuth with JWKS verification.
@@ -0,0 +1,34 @@
1
+ /**
2
+ * @fileoverview Format-parity lint rule. Verifies that every field in a tool's
3
+ * `output` schema is actually rendered by its `format()` function.
4
+ *
5
+ * Most LLM clients (Claude Code, VS Code Copilot, Cursor, Windsurf) only forward
6
+ * `content[]` to the model — not `structuredContent`. A field that exists in
7
+ * `output` but is never rendered is invisible to the model, even though it
8
+ * contributes to the tool's apparent surface area.
9
+ *
10
+ * Approach: sentinel injection.
11
+ * 1. Walk the output schema, build a synthetic value where every leaf is a
12
+ * uniquely identifiable sentinel (distinctive string, large number, or
13
+ * boolean/enum/literal with key-name fallback).
14
+ * 2. Invoke `def.format(synthetic)` once and concatenate `content[].text`.
15
+ * 3. For each leaf path, verify either the sentinel value or the field's key
16
+ * name appears in the rendered text.
17
+ * 4. Emit one error per missing path.
18
+ *
19
+ * Deterministic, dependency-free. Runs inside `validateDefinitions()` alongside
20
+ * every other lint rule — picked up automatically by `bun run lint:mcp`,
21
+ * `bun run devcheck`, and `createApp()` startup validation.
22
+ *
23
+ * @module src/linter/rules/format-parity-rules
24
+ */
25
+ import type { LintDiagnostic } from '../types.js';
26
+ /**
27
+ * Verifies that `def.format()` renders every field present in `def.output`.
28
+ *
29
+ * Preconditions (caller must check): `def.output` is a valid ZodObject and
30
+ * `def.format` is a function. Skipped entirely otherwise — the default
31
+ * JSON-stringify fallback renders everything by construction.
32
+ */
33
+ export declare function lintFormatParity(def: unknown, displayName: string): LintDiagnostic[];
34
+ //# sourceMappingURL=format-parity-rules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format-parity-rules.d.ts","sourceRoot":"","sources":["../../../src/linter/rules/format-parity-rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAwQlD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,GAAG,cAAc,EAAE,CAqEpF"}
@@ -0,0 +1,335 @@
1
+ /**
2
+ * @fileoverview Format-parity lint rule. Verifies that every field in a tool's
3
+ * `output` schema is actually rendered by its `format()` function.
4
+ *
5
+ * Most LLM clients (Claude Code, VS Code Copilot, Cursor, Windsurf) only forward
6
+ * `content[]` to the model — not `structuredContent`. A field that exists in
7
+ * `output` but is never rendered is invisible to the model, even though it
8
+ * contributes to the tool's apparent surface area.
9
+ *
10
+ * Approach: sentinel injection.
11
+ * 1. Walk the output schema, build a synthetic value where every leaf is a
12
+ * uniquely identifiable sentinel (distinctive string, large number, or
13
+ * boolean/enum/literal with key-name fallback).
14
+ * 2. Invoke `def.format(synthetic)` once and concatenate `content[].text`.
15
+ * 3. For each leaf path, verify either the sentinel value or the field's key
16
+ * name appears in the rendered text.
17
+ * 4. Emit one error per missing path.
18
+ *
19
+ * Deterministic, dependency-free. Runs inside `validateDefinitions()` alongside
20
+ * every other lint rule — picked up automatically by `bun run lint:mcp`,
21
+ * `bun run devcheck`, and `createApp()` startup validation.
22
+ *
23
+ * @module src/linter/rules/format-parity-rules
24
+ */
25
+ /** Zod 4 stores the type discriminator at `_zod.def.type`. Falls back to `_def.type`. */
26
+ function zodTypeOf(schema) {
27
+ if (!schema || typeof schema !== 'object')
28
+ return '';
29
+ const s = schema;
30
+ return s._zod?.def?.type ?? s._def?.type ?? '';
31
+ }
32
+ /**
33
+ * Strips Optional/Nullable/Default wrappers so we can always populate the field.
34
+ * Parity cares about "does format render this when present", so wrappers are transparent.
35
+ */
36
+ function unwrapSchema(schema) {
37
+ let current = schema;
38
+ for (let i = 0; i < 10; i++) {
39
+ const type = zodTypeOf(current);
40
+ if (type !== 'optional' && type !== 'nullable' && type !== 'default')
41
+ return current;
42
+ const c = current;
43
+ const inner = c._zod?.def?.innerType ?? c._def?.innerType;
44
+ if (!inner)
45
+ return current;
46
+ current = inner;
47
+ }
48
+ return current;
49
+ }
50
+ function stringSentinel(path) {
51
+ return `__MCP_PARITY_${path.replace(/[.[\]]/g, '_')}__`;
52
+ }
53
+ /** Builds a synthetic value and collects every leaf path simultaneously. */
54
+ function walk(schema, path, keyName, state) {
55
+ if (state.depth > 8)
56
+ return null;
57
+ state.depth++;
58
+ try {
59
+ const node = unwrapSchema(schema);
60
+ const type = zodTypeOf(node);
61
+ const n = node;
62
+ switch (type) {
63
+ case 'string': {
64
+ const sentinel = stringSentinel(path || keyName || 'root');
65
+ state.leaves.push({ path, keyName, sentinel, matchStrategy: 'strict' });
66
+ return sentinel;
67
+ }
68
+ case 'number':
69
+ case 'int':
70
+ case 'bigint': {
71
+ const sentinel = 900_000_001 + state.numberIndex++;
72
+ state.leaves.push({ path, keyName, sentinel, matchStrategy: 'strict' });
73
+ return sentinel;
74
+ }
75
+ case 'boolean': {
76
+ state.leaves.push({ path, keyName, sentinel: true, matchStrategy: 'permissive' });
77
+ return true;
78
+ }
79
+ case 'enum': {
80
+ // Zod 4 exposes options as array on the schema itself.
81
+ const options = n.options ?? getDefOptions(n);
82
+ const value = Array.isArray(options) && options.length > 0 ? options[0] : '';
83
+ state.leaves.push({ path, keyName, sentinel: value, matchStrategy: 'permissive' });
84
+ return value;
85
+ }
86
+ case 'literal': {
87
+ const value = n.value ?? getDefValue(n);
88
+ state.leaves.push({ path, keyName, sentinel: value, matchStrategy: 'permissive' });
89
+ return value;
90
+ }
91
+ case 'array': {
92
+ const element = n.element ?? getDefElement(n);
93
+ return [walk(element, `${path}[]`, keyName, state)];
94
+ }
95
+ case 'object': {
96
+ const shape = n.shape ?? {};
97
+ const out = {};
98
+ for (const [key, childSchema] of Object.entries(shape)) {
99
+ const childPath = path ? `${path}.${key}` : key;
100
+ out[key] = walk(childSchema, childPath, key, state);
101
+ }
102
+ return out;
103
+ }
104
+ case 'union':
105
+ case 'discriminated_union': {
106
+ const options = getDefOptions(n);
107
+ if (Array.isArray(options) && options.length > 0) {
108
+ return walk(options[0], path, keyName, state);
109
+ }
110
+ return null;
111
+ }
112
+ case 'record': {
113
+ const valueSchema = getDefValueType(n);
114
+ if (valueSchema) {
115
+ return { parity_key: walk(valueSchema, `${path}.<key>`, keyName, state) };
116
+ }
117
+ return {};
118
+ }
119
+ case 'tuple': {
120
+ const items = getDefItems(n);
121
+ if (Array.isArray(items)) {
122
+ return items.map((item, i) => walk(item, `${path}[${i}]`, keyName, state));
123
+ }
124
+ return [];
125
+ }
126
+ default: {
127
+ // Unknown/unsupported type — emit leaf with permissive fallback so the
128
+ // rule still asks "did format render this field's key somehow?"
129
+ state.leaves.push({ path, keyName, sentinel: null, matchStrategy: 'permissive' });
130
+ return null;
131
+ }
132
+ }
133
+ }
134
+ finally {
135
+ state.depth--;
136
+ }
137
+ }
138
+ function getDefOptions(node) {
139
+ const zod = node._zod;
140
+ const legacy = node._def;
141
+ if (Array.isArray(zod?.def?.options))
142
+ return zod.def.options;
143
+ if (Array.isArray(legacy?.options))
144
+ return legacy.options;
145
+ if (Array.isArray(legacy?.values))
146
+ return legacy.values;
147
+ // Zod 4 enum stores values in `entries` as { label: value }
148
+ const entries = zod?.def?.entries ?? legacy?.entries;
149
+ if (entries && typeof entries === 'object')
150
+ return Object.values(entries);
151
+ return;
152
+ }
153
+ function getDefValue(node) {
154
+ const zod = node._zod;
155
+ const legacy = node._def;
156
+ if (zod?.def?.value !== undefined)
157
+ return zod.def.value;
158
+ if (legacy?.value !== undefined)
159
+ return legacy.value;
160
+ if (Array.isArray(zod?.def?.values) && zod.def.values.length > 0)
161
+ return zod.def.values[0];
162
+ if (Array.isArray(legacy?.values) && legacy.values.length > 0)
163
+ return legacy.values[0];
164
+ return '';
165
+ }
166
+ function getDefElement(node) {
167
+ const zod = node._zod;
168
+ const legacy = node._def;
169
+ return zod?.def?.element ?? legacy?.element ?? legacy?.type;
170
+ }
171
+ function getDefValueType(node) {
172
+ const zod = node._zod;
173
+ const legacy = node._def;
174
+ return node.valueType ?? zod?.def?.valueType ?? legacy?.valueType;
175
+ }
176
+ function getDefItems(node) {
177
+ const zod = node._zod;
178
+ const legacy = node._def;
179
+ return zod?.def?.items ?? legacy?.items;
180
+ }
181
+ // ---------------------------------------------------------------------------
182
+ // Rendering + matching
183
+ // ---------------------------------------------------------------------------
184
+ /**
185
+ * Collects every string/number/boolean value reachable inside `content[]` so
186
+ * the sentinel check works for any ContentBlock variant — text, image, audio,
187
+ * resource — not just text. Image/audio blocks render sentinels inside
188
+ * `data`/`mimeType`; resource blocks inside `uri`/`text`/`blob`.
189
+ */
190
+ function extractText(content) {
191
+ if (!Array.isArray(content))
192
+ return '';
193
+ const parts = [];
194
+ for (const block of content)
195
+ collectPrimitives(block, parts);
196
+ return parts.join('\n');
197
+ }
198
+ function collectPrimitives(value, out) {
199
+ if (value === null || value === undefined)
200
+ return;
201
+ const t = typeof value;
202
+ if (t === 'string' || t === 'number' || t === 'boolean') {
203
+ out.push(String(value));
204
+ return;
205
+ }
206
+ if (Array.isArray(value)) {
207
+ for (const v of value)
208
+ collectPrimitives(v, out);
209
+ return;
210
+ }
211
+ if (t === 'object') {
212
+ for (const v of Object.values(value))
213
+ collectPrimitives(v, out);
214
+ }
215
+ }
216
+ function sentinelAppears(sentinel, text) {
217
+ if (sentinel === null || sentinel === undefined)
218
+ return false;
219
+ const asString = typeof sentinel === 'string' ? sentinel : String(sentinel);
220
+ return asString.length > 0 && text.includes(asString);
221
+ }
222
+ function escapeRegex(str) {
223
+ return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
224
+ }
225
+ /** Case-insensitive whole-word match. Returns false for keys shorter than 3. */
226
+ function wholeWordMatch(word, text) {
227
+ if (word.length < 3)
228
+ return false;
229
+ return new RegExp(`\\b${escapeRegex(word)}\\b`, 'i').test(text);
230
+ }
231
+ /** Splits camelCase/snake_case into lowercase segments. */
232
+ function splitKey(key) {
233
+ return key
234
+ .replace(/([a-z])([A-Z])/g, '$1_$2')
235
+ .split(/[_-]/)
236
+ .map((s) => s.toLowerCase())
237
+ .filter(Boolean);
238
+ }
239
+ function keyNameAppears(keyName, text) {
240
+ if (!keyName)
241
+ return false;
242
+ if (wholeWordMatch(keyName, text))
243
+ return true;
244
+ for (const segment of splitKey(keyName)) {
245
+ if (wholeWordMatch(segment, text))
246
+ return true;
247
+ }
248
+ return false;
249
+ }
250
+ function leafIsRendered(leaf, text) {
251
+ if (sentinelAppears(leaf.sentinel, text))
252
+ return true;
253
+ if (leaf.matchStrategy === 'permissive') {
254
+ return keyNameAppears(leaf.keyName, text);
255
+ }
256
+ return false;
257
+ }
258
+ // ---------------------------------------------------------------------------
259
+ // Public rule
260
+ // ---------------------------------------------------------------------------
261
+ /**
262
+ * Verifies that `def.format()` renders every field present in `def.output`.
263
+ *
264
+ * Preconditions (caller must check): `def.output` is a valid ZodObject and
265
+ * `def.format` is a function. Skipped entirely otherwise — the default
266
+ * JSON-stringify fallback renders everything by construction.
267
+ */
268
+ export function lintFormatParity(def, displayName) {
269
+ const d = def;
270
+ const output = d.output;
271
+ const format = d.format;
272
+ if (zodTypeOf(output) !== 'object')
273
+ return [];
274
+ if (typeof format !== 'function')
275
+ return [];
276
+ // Build synthetic sample.
277
+ const state = { leaves: [], numberIndex: 0, depth: 0 };
278
+ let synthetic;
279
+ try {
280
+ synthetic = walk(output, '', '', state);
281
+ }
282
+ catch (err) {
283
+ return [
284
+ {
285
+ rule: 'format-parity-walk-failed',
286
+ severity: 'warning',
287
+ message: `Tool '${displayName}' output schema could not be walked to build a synthetic ` +
288
+ `sample (${err instanceof Error ? err.message : String(err)}). ` +
289
+ 'Format parity could not be verified.',
290
+ definitionType: 'tool',
291
+ definitionName: displayName,
292
+ },
293
+ ];
294
+ }
295
+ if (state.leaves.length === 0)
296
+ return [];
297
+ // Run format().
298
+ let rendered;
299
+ try {
300
+ const result = format(synthetic);
301
+ rendered = extractText(result);
302
+ }
303
+ catch (err) {
304
+ return [
305
+ {
306
+ rule: 'format-parity-threw',
307
+ severity: 'warning',
308
+ message: `Tool '${displayName}' format() threw on a synthetic sample ` +
309
+ `(${err instanceof Error ? err.message : String(err)}). ` +
310
+ 'format() should be total — render any valid value of the output schema.',
311
+ definitionType: 'tool',
312
+ definitionName: displayName,
313
+ },
314
+ ];
315
+ }
316
+ // Verify each leaf.
317
+ const diagnostics = [];
318
+ for (const leaf of state.leaves) {
319
+ if (!leafIsRendered(leaf, rendered)) {
320
+ const displayPath = leaf.path || leaf.keyName || '<root>';
321
+ diagnostics.push({
322
+ rule: 'format-parity',
323
+ severity: 'error',
324
+ message: `Tool '${displayName}' format() does not render output field '${displayPath}'. ` +
325
+ 'Every field in the output schema must appear in format() — most LLM clients only ' +
326
+ 'forward content[] to the model, not structuredContent. Either render it in format() ' +
327
+ 'or remove it from the output schema.',
328
+ definitionType: 'tool',
329
+ definitionName: displayName,
330
+ });
331
+ }
332
+ }
333
+ return diagnostics;
334
+ }
335
+ //# sourceMappingURL=format-parity-rules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format-parity-rules.js","sourceRoot":"","sources":["../../../src/linter/rules/format-parity-rules.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"tool-rules.d.ts","sourceRoot":"","sources":["../../../src/linter/rules/tool-rules.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAQlD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,cAAc,EAAE,CAyEjE;AAED,+EAA+E;AAC/E,wBAAgB,cAAc,CAC5B,IAAI,EAAE,OAAO,EACb,cAAc,EAAE,cAAc,CAAC,gBAAgB,CAAC,EAChD,cAAc,EAAE,MAAM,GACrB,cAAc,EAAE,CA8BlB;AAgDD;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,OAAO,EAAE,EAChB,SAAS,EAAE,OAAO,EAAE,GACnB,cAAc,EAAE,CA6ClB"}
1
+ {"version":3,"file":"tool-rules.d.ts","sourceRoot":"","sources":["../../../src/linter/rules/tool-rules.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AASlD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,cAAc,EAAE,CA6EjE;AAED,+EAA+E;AAC/E,wBAAgB,cAAc,CAC5B,IAAI,EAAE,OAAO,EACb,cAAc,EAAE,cAAc,CAAC,gBAAgB,CAAC,EAChD,cAAc,EAAE,MAAM,GACrB,cAAc,EAAE,CA8BlB;AAgDD;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,OAAO,EAAE,EAChB,SAAS,EAAE,OAAO,EAAE,GACnB,cAAc,EAAE,CA6ClB"}
@@ -3,6 +3,7 @@
3
3
  * Validates tool definitions against MCP spec and framework conventions.
4
4
  * @module src/linter/rules/tool-rules
5
5
  */
6
+ import { lintFormatParity } from './format-parity-rules.js';
6
7
  import { checkNameRequired, checkToolNameFormat } from './name-rules.js';
7
8
  import { checkFieldDescriptions, checkIsZodObject, checkSchemaSerializable, } from './schema-rules.js';
8
9
  /**
@@ -64,6 +65,10 @@ export function lintToolDefinition(def) {
64
65
  const outputSerial = checkSchemaSerializable(d?.output, 'output', 'tool', displayName);
65
66
  if (outputSerial)
66
67
  diagnostics.push(outputSerial);
68
+ // Format parity: skip when output isn't serializable (synthetic sample may misbehave).
69
+ if (!outputSerial && typeof d?.format === 'function') {
70
+ diagnostics.push(...lintFormatParity(d, displayName));
71
+ }
67
72
  }
68
73
  // Auth scopes validation
69
74
  if (d?.auth !== undefined) {
@@ -1 +1 @@
1
- {"version":3,"file":"tool-rules.js","sourceRoot":"","sources":["../../../src/linter/rules/tool-rules.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tool-rules.js","sourceRoot":"","sources":["../../../src/linter/rules/tool-rules.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cyanheads/mcp-ts-core",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "mcpName": "io.github.cyanheads/mcp-ts-core",
5
5
  "description": "Agent-native TypeScript framework for building MCP servers. Build tools, not infrastructure. Declarative definitions with auth, multi-backend storage, OpenTelemetry, and first-class support for Node.js and Cloudflare Workers.",
6
6
  "main": "dist/core/index.js",
@@ -4,7 +4,7 @@ description: >
4
4
  Scaffold a new MCP tool definition. Use when the user asks to add a tool, create a new tool, or implement a new capability for the server.
5
5
  metadata:
6
6
  author: cyanheads
7
- version: "1.4"
7
+ version: "1.5"
8
8
  audience: external
9
9
  type: reference
10
10
  ---
@@ -60,6 +60,7 @@ export const {{TOOL_EXPORT}} = tool('{{tool_name}}', {
60
60
  // format() populates MCP content[] — the only field most LLM clients forward
61
61
  // to the model. structuredContent (from output) is for programmatic use only.
62
62
  // Render ALL data the LLM needs to reason about the result.
63
+ // Enforced at lint time: every field in `output` must appear in the rendered text.
63
64
  format: (result) => {
64
65
  const lines: string[] = [];
65
66
  // Render each item with all relevant fields — not just a count or title.
@@ -312,7 +313,7 @@ Large payloads burn the agent's context window. Default to curated summaries; of
312
313
  - [ ] JSDoc `@fileoverview` and `@module` header present
313
314
  - [ ] Optional nested objects guarded for empty inner values from form-based clients (check `?.field` truthiness, not just object presence)
314
315
  - [ ] `handler(input, ctx)` is pure — throws on failure, no try/catch
315
- - [ ] `format()` renders all data the LLM needs (not just a count or title) `content[]` is the only field most clients forward to the model
316
+ - [ ] `format()` renders every field in the output schema enforced at lint time via sentinel injection, startup fails with `format-parity` errors otherwise. `content[]` is the only field most clients forward to the model; if a field shouldn't be shown, remove it from the output schema rather than skipping it in `format()`
316
317
  - [ ] If wrapping external API: output schema and `format()` preserve uncertainty from sparse upstream payloads instead of inventing concrete values
317
318
  - [ ] `auth` scopes declared if the tool needs authorization
318
319
  - [ ] `task: true` added if the tool is long-running
@@ -4,7 +4,7 @@ description: >
4
4
  Reference for core and server configuration in `@cyanheads/mcp-ts-core`. Covers env var tables with defaults, priority order, server-specific Zod schema pattern, and Workers lazy-parsing requirement.
5
5
  metadata:
6
6
  author: cyanheads
7
- version: "1.1"
7
+ version: "1.2"
8
8
  audience: external
9
9
  type: reference
10
10
  ---
@@ -4,7 +4,7 @@ description: >
4
4
  Exercise tools, resources, and prompts with real-world inputs to verify behavior end-to-end. Use after adding or modifying definitions, or when the user asks to test, try out, or verify their MCP surface. Calls each definition with realistic and adversarial inputs and produces a report of issues, pain points, and recommendations.
5
5
  metadata:
6
6
  author: cyanheads
7
- version: "1.1"
7
+ version: "1.2"
8
8
  audience: external
9
9
  type: debug
10
10
  ---
@@ -36,7 +36,7 @@ For every tool, resource, and prompt, run through these categories:
36
36
  | Category | What to test |
37
37
  |:---------|:-------------|
38
38
  | **Happy path** | Realistic input that should succeed. Verify output shape matches the output schema. Verify format function produces sensible content blocks. |
39
- | **`structuredContent` parity** | Compare the raw handler return, the data captured in `structuredContent`, and what `format()` renders into `content[]`. Flag fields or records that exist in the handler result or `structuredContent` but are absent from `content[]` unless the omission is explicit and acceptable for the tool's purpose. Most LLM clients only see `content[]`, so silent formatter drops are real bugs. |
39
+ | **`structuredContent` parity** | The `format-parity` lint rule already asserts every terminal field in the output schema appears in `format()`'s rendered text (via sentinel injection at startup). Field testing layers real-data checks on top: are values rendered accurately (not just their labels)? Do conditional-render branches in `format()` still render every field when specific values are present? Does the content look right to a human reading the LLM's view? |
40
40
  | **Variations** | Different valid input combinations — optional fields omitted, optional fields included, different enum values, min/max boundaries. |
41
41
  | **Field selection / projection** | For tools with `fields`, `include`, `expand`, `view`, or similar parameters, call the tool with non-default selections. Verify the handler returns the requested fields and `format()` renders each requested field rather than a hardcoded summary subset. |
42
42
  | **Edge cases** | Empty strings, zero values, very long inputs, special characters, Unicode. |
@@ -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: "1.3"
7
+ version: "1.4"
8
8
  audience: external
9
9
  type: workflow
10
10
  ---
@@ -48,7 +48,7 @@ Capture: tool count, resource count, prompt count, service count, required env v
48
48
 
49
49
  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.
50
50
 
51
- The header tagline (`<p><b>...</b></p>`) must match the `package.json` `description`.
51
+ 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 `•`.
52
52
 
53
53
  ### 3. Agent Protocol (CLAUDE.md / AGENTS.md)
54
54
 
@@ -7,42 +7,47 @@ Structure and content guide for creating or updating a README for an MCP server
7
7
  Use this section order. Omit sections that don't apply (e.g., skip Docker/Workers if the server doesn't deploy there).
8
8
 
9
9
  ```text
10
- # {Server Name} ← centered HTML block
11
- Badges row ← npm, Docker, Version, MCP Spec, SDK, License, Status, TS, Bun, Coverage
10
+ # {Server Name} ← centered HTML block
11
+ [Public hosted callout if present] ← centered HTML block, directly under badges
12
+ Badges row ← npm, Docker, Version, Framework, MCP SDK, License, TS, Bun, Coverage
12
13
  ---
13
- ## Tools ← summary table, then per-tool subsections
14
- ## Resources (if any) summary table
15
- ## Prompts (if any) ← summary table
16
- ## Features framework + domain-specific bullets
17
- ## Getting Started hosted instance (if any), MCP client config, prerequisites, install
18
- ## Configuration env var table
19
- ## Running the Server dev, production, Workers/Docker
20
- ## Project Structure directory/purpose table
21
- ## Development Guide link to CLAUDE.md, key rules
22
- ## Contributing brief
23
- ## License ← one line
14
+ ## Tools grouping sentence → summary table per-tool subsections
15
+ ## Resources and prompts (if any) single combined table (Type / Name / Description)
16
+ ## Features ← framework bullets + domain-specific bullets
17
+ ## Getting started hosted (if any), bunx/npx/docker configs, HTTP one-liner, prerequisites, install
18
+ ## Configuration env var table + `.env.example` pointer
19
+ ## Running the server dev, production, Workers/Docker
20
+ ## Project structure directory/purpose table
21
+ ## Development guide link to CLAUDE.md, key rules
22
+ ## Contributing brief
23
+ ## License one line
24
24
  ```
25
25
 
26
26
  ## Section Guide
27
27
 
28
28
  ### Title Block
29
29
 
30
- Centered HTML. The `<h1>` is the server name — use the scoped package name if published under a scope (e.g., `@cyanheads/my-mcp-server`). The `<p>` is a bold one-liner: what the server wraps, key capabilities, transport/deployment options. Follow with a count line summarizing the MCP surface (tools, resources, prompts) separated by ` · `, then a badge row.
30
+ Centered HTML. The `<h1>` is the server name — use the scoped package name if published under a scope (e.g., `@cyanheads/my-mcp-server`). The `<p>` is a bold one-liner: what the server wraps, key capabilities, transport/deployment options. **Nest the surface count as a `<div>` inside the same `<p>`**, separated by `•` (U+2022 bullet) not as a second `<p>`. This matches the shipping convention across `@cyanheads/*` servers.
31
31
 
32
32
  ```html
33
33
  <div align="center">
34
34
  <h1>@cyanheads/my-mcp-server</h1>
35
- <p><b>MCP server for the Acme API. Search projects, manage tasks, track teams. STDIO & Streamable HTTP</b></p>
36
- <p><b>7 Tools · 2 Resources · 1 Prompt</b></p>
35
+ <p><b>MCP server for the Acme API search projects, manage tasks, track teams. STDIO or Streamable HTTP.</b>
36
+ <div>7 Tools 2 Resources 1 Prompt</div>
37
+ </p>
37
38
  </div>
38
39
 
39
40
  <div align="center">
40
41
 
41
- [![npm](https://img.shields.io/npm/v/my-mcp-server?style=flat-square&logo=npm&logoColor=white)](https://www.npmjs.com/package/my-mcp-server) [![Version](https://img.shields.io/badge/Version-1.0.0-blue.svg?style=flat-square)](./CHANGELOG.md) [![Framework](https://img.shields.io/badge/Built%20on-@cyanheads/mcp--ts--core-259?style=flat-square)](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) [![MCP SDK](https://img.shields.io/badge/MCP%20SDK-^1.27.1-green.svg?style=flat-square)](https://modelcontextprotocol.io/) [![License](https://img.shields.io/badge/License-Apache%202.0-orange.svg?style=flat-square)](./LICENSE) [![TypeScript](https://img.shields.io/badge/TypeScript-^5.9.3-3178C6.svg?style=flat-square)](https://www.typescriptlang.org/)
42
+ [![npm](https://img.shields.io/npm/v/@cyanheads/my-mcp-server?style=flat-square&logo=npm&logoColor=white)](https://www.npmjs.com/package/@cyanheads/my-mcp-server) [![Version](https://img.shields.io/badge/Version-1.0.0-blue.svg?style=flat-square)](./CHANGELOG.md) [![Framework](https://img.shields.io/badge/Built%20on-@cyanheads/mcp--ts--core-259?style=flat-square)](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) [![MCP SDK](https://img.shields.io/badge/MCP%20SDK-^1.29.0-green.svg?style=flat-square)](https://modelcontextprotocol.io/)
43
+
44
+ [![License](https://img.shields.io/badge/License-Apache%202.0-orange.svg?style=flat-square)](./LICENSE) [![TypeScript](https://img.shields.io/badge/TypeScript-^6.0.3-3178C6.svg?style=flat-square)](https://www.typescriptlang.org/) [![Bun](https://img.shields.io/badge/Bun-v1.3.2-blueviolet.svg?style=flat-square)](https://bun.sh/)
42
45
 
43
46
  </div>
44
47
  ```
45
48
 
49
+ The header tagline must match the `package.json` `description`.
50
+
46
51
  **Badge selection:** All badges use `style=flat-square`. Include what applies — don't add badges for things the server doesn't have:
47
52
 
48
53
  | Badge | When to include |
@@ -51,19 +56,41 @@ Centered HTML. The `<h1>` is the server name — use the scoped package name if
51
56
  | Docker | Published to ghcr.io or Docker Hub |
52
57
  | Version | Always — link to CHANGELOG.md |
53
58
  | Framework | Always — links to `@cyanheads/mcp-ts-core` on npm |
54
- | MCP Spec | Always — link to the spec version implemented |
55
59
  | MCP SDK | Always — show the `@modelcontextprotocol/sdk` version |
56
60
  | License | Always |
57
- | Status | Optional — Stable, Beta, etc. |
58
61
  | TypeScript | Always |
59
- | Bun | If using Bun |
62
+ | Bun | If using Bun (standard for this framework) |
63
+ | MCP Spec | Optional — rarely included; the SDK badge usually suffices |
64
+ | Status | Optional — Stable, Beta, etc. |
60
65
  | Code Coverage | If coverage is tracked |
61
66
 
62
67
  Add a `---` horizontal rule after the badge block.
63
68
 
69
+ ### Public Hosted Callout (if present)
70
+
71
+ If a public hosted instance is available, **promote it to a top-level callout** immediately below the badge block — don't bury it inside Getting Started. This is the highest-value piece of information for a visitor who wants to try the server with zero install.
72
+
73
+ ```html
74
+ <div align="center">
75
+
76
+ **Public Hosted Server:** [https://my-server.example.com/mcp](https://my-server.example.com/mcp)
77
+
78
+ </div>
79
+ ```
80
+
81
+ 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.
82
+
64
83
  ### Tools
65
84
 
66
- This is the most important section — it tells humans and LLMs exactly what the server exposes. Two layers: summary table, then per-tool subsections for tools with non-trivial behavior.
85
+ 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.
86
+
87
+ **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:
88
+
89
+ - "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."
90
+ - "Nine tools for working with PubMed and NCBI data:"
91
+ - "Five tools covering project lifecycle — discovery, task CRUD, and team analytics."
92
+
93
+ If the tools aren't meaningfully grouped, a single sentence count ("Seven tools for working with Acme data:") is acceptable.
67
94
 
68
95
  **Summary table:**
69
96
 
@@ -79,8 +106,6 @@ Seven tools for working with Acme data:
79
106
  | `get_task` | Fetch one or more tasks by ID, with full or summary data. |
80
107
  ```
81
108
 
82
- Lead with a one-line count: "Seven tools for working with X data:" (or "Three tools", etc.).
83
-
84
109
  **Per-tool subsections:**
85
110
 
86
111
  Below the table, add a `### tool_name` subsection for each tool that has meaningful detail beyond its one-line description. Include:
@@ -110,34 +135,35 @@ Fetch one or more tasks by ID, with full data or concise summaries.
110
135
  - Batch fetch up to 5 tasks at once
111
136
  - Full data includes subtasks, comments, attachments, and history
112
137
  - Partial success reporting when some tasks in a batch fail
113
-
114
- [View detailed examples](./examples/get_task.md)
115
138
  ```
116
139
 
117
140
  Skip the per-tool subsection for simple tools where the table description says everything (e.g., a `get_field_values` lookup tool).
118
141
 
119
- ### Resources (if any)
142
+ ### Resources and Prompts (combined)
143
+
144
+ **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.
120
145
 
121
146
  ```markdown
122
- ## Resources
147
+ ## Resources and prompts
123
148
 
124
- | URI Pattern | Description |
125
- |:------------|:------------|
126
- | `acme://projects/{projectId}` | Project details by ID |
127
- | `acme://tasks/{taskId}` | Task details by ID |
149
+ | Type | Name | Description |
150
+ |:---|:---|:---|
151
+ | Resource | `acme://projects/{projectId}` | Project details by ID |
152
+ | Resource | `acme://tasks/{taskId}` | Task details by ID |
153
+ | Prompt | `project_summary` | Summarize a project's status and open tasks |
128
154
  ```
129
155
 
130
- ### Prompts (if any)
156
+ Use singular ("Resource and prompt") if there's only one of each.
131
157
 
132
- ```markdown
133
- ## Prompts
158
+ **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:
134
159
 
135
- | Prompt | Description |
136
- |:-------|:------------|
137
- | `project_summary` | Summarize a project's status and open tasks |
160
+ ```markdown
161
+ 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.
138
162
  ```
139
163
 
140
- Derive all tool/resource/prompt tables directly from the actual definitions. Use the real names and descriptions from the Zod schemas.
164
+ 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).`
165
+
166
+ Derive all tool/resource/prompt rows directly from the actual definitions. Use the real names and descriptions from the Zod schemas.
141
167
 
142
168
  ### Features
143
169
 
@@ -146,90 +172,166 @@ Two subsection groups: framework capabilities, then domain-specific capabilities
146
172
  ```markdown
147
173
  ## Features
148
174
 
149
- Built on [`@cyanheads/mcp-ts-core`](https://github.com/cyanheads/mcp-ts-core):
175
+ Built on [`@cyanheads/mcp-ts-core`](https://www.npmjs.com/package/@cyanheads/mcp-ts-core):
150
176
 
151
- - Declarative tool definitions — single file per tool, framework handles registration and validation
152
- - Unified error handling across all tools
153
- - Pluggable auth (`none`, `jwt`, `oauth`)
177
+ - Declarative tool, resource, and prompt definitions — single file per primitive, framework handles registration and validation
178
+ - Unified error handling handlers throw, framework catches, classifies, and formats
179
+ - Pluggable auth: `none`, `jwt`, `oauth`
154
180
  - Swappable storage backends: `in-memory`, `filesystem`, `Supabase`, `Cloudflare KV/R2/D1`
155
181
  - Structured logging with optional OpenTelemetry tracing
156
- - Runs locally (stdio/HTTP) or on Cloudflare Workers from the same codebase
182
+ - STDIO and Streamable HTTP transports
157
183
 
158
184
  Acme-specific:
159
185
 
160
186
  - Type-safe client for the Acme v2 API
161
187
  - Automatic cleaning and simplification of API responses for agent consumption
188
+ - Workflow tools parallelize related sub-requests under a configurable concurrency limit
162
189
  ```
163
190
 
164
191
  ### Getting Started
165
192
 
166
- Lead with the lowest-friction option. If a public hosted instance exists, show that first. Then self-hosted via `bunx`/`npx`. Then manual clone/install.
193
+ Lead with the lowest-friction option. If a public hosted instance exists, show that first. Then the **three standard install configs in order — `bunx`, `npx`, `docker run`** — followed by the HTTP one-liner quickstart, then prerequisites and install steps.
167
194
 
168
- ```markdown
169
- ## Getting Started
195
+ **Standard three-block pattern** (the house style across shipping `@cyanheads/*` servers):
170
196
 
171
- ### Public Hosted Instance
197
+ ```markdown
198
+ ## Getting started
172
199
 
173
- A public instance is available at `https://my-server.example.com/mcp` no installation required:
200
+ Add the following to your MCP client configuration file. See [`docs/api-key.md`](./docs/api-key.md) for how to generate an API key.
174
201
 
175
202
  \`\`\`json
176
203
  {
177
204
  "mcpServers": {
178
205
  "my-server": {
179
- "type": "streamable-http",
180
- "url": "https://my-server.example.com/mcp"
206
+ "type": "stdio",
207
+ "command": "bunx",
208
+ "args": ["@cyanheads/my-mcp-server@latest"],
209
+ "env": {
210
+ "MCP_TRANSPORT_TYPE": "stdio",
211
+ "MCP_LOG_LEVEL": "info",
212
+ "ACME_API_KEY": "your-api-key"
213
+ }
181
214
  }
182
215
  }
183
216
  }
184
217
  \`\`\`
185
218
 
186
- ### Self-Hosted / Local
187
-
188
- Add to your MCP client config (e.g., `claude_desktop_config.json`):
219
+ Or with npx (no Bun required):
189
220
 
190
221
  \`\`\`json
191
222
  {
192
223
  "mcpServers": {
193
- "my-mcp-server": {
224
+ "my-server": {
194
225
  "type": "stdio",
195
- "command": "bunx",
196
- "args": ["my-mcp-server@latest"],
226
+ "command": "npx",
227
+ "args": ["-y", "@cyanheads/my-mcp-server@latest"],
197
228
  "env": {
198
- "ACME_API_KEY": "your-api-key",
199
- "MCP_TRANSPORT_TYPE": "stdio"
229
+ "MCP_TRANSPORT_TYPE": "stdio",
230
+ "MCP_LOG_LEVEL": "info",
231
+ "ACME_API_KEY": "your-api-key"
200
232
  }
201
233
  }
202
234
  }
203
235
  }
204
236
  \`\`\`
205
237
 
238
+ Or with Docker:
239
+
240
+ \`\`\`json
241
+ {
242
+ "mcpServers": {
243
+ "my-server": {
244
+ "type": "stdio",
245
+ "command": "docker",
246
+ "args": [
247
+ "run", "-i", "--rm",
248
+ "-e", "MCP_TRANSPORT_TYPE=stdio",
249
+ "-e", "ACME_API_KEY=your-api-key",
250
+ "ghcr.io/cyanheads/my-mcp-server:latest"
251
+ ]
252
+ }
253
+ }
254
+ }
255
+ \`\`\`
256
+
257
+ For Streamable HTTP, set the transport and start the server:
258
+
259
+ \`\`\`sh
260
+ MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 ACME_API_KEY=... bun run start:http
261
+ # Server listens at http://localhost:3010/mcp
262
+ \`\`\`
263
+ ```
264
+
265
+ Refer to "your MCP client configuration file" generically — don't prescribe `claude_desktop_config.json` by name. Different clients use different config paths and the server isn't client-specific.
266
+
267
+ **If a public hosted instance exists**, precede the three-block pattern with a `### Public Hosted Instance` subsection and wrap the local configs in a `### Self-Hosted / Local` subsection:
268
+
269
+ ```markdown
270
+ ### Public Hosted Instance
271
+
272
+ A public instance is available at `https://my-server.example.com/mcp` — no installation required. Point any MCP client at it via Streamable HTTP:
273
+
274
+ \`\`\`json
275
+ {
276
+ "mcpServers": {
277
+ "my-server": {
278
+ "type": "streamable-http",
279
+ "url": "https://my-server.example.com/mcp"
280
+ }
281
+ }
282
+ }
283
+ \`\`\`
284
+
285
+ ### Self-Hosted / Local
286
+
287
+ [bunx / npx / docker blocks here]
288
+ ```
289
+
290
+ **Prerequisites:** Include a Bun version line and any domain-specific setup (API key format, rate-limit tiers, required accounts). Don't just list Bun — readers need to know what else to prepare.
291
+
292
+ ```markdown
206
293
  ### Prerequisites
207
294
 
208
- - [Bun v1.2.0](https://bun.sh/) or higher.
295
+ - [Bun v1.3.2](https://bun.sh/) or higher (or Node.js v22+).
296
+ - An Acme API key — see [`docs/api-key.md`](./docs/api-key.md) for how to generate one.
297
+ ```
298
+
299
+ **Installation:** Standard four steps (clone, cd, install, configure env):
209
300
 
301
+ ```markdown
210
302
  ### Installation
211
303
 
212
304
  1. **Clone the repository:**
305
+
213
306
  \`\`\`sh
214
307
  git clone https://github.com/cyanheads/my-mcp-server.git
215
308
  \`\`\`
216
309
 
217
310
  2. **Navigate into the directory:**
311
+
218
312
  \`\`\`sh
219
313
  cd my-mcp-server
220
314
  \`\`\`
221
315
 
222
316
  3. **Install dependencies:**
317
+
223
318
  \`\`\`sh
224
319
  bun install
225
320
  \`\`\`
321
+
322
+ 4. **Configure environment:**
323
+
324
+ \`\`\`sh
325
+ cp .env.example .env
326
+ # edit .env and set required vars
327
+ \`\`\`
226
328
  ```
227
329
 
228
- Omit the hosted instance subsection if there isn't one. Omit the clone/install steps if the server is npm-only (not meant to be cloned).
330
+ Omit the clone/install steps if the server is npm-only (not meant to be cloned).
229
331
 
230
332
  ### Configuration
231
333
 
232
- Table of environment variables. Include framework vars only if the server uses non-default values.
334
+ Table of environment variables. Include framework vars only if the server uses non-default values. Mark required vars with bold **Required.** in the description rather than a separate column. **Close with a pointer to `.env.example`** for the full list of optional overrides.
233
335
 
234
336
  ```markdown
235
337
  ## Configuration
@@ -238,6 +340,7 @@ Table of environment variables. Include framework vars only if the server uses n
238
340
  |:---------|:------------|:--------|
239
341
  | `ACME_API_KEY` | **Required.** API key for the Acme service. | — |
240
342
  | `ACME_BASE_URL` | API base URL. | `https://api.acme.com` |
343
+ | `ACME_TIMEOUT_MS` | Per-request timeout in milliseconds. | `60000` |
241
344
  | `MCP_TRANSPORT_TYPE` | Transport: `stdio` or `http`. | `stdio` |
242
345
  | `MCP_HTTP_PORT` | Port for HTTP server. | `3010` |
243
346
  | `MCP_AUTH_MODE` | Auth mode: `none`, `jwt`, or `oauth`. | `none` |
@@ -245,74 +348,105 @@ Table of environment variables. Include framework vars only if the server uses n
245
348
  | `LOGS_DIR` | Directory for log files (Node.js only). | `<project-root>/logs` |
246
349
  | `STORAGE_PROVIDER_TYPE` | Storage backend. | `in-memory` |
247
350
  | `OTEL_ENABLED` | Enable OpenTelemetry. | `false` |
351
+
352
+ See [`.env.example`](./.env.example) for the full list of optional overrides.
248
353
  ```
249
354
 
250
- Source from the server config Zod schema and `.env.example`. Mark required vars with bold **Required.** in the description rather than a separate column.
355
+ Source from the server config Zod schema and `.env.example`.
251
356
 
252
357
  ### Running the Server
253
358
 
254
- Separate from Getting Started. Show build + run commands, and Workers/Docker deployment if applicable.
359
+ Separate from Getting Started. Show dev, build + run, and Workers/Docker deployment if applicable.
255
360
 
256
361
  ```markdown
257
- ## Running the Server
362
+ ## Running the server
363
+
364
+ ### Local development
258
365
 
259
- ### Local Development
366
+ - **Hot-reload dev mode:**
367
+
368
+ \`\`\`sh
369
+ bun run dev:stdio
370
+ bun run dev:http
371
+ \`\`\`
260
372
 
261
373
  - **Build and run the production version:**
374
+
262
375
  \`\`\`sh
263
- bun run build
264
- bun run start:http # or start:stdio
376
+ # One-time build
377
+ bun run rebuild
378
+
379
+ # Run the built server
380
+ bun run start:stdio
381
+ # or
382
+ bun run start:http
265
383
  \`\`\`
266
384
 
267
385
  - **Run checks and tests:**
386
+
268
387
  \`\`\`sh
269
- bun run devcheck # Lints, formats, type-checks
270
- bun run test # Runs test suite
388
+ bun run devcheck # Lint, format, typecheck, security
389
+ bun run test # Vitest test suite
390
+ bun run lint:mcp # Validate MCP definitions against spec
271
391
  \`\`\`
272
392
 
393
+ ### Docker
394
+
395
+ \`\`\`sh
396
+ docker build -t my-mcp-server .
397
+ docker run --rm -e ACME_API_KEY=your-key -p 3010:3010 my-mcp-server
398
+ \`\`\`
399
+
400
+ The Dockerfile defaults to HTTP transport, stateless session mode, and logs to `/var/log/my-mcp-server`. OpenTelemetry peer dependencies are installed by default — build with `--build-arg OTEL_ENABLED=false` to omit them.
401
+
273
402
  ### Cloudflare Workers
274
403
 
275
404
  1. **Build the Worker bundle:**
405
+
276
406
  \`\`\`sh
277
407
  bun run build:worker
278
408
  \`\`\`
279
409
 
280
410
  2. **Deploy:**
411
+
281
412
  \`\`\`sh
282
413
  bun run deploy:prod
283
414
  \`\`\`
284
415
  ```
285
416
 
286
- Include the Docker or Workers subsection only if the server supports it.
417
+ Include the Docker or Workers subsection only if the server supports it. The Docker trailing paragraph (log directory, OTEL build arg) is important — it documents Dockerfile behavior that isn't obvious from the build command.
287
418
 
288
419
  ### Project Structure
289
420
 
290
421
  Directory/purpose table orienting contributors to the codebase.
291
422
 
292
423
  ```markdown
293
- ## Project Structure
424
+ ## Project structure
294
425
 
295
426
  | Directory | Purpose |
296
427
  |:----------|:--------|
428
+ | `src/index.ts` | `createApp()` entry point — registers tools/resources/prompts and inits services. |
429
+ | `src/config` | Server-specific environment variable parsing and validation with Zod. |
297
430
  | `src/mcp-server/tools` | Tool definitions (`*.tool.ts`). |
298
431
  | `src/mcp-server/resources` | Resource definitions (`*.resource.ts`). |
432
+ | `src/mcp-server/prompts` | Prompt definitions (`*.prompt.ts`). |
299
433
  | `src/services` | Domain service integrations. |
300
- | `src/config` | Environment variable parsing and validation with Zod. |
301
434
  | `tests/` | Unit and integration tests mirroring `src/`. |
302
435
  ```
303
436
 
304
437
  ### Development Guide
305
438
 
306
- Brief — link to CLAUDE.md for full details. State 2-3 key rules.
439
+ Brief — link to CLAUDE.md for full details. State 3-4 key rules. **Include the "validate → normalize → never fabricate" bullet** — it's the canonical anti-hallucination convention for external API wrappers and reinforces the framework's `no fabricated signal` principle.
307
440
 
308
441
  ```markdown
309
- ## Development Guide
442
+ ## Development guide
310
443
 
311
444
  See [`CLAUDE.md`](./CLAUDE.md) for development guidelines and architectural rules. The short version:
312
445
 
313
446
  - Handlers throw, framework catches — no `try/catch` in tool logic
314
- - Use `ctx.log` for domain-specific logging, `ctx.state` for storage
315
- - Register new tools and resources in the `index.ts` barrel files
447
+ - Use `ctx.log` for request-scoped logging, `ctx.state` for tenant-scoped storage
448
+ - Register new tools and resources via the barrels in `src/mcp-server/*/definitions/index.ts`
449
+ - Wrap external API calls: validate raw → normalize to domain type → return output schema; never fabricate missing fields
316
450
  ```
317
451
 
318
452
  ### Contributing
@@ -320,7 +454,7 @@ See [`CLAUDE.md`](./CLAUDE.md) for development guidelines and architectural rule
320
454
  ```markdown
321
455
  ## Contributing
322
456
 
323
- Issues and pull requests are welcome. Run checks before submitting:
457
+ Issues and pull requests are welcome. Run checks and tests before submitting:
324
458
 
325
459
  \`\`\`sh
326
460
  bun run devcheck
@@ -343,8 +477,12 @@ Apache-2.0 — see [LICENSE](LICENSE) for details.
343
477
  - **Accuracy over aspiration.** Only document what exists. Don't describe planned features as if they're implemented.
344
478
  - **Tools first.** The tool surface is the most important content. Lead with it.
345
479
  - **Tables over prose** for structured data (tools, config, directories). Scannable and diff-friendly.
346
- - **Two-layer tool docs.** Summary table for quick scanning, per-tool subsections for detail. Skip subsections for trivial tools.
480
+ - **Two-layer tool docs.** Grouping sentence + summary table for quick scanning, per-tool subsections for detail. Skip subsections for trivial tools.
481
+ - **Combined resources + prompts.** Single table with a `Type` column, not separate sections.
482
+ - **Promote hosted instances.** If there's a public URL, put it in a top-level callout under the badges — not buried in Getting Started.
483
+ - **Three install configs.** `bunx`, `npx`, `docker run` in that order. Each as a complete MCP-client JSON block.
347
484
  - **Real names from code.** Tool names, env vars, and URIs must match the source exactly. Copy from the definitions, don't paraphrase.
348
- - **Lowest friction first.** In Getting Started, lead with the easiest option (hosted instance > bunx > clone).
485
+ - **Lowest friction first.** Hosted instance > bunx > npx > docker > clone.
349
486
  - **No badges unless publishing.** Badges for unpublished packages are noise.
487
+ - **Client-agnostic framing.** Say "your MCP client configuration file", not `claude_desktop_config.json`.
350
488
  - **Keep it current.** Update the README whenever tools are added or removed.
@@ -4,7 +4,7 @@ description: >
4
4
  Post-init orientation for an MCP server built on @cyanheads/mcp-ts-core. Use after running `@cyanheads/mcp-ts-core init` to understand the project structure, conventions, and skill sync model. Also use when onboarding to an existing project for the first time.
5
5
  metadata:
6
6
  author: cyanheads
7
- version: "1.2"
7
+ version: "1.3"
8
8
  audience: external
9
9
  type: workflow
10
10
  ---
@@ -76,6 +76,7 @@ export const searchItems = tool('search_items', {
76
76
 
77
77
  // format() populates content[] — the only field most LLM clients forward to
78
78
  // the model. Render all data the LLM needs, not just a count or title.
79
+ // Enforced at lint time: every field in `output` must appear in the rendered text.
79
80
  format: (result) => [{
80
81
  type: 'text',
81
82
  text: result.items.map(i => `**${i.id}**: ${i.name}`).join('\n'),
@@ -76,6 +76,7 @@ export const searchItems = tool('search_items', {
76
76
 
77
77
  // format() populates content[] — the only field most LLM clients forward to
78
78
  // the model. Render all data the LLM needs, not just a count or title.
79
+ // Enforced at lint time: every field in `output` must appear in the rendered text.
79
80
  format: (result) => [{
80
81
  type: 'text',
81
82
  text: result.items.map(i => `**${i.id}**: ${i.name}`).join('\n'),
@@ -1,54 +0,0 @@
1
- ---
2
- name: devcheck
3
- description: >
4
- Lint, format, typecheck, and verify the project is clean. Use after making changes, before committing, or when the user asks to verify quality.
5
- metadata:
6
- author: cyanheads
7
- version: "1.3"
8
- audience: external
9
- type: workflow
10
- ---
11
-
12
- ## What It Runs
13
-
14
- `bun run devcheck` runs a broader check suite than just lint + types. By default it includes local hygiene checks, MCP definition linting, Biome, TypeScript, and slow dependency/security checks unless `--fast` is passed. Tests are opt-in via `--test`.
15
-
16
- | Check | Tool | Notes |
17
- |:------|:-----|:------|
18
- | TODOs / FIXMEs | `git grep` | Fails on tracked TODO/FIXME markers outside excluded files |
19
- | Tracked secrets | `git ls-files` | Flags tracked `.env`, keys, credentials, and similar sensitive files |
20
- | MCP definitions | `bun run scripts/lint-mcp.ts` | Validates tool/resource/prompt definitions against framework rules |
21
- | Biome | `biome check` | Unified lint + format — read-only by default |
22
- | TypeScript | `tsc --noEmit` | Full project type check |
23
- | Unused dependencies | `depcheck` | Runs by default; network-free but slower on large repos |
24
- | Security audit | `bun audit` | Runs by default unless `--fast` or `--no-audit` |
25
- | Outdated dependencies | `bun outdated` | Runs by default unless `--fast` or `--no-deps` |
26
- | Tests | `vitest run` | Off by default; enable with `bun run devcheck --test` |
27
-
28
- To auto-fix lint/format issues, run `bun run format`.
29
-
30
- ## Steps
31
-
32
- 1. Run `bun run devcheck`
33
- 2. Read the failing checks in the summary and per-check output
34
- 3. Fix the reported issues
35
- 4. Re-run `bun run devcheck` until clean
36
- 5. If the change touches runtime behavior, also run `bun run devcheck --test` or `bun run test`
37
- 6. Do not consider this skill complete until the required commands exit successfully with no errors
38
-
39
- ## Common Issues
40
-
41
- | Check | Error Type | Typical Fix |
42
- |:------|:-----------|:------------|
43
- | TODOs / FIXMEs | Tracked work markers | Resolve or remove the marker before committing |
44
- | Tracked secrets | Sensitive files in git | Add to `.gitignore` and remove from the index |
45
- | MCP definitions | Definition lint errors | Fix schema/name/annotation issues reported by `lint-mcp` |
46
- | Biome | Lint/format errors | Run `bun run format` to auto-fix, or address the flagged rule manually |
47
- | TypeScript | Type errors | Fix type mismatches, missing properties, incorrect generics |
48
- | Security audit | Vulnerabilities in direct deps | Update or replace the affected dependency |
49
- | Outdated deps | Stale package versions | Run `bun update` or allowlist intentionally pinned packages |
50
-
51
- ## Checklist
52
-
53
- - [ ] `bun run devcheck` exits with no errors
54
- - [ ] Tests run when needed (`bun run devcheck --test` or `bun run test`)
@@ -1,50 +0,0 @@
1
- ---
2
- name: walkthrough-init
3
- description: >
4
- Trace the agent onboarding flow after `init` scaffolds a new project. Starts from the agent reading CLAUDE.md for the first time and follows every instruction chain through skills and framework docs. Use to audit the onboarding path, find dead ends, or catch missing instructions.
5
- metadata:
6
- author: cyanheads
7
- version: "1.0"
8
- audience: internal
9
- type: debug
10
- ---
11
-
12
- ## What this skill does
13
-
14
- A developer has run `npx @cyanheads/mcp-ts-core init banking-mcp-server` and `bun install`. They open the project and run `claude`. You are that agent, seeing this project for the first time.
15
-
16
- Trace the onboarding path through the actual files as they exist right now. Follow every instruction chain — read what you're told to read, do what you're told to do, and report what happens.
17
-
18
- ---
19
-
20
- ## Instructions
21
-
22
- ### Step 1: Read the project's CLAUDE.md
23
-
24
- This is the first file the agent sees. Read `CLAUDE.md` at the project root. Report:
25
-
26
- - What does it tell you to do first?
27
- - What files does it point you to?
28
- - Does it mention the `setup` skill? How?
29
-
30
- ### Step 2: Follow the first instruction
31
-
32
- Whatever CLAUDE.md says to do first — do it. If it says to read a file, read it. If it says to run a skill, read that skill's SKILL.md. Report what you find and what it tells you to do next.
33
-
34
- ### Step 3: Keep following the chain
35
-
36
- Continue following instructions until you've completed the full onboarding loop. At each step:
37
-
38
- - What file are you reading?
39
- - What does it tell you to do?
40
- - Can you actually do it? (Do the referenced files/paths exist?)
41
- - What's the next step it points you to?
42
-
43
- ### Step 4: Report
44
-
45
- After the chain ends (or breaks), produce:
46
-
47
- 1. **The path you followed** — ordered list of files read and actions taken
48
- 2. **Broken links** — instructions that point to files that don't exist, skills that aren't written, or actions that can't be completed
49
- 3. **Dead ends** — places where the instructions stop and you don't know what to do next
50
- 4. **The complete onboarding flow** — a summary of what a new agent actually experiences, step by step