@cyanheads/mcp-ts-core 0.12.8 → 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.
- package/AGENTS.md +12 -11
- package/CLAUDE.md +12 -11
- package/README.md +2 -2
- package/biome.json +1 -1
- package/changelog/0.12.x/0.12.9.md +36 -0
- package/changelog/0.13.x/0.13.0.md +48 -0
- package/changelog/template.md +7 -24
- package/dist/cli/init.js +2 -2
- package/dist/cli/init.js.map +1 -1
- package/dist/config/envValue.d.ts +18 -0
- package/dist/config/envValue.d.ts.map +1 -0
- package/dist/config/envValue.js +35 -0
- package/dist/config/envValue.js.map +1 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +5 -7
- package/dist/config/index.js.map +1 -1
- package/dist/config/parseEnvConfig.d.ts +7 -0
- package/dist/config/parseEnvConfig.d.ts.map +1 -1
- package/dist/config/parseEnvConfig.js +9 -1
- package/dist/config/parseEnvConfig.js.map +1 -1
- package/dist/linter/validate.js +2 -2
- package/dist/linter/validate.js.map +1 -1
- package/dist/mcp-server/transports/http/httpTransport.d.ts.map +1 -1
- package/dist/mcp-server/transports/http/httpTransport.js +70 -2
- package/dist/mcp-server/transports/http/httpTransport.js.map +1 -1
- package/dist/mcp-server/transports/http/landing-page/sections/connect.d.ts.map +1 -1
- package/dist/mcp-server/transports/http/landing-page/sections/connect.js +9 -2
- package/dist/mcp-server/transports/http/landing-page/sections/connect.js.map +1 -1
- package/dist/mcp-server/transports/http/sessionStore.d.ts +10 -2
- package/dist/mcp-server/transports/http/sessionStore.d.ts.map +1 -1
- package/dist/mcp-server/transports/http/sessionStore.js.map +1 -1
- package/dist/services/mirror/sqlite/handle.d.ts.map +1 -1
- package/dist/services/mirror/sqlite/handle.js +14 -12
- package/dist/services/mirror/sqlite/handle.js.map +1 -1
- package/dist/services/mirror/sqlite/sqliteMirrorStore.js +8 -9
- package/dist/services/mirror/sqlite/sqliteMirrorStore.js.map +1 -1
- package/dist/services/mirror/types.d.ts +5 -1
- package/dist/services/mirror/types.d.ts.map +1 -1
- package/dist/utils/internal/performance.d.ts +1 -1
- package/dist/utils/internal/performance.js +2 -2
- package/dist/utils/network/fetchWithTimeout.js +1 -1
- package/dist/utils/network/retry.js +1 -1
- package/dist/utils/security/idGenerator.d.ts +3 -1
- package/dist/utils/security/idGenerator.d.ts.map +1 -1
- package/dist/utils/security/idGenerator.js +12 -1
- package/dist/utils/security/idGenerator.js.map +1 -1
- package/framework-skills/README.md +40 -0
- package/{skills → framework-skills}/add-app-tool/SKILL.md +2 -2
- package/{skills → framework-skills}/add-resource/SKILL.md +2 -2
- package/{skills → framework-skills}/add-service/SKILL.md +2 -2
- package/{skills → framework-skills}/add-test/SKILL.md +2 -2
- package/{skills → framework-skills}/add-tool/SKILL.md +7 -7
- package/{skills → framework-skills}/api-config/SKILL.md +3 -1
- package/{skills → framework-skills}/api-context/SKILL.md +3 -3
- package/{skills → framework-skills}/api-errors/SKILL.md +2 -1
- package/{skills → framework-skills}/api-linter/SKILL.md +4 -4
- package/{skills → framework-skills}/api-mirror/SKILL.md +3 -1
- package/{skills → framework-skills}/design-mcp-server/SKILL.md +59 -101
- package/{skills → framework-skills}/field-test/SKILL.md +10 -5
- package/{skills → framework-skills}/git-wrapup/SKILL.md +5 -3
- package/{skills → framework-skills}/maintenance/SKILL.md +30 -21
- package/{skills → framework-skills}/orchestrations/SKILL.md +2 -2
- package/{skills → framework-skills}/orchestrations/workflows/field-test-fix.md +8 -8
- package/{skills → framework-skills}/orchestrations/workflows/fix-wrapup-release.md +5 -5
- package/{skills → framework-skills}/orchestrations/workflows/greenfield-build.md +11 -11
- package/{skills → framework-skills}/orchestrations/workflows/maintenance-release.md +12 -12
- package/{skills → framework-skills}/polish-docs-meta/SKILL.md +18 -10
- package/{skills → framework-skills}/polish-docs-meta/references/agent-protocol.md +1 -1
- package/{skills → framework-skills}/polish-docs-meta/references/package-meta.md +1 -1
- package/{skills → framework-skills}/polish-docs-meta/references/readme.md +88 -72
- package/{skills → framework-skills}/release-and-publish/SKILL.md +4 -1
- package/{skills → framework-skills}/release-pr-review/SKILL.md +2 -2
- package/{skills → framework-skills}/report-issue-framework/SKILL.md +25 -25
- package/{skills → framework-skills}/report-issue-local/SKILL.md +22 -24
- package/{skills → framework-skills}/security-pass/SKILL.md +2 -2
- package/{skills → framework-skills}/setup/SKILL.md +10 -8
- package/package.json +13 -13
- package/scripts/check-framework-antipatterns.ts +1 -1
- package/scripts/check-skill-versions.ts +16 -9
- package/scripts/check-skills-sync.ts +64 -13
- package/scripts/clean-mcpb.ts +3 -3
- package/scripts/devcheck.ts +37 -27
- package/scripts/lint-packaging.ts +158 -24
- package/scripts/list-skills.ts +2 -2
- package/templates/.claude-plugin/plugin.json +5 -1
- package/templates/.env.example +1 -1
- package/templates/.github/CONTRIBUTING.md +4 -5
- package/templates/.github/ISSUE_TEMPLATE/bug_report.yml +5 -4
- package/templates/.github/ISSUE_TEMPLATE/config.yml +6 -1
- package/templates/.github/ISSUE_TEMPLATE/feature_request.yml +1 -2
- package/templates/AGENTS.md +16 -15
- package/templates/CLAUDE.md +16 -15
- package/templates/_.mcpbignore +1 -1
- package/templates/changelog/template.md +7 -24
- package/templates/package.json +4 -3
- package/templates/src/mcp-server/resources/definitions/echo-app-ui.app-resource.ts +1 -1
- package/skills/README.md +0 -38
- /package/{skills → framework-skills}/add-export/SKILL.md +0 -0
- /package/{skills → framework-skills}/add-prompt/SKILL.md +0 -0
- /package/{skills → framework-skills}/add-provider/SKILL.md +0 -0
- /package/{skills → framework-skills}/api-auth/SKILL.md +0 -0
- /package/{skills → framework-skills}/api-canvas/SKILL.md +0 -0
- /package/{skills → framework-skills}/api-services/SKILL.md +0 -0
- /package/{skills → framework-skills}/api-services/references/graph.md +0 -0
- /package/{skills → framework-skills}/api-services/references/llm.md +0 -0
- /package/{skills → framework-skills}/api-services/references/speech.md +0 -0
- /package/{skills → framework-skills}/api-telemetry/SKILL.md +0 -0
- /package/{skills → framework-skills}/api-testing/SKILL.md +0 -0
- /package/{skills → framework-skills}/api-utils/SKILL.md +0 -0
- /package/{skills → framework-skills}/api-utils/references/formatting.md +0 -0
- /package/{skills → framework-skills}/api-utils/references/parsing.md +0 -0
- /package/{skills → framework-skills}/api-utils/references/security.md +0 -0
- /package/{skills → framework-skills}/api-workers/SKILL.md +0 -0
- /package/{skills → framework-skills}/code-simplifier/SKILL.md +0 -0
- /package/{skills → framework-skills}/polish-docs-meta/references/server-json.md +0 -0
- /package/{skills → framework-skills}/techniques/SKILL.md +0 -0
- /package/{skills → framework-skills}/techniques/references/outline-on-overflow.md +0 -0
- /package/{skills → framework-skills}/tool-defs-analysis/SKILL.md +0 -0
|
@@ -158,7 +158,11 @@ export interface QueryResult {
|
|
|
158
158
|
}
|
|
159
159
|
/** A schema migration: bump `version` and apply `up` on open when the stored version is lower. */
|
|
160
160
|
export interface Migration {
|
|
161
|
-
/**
|
|
161
|
+
/**
|
|
162
|
+
* Apply the migration. Runs inside the open handle, on first creation as well
|
|
163
|
+
* as on upgrade, so it must be idempotent and tolerate a database that already
|
|
164
|
+
* has the current declarative schema.
|
|
165
|
+
*/
|
|
162
166
|
up(handle: SqliteHandle): void;
|
|
163
167
|
/** Target schema version this migration produces. */
|
|
164
168
|
version: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/services/mirror/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/services/mirror/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,7 +12,7 @@ export declare function initHandlerMetrics(): void;
|
|
|
12
12
|
* Returns the current time in milliseconds using `globalThis.performance.now()`.
|
|
13
13
|
*
|
|
14
14
|
* Sub-millisecond resolution is guaranteed on all supported engine floors
|
|
15
|
-
* (Node ≥24, Bun ≥1.
|
|
15
|
+
* (Node ≥24, Bun ≥1.4, Cloudflare Workers). The returned value is suitable for
|
|
16
16
|
* computing durations but its epoch origin is implementation-defined — do not
|
|
17
17
|
* treat it as a wall-clock timestamp.
|
|
18
18
|
*
|
|
@@ -54,14 +54,14 @@ function getActiveRequestsGauge() {
|
|
|
54
54
|
* Returns the current time in milliseconds using `globalThis.performance.now()`.
|
|
55
55
|
*
|
|
56
56
|
* Sub-millisecond resolution is guaranteed on all supported engine floors
|
|
57
|
-
* (Node ≥24, Bun ≥1.
|
|
57
|
+
* (Node ≥24, Bun ≥1.4, Cloudflare Workers). The returned value is suitable for
|
|
58
58
|
* computing durations but its epoch origin is implementation-defined — do not
|
|
59
59
|
* treat it as a wall-clock timestamp.
|
|
60
60
|
*
|
|
61
61
|
* @returns Current time in milliseconds.
|
|
62
62
|
*/
|
|
63
63
|
// performance is an ambient global declared by @types/node (perf_hooks.d.ts)
|
|
64
|
-
// and available in all supported environments (Node ≥24, Bun ≥1.
|
|
64
|
+
// and available in all supported environments (Node ≥24, Bun ≥1.4, workerd).
|
|
65
65
|
export const nowMs = () => performance.now();
|
|
66
66
|
// Module-level TextEncoder singleton (stateless, safe to reuse)
|
|
67
67
|
let cachedEncoder;
|
|
@@ -479,7 +479,7 @@ export async function fetchWithTimeout(url, timeoutMs, context, options) {
|
|
|
479
479
|
const timeoutReason = new DOMException(`${operationDescription} timed out after ${timeoutMs}ms.`, 'TimeoutError');
|
|
480
480
|
const timeoutId = setTimeout(() => controller.abort(timeoutReason), timeoutMs);
|
|
481
481
|
// Compose the timeout signal with any caller-supplied signal. AbortSignal.any
|
|
482
|
-
// is available on all supported floors (Node ≥24, Bun ≥1.
|
|
482
|
+
// is available on all supported floors (Node ≥24, Bun ≥1.4, workerd).
|
|
483
483
|
const fetchSignal = externalSignal
|
|
484
484
|
? AbortSignal.any([controller.signal, externalSignal])
|
|
485
485
|
: controller.signal;
|
|
@@ -209,7 +209,7 @@ function sleep(ms, signal) {
|
|
|
209
209
|
return;
|
|
210
210
|
}
|
|
211
211
|
const controller = new AbortController();
|
|
212
|
-
// AbortSignal.any is available on all supported floors (Node ≥24, Bun ≥1.
|
|
212
|
+
// AbortSignal.any is available on all supported floors (Node ≥24, Bun ≥1.4, workerd).
|
|
213
213
|
const combined = signal ? AbortSignal.any([controller.signal, signal]) : controller.signal;
|
|
214
214
|
const timer = setTimeout(() => {
|
|
215
215
|
controller.abort();
|
|
@@ -64,8 +64,10 @@ export declare class IdGenerator {
|
|
|
64
64
|
/**
|
|
65
65
|
* Generates a cryptographically secure random string.
|
|
66
66
|
* @param length - The desired length of the random string. Defaults to `IdGenerator.DEFAULT_LENGTH`.
|
|
67
|
-
* @param charset - The character set to use. Defaults to `IdGenerator.DEFAULT_CHARSET`.
|
|
67
|
+
* @param charset - The character set to use, 1 to 256 characters. Defaults to `IdGenerator.DEFAULT_CHARSET`.
|
|
68
68
|
* @returns The generated random string.
|
|
69
|
+
* @throws {McpError} With {@link JsonRpcErrorCode.ValidationError} when `charset` is empty
|
|
70
|
+
* or longer than 256 characters — the sampler cannot terminate on either.
|
|
69
71
|
*/
|
|
70
72
|
generateRandomString(length?: number, charset?: string): string;
|
|
71
73
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"idGenerator.d.ts","sourceRoot":"","sources":["../../../src/utils/security/idGenerator.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"idGenerator.d.ts","sourceRoot":"","sources":["../../../src/utils/security/idGenerator.ts"],"names":[],"mappings":"AAqDA;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,sFAAsF;IACtF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,+EAA+E;IAC/E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,qBAAa,WAAW;IACtB;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,eAAe,CAA0C;IACxE;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAO;IACvC;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,cAAc,CAAK;IAElC;;;OAGG;IACH,OAAO,CAAC,cAAc,CAA0B;IAChD;;;OAGG;IACH,OAAO,CAAC,kBAAkB,CAA8B;IAExD;;;OAGG;IACH,YAAY,cAAc,GAAE,kBAAuB,EAGlD;IAED;;;OAGG;IACI,iBAAiB,CAAC,cAAc,EAAE,kBAAkB,GAAG,IAAI,CAWjE;IAED;;;OAGG;IACI,iBAAiB,IAAI,kBAAkB,CAE7C;IAED;;;;;;;OAOG;IACI,oBAAoB,CACzB,MAAM,GAAE,MAAmC,EAC3C,OAAO,GAAE,MAAoC,GAC5C,MAAM,CAQR;IAED;;;;;OAKG;IACI,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,MAAM,CAW1E;IAED;;;;;;OAMG;IACI,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,MAAM,CAMtF;IAED;;;;;;;OAOG;IACI,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAqBzF;IAED;;;;;OAKG;IACH,OAAO,CAAC,WAAW;IAInB;;;;;;;;;;;;;;;;;OAiBG;IACI,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,GAAE,MAAsC,GAAG,MAAM,CAGxF;IAED;;;;;;OAMG;IACI,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,GAAE,MAAsC,GAAG,MAAM,CAe1F;IAED;;;;;;;;;;;;;;;;;;;;;OAqBG;IACI,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,GAAE,MAAsC,GAAG,MAAM,CAStF;CACF;AAED;;;;GAIG;AACH,eAAO,MAAM,WAAW,aAAoB,CAAC;AAE7C;;;;;;;;;;GAUG;AACH,eAAO,MAAM,YAAY,QAAO,MAA6B,CAAC;AAE9D;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,wBAAwB,QAAO,MAG3C,CAAC"}
|
|
@@ -21,6 +21,8 @@ function getRandomBytes(count) {
|
|
|
21
21
|
crypto.getRandomValues(bytes);
|
|
22
22
|
return bytes;
|
|
23
23
|
}
|
|
24
|
+
/** Largest charset the byte-wise rejection sampler below can draw from. */
|
|
25
|
+
const MAX_CHARSET_LENGTH = 256;
|
|
24
26
|
/**
|
|
25
27
|
* Builds a random string of `length` characters drawn uniformly from `charset`.
|
|
26
28
|
*
|
|
@@ -28,6 +30,10 @@ function getRandomBytes(count) {
|
|
|
28
30
|
* multiple of `charset.length` that fits in 256, so `byte % charset.length`
|
|
29
31
|
* never biases toward the low characters. Bytes are drawn in over-sized chunks
|
|
30
32
|
* rather than one at a time, so a typical ID costs one `getRandomValues` call.
|
|
33
|
+
*
|
|
34
|
+
* `charset` must hold 1 to {@link MAX_CHARSET_LENGTH} characters: an empty
|
|
35
|
+
* charset never grows `result`, and a longer one rejects every byte, so either
|
|
36
|
+
* would spin here forever. Public callers validate before reaching this.
|
|
31
37
|
*/
|
|
32
38
|
function randomStringFromCharset(length, charset) {
|
|
33
39
|
const maxValidByteValue = Math.floor(256 / charset.length) * charset.length;
|
|
@@ -103,10 +109,15 @@ export class IdGenerator {
|
|
|
103
109
|
/**
|
|
104
110
|
* Generates a cryptographically secure random string.
|
|
105
111
|
* @param length - The desired length of the random string. Defaults to `IdGenerator.DEFAULT_LENGTH`.
|
|
106
|
-
* @param charset - The character set to use. Defaults to `IdGenerator.DEFAULT_CHARSET`.
|
|
112
|
+
* @param charset - The character set to use, 1 to 256 characters. Defaults to `IdGenerator.DEFAULT_CHARSET`.
|
|
107
113
|
* @returns The generated random string.
|
|
114
|
+
* @throws {McpError} With {@link JsonRpcErrorCode.ValidationError} when `charset` is empty
|
|
115
|
+
* or longer than 256 characters — the sampler cannot terminate on either.
|
|
108
116
|
*/
|
|
109
117
|
generateRandomString(length = IdGenerator.DEFAULT_LENGTH, charset = IdGenerator.DEFAULT_CHARSET) {
|
|
118
|
+
if (charset.length === 0 || charset.length > MAX_CHARSET_LENGTH) {
|
|
119
|
+
throw validationError(`Charset must contain between 1 and ${MAX_CHARSET_LENGTH} characters; received ${charset.length}.`, { charsetLength: charset.length, max: MAX_CHARSET_LENGTH });
|
|
120
|
+
}
|
|
110
121
|
return randomStringFromCharset(length, charset);
|
|
111
122
|
}
|
|
112
123
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"idGenerator.js","sourceRoot":"","sources":["../../../src/utils/security/idGenerator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAE3D;;;;;GAKG;AACH,SAAS,cAAc,CAAC,KAAa;IACnC,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC;IACpC,MAAM,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;IAC9B,OAAO,KAAK,CAAC;AACf,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"idGenerator.js","sourceRoot":"","sources":["../../../src/utils/security/idGenerator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Framework skills
|
|
2
|
+
|
|
3
|
+
Agent Skills for `@cyanheads/mcp-ts-core`. Each subdirectory contains a `SKILL.md` following the [Agent Skills specification](https://agentskills.io/specification).
|
|
4
|
+
|
|
5
|
+
The directory is `framework-skills/`, not `skills/`, on purpose. Claude Code and Codex auto-load a plugin's root `skills/`, and these are development-time skills for building a server — not skills for the agents that use one. A server that ships a plugin manifest keeps `skills/` free for that second kind.
|
|
6
|
+
|
|
7
|
+
## Three-Tier Distribution
|
|
8
|
+
|
|
9
|
+
Skills flow through three locations. Each tier has a distinct role:
|
|
10
|
+
|
|
11
|
+
| Tier | Location | Written by | Purpose |
|
|
12
|
+
|:-----|:---------|:-----------|:--------|
|
|
13
|
+
| 1. Package | `node_modules/@cyanheads/mcp-ts-core/framework-skills/` | `npm publish` / `bun publish` | Canonical source. Ships with the package. |
|
|
14
|
+
| 2. Project | `framework-skills/` (project root) | `@cyanheads/mcp-ts-core init` CLI | Project's source of truth. Committed to git. Server-specific skills live here too. |
|
|
15
|
+
| 3. Agent | `.claude/skills/`, `.codex/skills/`, etc. | The agent itself | Agent's working copy. Synced from project `framework-skills/`. Checklists are checked here. |
|
|
16
|
+
|
|
17
|
+
### Flow
|
|
18
|
+
|
|
19
|
+
```text
|
|
20
|
+
npm publish init CLI agent sync
|
|
21
|
+
[package framework-skills/] ──────────> [project framework-skills/] ──────────> [.claude/skills/]
|
|
22
|
+
│
|
|
23
|
+
├── core skills (from package)
|
|
24
|
+
└── server-specific skills (added by devs)
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Audience
|
|
28
|
+
|
|
29
|
+
Each skill declares `metadata.audience` in its SKILL.md frontmatter:
|
|
30
|
+
|
|
31
|
+
- **`external`** — For consumers building MCP servers. Copied to project `framework-skills/` by `init`.
|
|
32
|
+
- **`internal`** — For core package developers. Stays in `node_modules`, not copied.
|
|
33
|
+
|
|
34
|
+
## Versioning
|
|
35
|
+
|
|
36
|
+
Skills declare `metadata.version` in frontmatter. The `maintenance` skill's Phase A compares versions after `bun update` and replaces a skill directory when the package version is newer; `init` only fills in what is missing and never overwrites an existing file. To pin a skill against those replacements, bump its local `metadata.version` above the package's.
|
|
37
|
+
|
|
38
|
+
## Adding Server-Specific Skills
|
|
39
|
+
|
|
40
|
+
Create a new directory in `framework-skills/` with a `SKILL.md` following the same format. The agent will pick it up on next sync. Use the core skills as examples for structure and checklist conventions.
|
|
@@ -4,7 +4,7 @@ description: >
|
|
|
4
4
|
Scaffold an MCP App tool + UI resource pair. Use when the user asks to add a tool with interactive UI, create an MCP App, or build a visual/interactive tool.
|
|
5
5
|
metadata:
|
|
6
6
|
author: cyanheads
|
|
7
|
-
version: "1.
|
|
7
|
+
version: "1.5"
|
|
8
8
|
audience: external
|
|
9
9
|
type: reference
|
|
10
10
|
---
|
|
@@ -117,7 +117,7 @@ const APP_HTML = `<!DOCTYPE html>
|
|
|
117
117
|
applyDocumentTheme,
|
|
118
118
|
applyHostFonts,
|
|
119
119
|
applyHostStyleVariables,
|
|
120
|
-
} from "https://unpkg.com/@modelcontextprotocol/ext-apps@
|
|
120
|
+
} from "https://unpkg.com/@modelcontextprotocol/ext-apps@2/app-with-deps";
|
|
121
121
|
|
|
122
122
|
const app = new App({ name: "{{TOOL_TITLE}}", version: "1.0.0" });
|
|
123
123
|
|
|
@@ -4,7 +4,7 @@ description: >
|
|
|
4
4
|
Scaffold a new MCP resource definition. Use when the user asks to add a resource, expose data via URI, or create a readable endpoint.
|
|
5
5
|
metadata:
|
|
6
6
|
author: cyanheads
|
|
7
|
-
version: "1.
|
|
7
|
+
version: "1.6"
|
|
8
8
|
audience: external
|
|
9
9
|
type: reference
|
|
10
10
|
---
|
|
@@ -139,7 +139,7 @@ export const articleResource = resource('article://{pmid}', {
|
|
|
139
139
|
});
|
|
140
140
|
```
|
|
141
141
|
|
|
142
|
-
Without `errors[]`, the handler receives plain `Context` (no `fail` method) and throws via error factories (`notFound`, `serviceUnavailable`, …) directly. The contract is opt-in. See `skills/api-errors/SKILL.md` for the full pattern, baseline codes, and conformance rules.
|
|
142
|
+
Without `errors[]`, the handler receives plain `Context` (no `fail` method) and throws via error factories (`notFound`, `serviceUnavailable`, …) directly. The contract is opt-in. See `framework-skills/api-errors/SKILL.md` for the full pattern, baseline codes, and conformance rules.
|
|
143
143
|
|
|
144
144
|
### URI template variable completion
|
|
145
145
|
|
|
@@ -4,7 +4,7 @@ description: >
|
|
|
4
4
|
Scaffold a new service integration. Use when the user asks to add a service, integrate an external API, or create a reusable domain module with its own initialization and state.
|
|
5
5
|
metadata:
|
|
6
6
|
author: cyanheads
|
|
7
|
-
version: "1.
|
|
7
|
+
version: "1.10"
|
|
8
8
|
audience: external
|
|
9
9
|
type: reference
|
|
10
10
|
---
|
|
@@ -95,7 +95,7 @@ handler: async (input, ctx) => {
|
|
|
95
95
|
|
|
96
96
|
## Resilience (External API Services)
|
|
97
97
|
|
|
98
|
-
When a service wraps an external API, apply these patterns. For the framework retry contract, see `skills/api-utils/SKILL.md`.
|
|
98
|
+
When a service wraps an external API, apply these patterns. For the framework retry contract, see `framework-skills/api-utils/SKILL.md`.
|
|
99
99
|
|
|
100
100
|
### Retry wraps the full pipeline
|
|
101
101
|
|
|
@@ -4,7 +4,7 @@ description: >
|
|
|
4
4
|
Scaffold a test file for an existing tool, resource, or service. Use when the user asks to add tests, improve coverage, or when a definition exists without a matching test file.
|
|
5
5
|
metadata:
|
|
6
6
|
author: cyanheads
|
|
7
|
-
version: "1.
|
|
7
|
+
version: "1.7"
|
|
8
8
|
audience: external
|
|
9
9
|
type: reference
|
|
10
10
|
---
|
|
@@ -15,7 +15,7 @@ Tests use Vitest and `createMockContext` from `@cyanheads/mcp-ts-core/testing`.
|
|
|
15
15
|
|
|
16
16
|
For the full `createMockContext` API and testing patterns, read:
|
|
17
17
|
|
|
18
|
-
skills/api-testing/SKILL.md
|
|
18
|
+
framework-skills/api-testing/SKILL.md
|
|
19
19
|
|
|
20
20
|
## Steps
|
|
21
21
|
|
|
@@ -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: "2.
|
|
7
|
+
version: "2.24"
|
|
8
8
|
audience: external
|
|
9
9
|
type: reference
|
|
10
10
|
---
|
|
@@ -26,9 +26,9 @@ Tools use the `tool()` builder from `@cyanheads/mcp-ts-core`. Each tool lives in
|
|
|
26
26
|
|
|
27
27
|
Tools use lowercase snake_case with a canonical server/domain prefix: `{server}_{verb}_{noun}` — 3 words.
|
|
28
28
|
|
|
29
|
-
Examples: `pubmed_search_articles`, `pubmed_fetch_fulltext`, `
|
|
29
|
+
Examples: `pubmed_search_articles`, `pubmed_fetch_fulltext`, `clinicaltrials_find_eligible`.
|
|
30
30
|
|
|
31
|
-
The server prefix
|
|
31
|
+
The server prefix is judged on clarity, not length: the brand name or the plain well-known word for the domain both pass (`pubmed_`, `patents_`); an abbreviation fails only when it reads as something else out of context (`loc_`, `ct_`). A fourth segment is fine when the noun is inherently two words (`openfda_search_device_clearances`). When a name resists the schema — can't pick a verb, noun feels generic, the *verb* wants a second word — that's usually a signal the scope is fuzzy; split the tool, rename, or reconsider.
|
|
32
32
|
|
|
33
33
|
For shape selection (Workflow or Instruction variants — standard single-action tools are the default), see the `design-mcp-server` skill's Tool shapes section.
|
|
34
34
|
|
|
@@ -169,7 +169,7 @@ export const {{TOOL_EXPORT}} = tool('{{tool_name}}', {
|
|
|
169
169
|
});
|
|
170
170
|
```
|
|
171
171
|
|
|
172
|
-
Write it as `return ctx.requestInput(...)` — the `never` return type makes it valid in return position for any output, and it is what lets TypeScript narrow the line below. Full reference (`inputRequired.elicitUrl` / `.createMessage` / `.listRoots`, `requestState`, decline handling): `skills/api-context`.
|
|
172
|
+
Write it as `return ctx.requestInput(...)` — the `never` return type makes it valid in return position for any output, and it is what lets TypeScript narrow the line below. Full reference (`inputRequired.elicitUrl` / `.createMessage` / `.listRoots`, `requestState`, decline handling): `framework-skills/api-context`.
|
|
173
173
|
|
|
174
174
|
### Registration
|
|
175
175
|
|
|
@@ -413,7 +413,7 @@ async handler(input, ctx) {
|
|
|
413
413
|
},
|
|
414
414
|
```
|
|
415
415
|
|
|
416
|
-
The alternative — declaring `previewData: z.string()` in `output` and emitting the block from `format()` — ships the bytes twice (once in `structuredContent`, once in the block). Reserve `output` for data the agent reasons over; route raw media through `ctx.content`. Test with `getContentBlocks(ctx)`. Full reference: `skills/api-context` § `ctx.content`.
|
|
416
|
+
The alternative — declaring `previewData: z.string()` in `output` and emitting the block from `format()` — ships the bytes twice (once in `structuredContent`, once in the block). Reserve `output` for data the agent reasons over; route raw media through `ctx.content`. Test with `getContentBlocks(ctx)`. Full reference: `framework-skills/api-context` § `ctx.content`.
|
|
417
417
|
|
|
418
418
|
### Capped lists must disclose truncation
|
|
419
419
|
|
|
@@ -714,7 +714,7 @@ throw invalidParams(
|
|
|
714
714
|
);
|
|
715
715
|
```
|
|
716
716
|
|
|
717
|
-
**Error messages are recovery instructions.** Name what went wrong, why, and what action to take. The message is the agent's only signal — a bare "Not found" is a dead end. See `skills/api-errors/SKILL.md` for the full contract pattern, factories list, auto-classification table, and error-path parity (how `data.recovery.hint` reaches both client surfaces).
|
|
717
|
+
**Error messages are recovery instructions.** Name what went wrong, why, and what action to take. The message is the agent's only signal — a bare "Not found" is a dead end. See `framework-skills/api-errors/SKILL.md` for the full contract pattern, factories list, auto-classification table, and error-path parity (how `data.recovery.hint` reaches both client surfaces).
|
|
718
718
|
|
|
719
719
|
### Include operational metadata
|
|
720
720
|
|
|
@@ -774,7 +774,7 @@ Large payloads burn the agent's context window. Default to curated summaries; of
|
|
|
774
774
|
- **Lists**: Return top N with a total count and pagination cursor, not unbounded arrays
|
|
775
775
|
- **Large objects**: Return key fields by default; accept a `fields` or `verbose` parameter for full data
|
|
776
776
|
- **Binary/blob content**: Return metadata and a reference, not the raw content
|
|
777
|
-
- **Analytical working sets**: When upstream returns more *analytical* rows (data an agent would SQL — aggregate, group, join) than fit in context, `DataCanvas` (`
|
|
777
|
+
- **Analytical working sets**: When upstream returns more *analytical* rows (data an agent would SQL — aggregate, group, join) than fit in context, `DataCanvas` (`core.canvas`, wired in `setup()` via `setCanvas`; Tier 3 — opt-in via `CANVAS_PROVIDER_TYPE=duckdb`) lets you register the rows and return the `canvas_id` plus a preview so the agent can run SQL to slice down without a re-fetch. The `spillover()` helper (`@cyanheads/mcp-ts-core/canvas`) automates the overflow case: drain rows up to a character budget for the inline preview, auto-register the full source on overflow, return both as a discriminated union. **Two gates:** it must be analytical, not a discovery/search surface of categorical metadata (those don't earn a canvas regardless of row count — use MCP-side list filtering or pagination); and a tool emitting a `canvas_id` MUST be paired with a registered `dataframe_query` tool, or the handle is unreachable. Compute distributions or refinement hints across the full result — not the preview — so the agent gets honest aggregate signal on the rows it didn't read. See `api-canvas` for the register / query / export pattern and the spillover flow.
|
|
778
778
|
- **One large document**: When a single call returns one document-shaped record (not a row set) that can overflow context, return a section *outline* — top-level keys + per-section byte size — and let the agent re-call with `sections: [...]` for only what it needs, instead of truncating one surface. `outlineOnOverflow()` with `OUTLINE_VARIANT` / `selectSections()` / `formatOutline()` (`@cyanheads/mcp-ts-core/utils`) measures the payload and returns a `full | outline` result. Declare the tool's `output` as a flat `z.object` with a `kind` discriminator and presence-based optional arms (fold in `OUTLINE_VARIANT.shape.sections` / `.notice`) — `tool()` rejects a `z.discriminatedUnion` output — and render each arm on field presence in `format()` so parity holds. Pure measure + key-slice — Workers-portable, unlike canvas `spillover()`. Use for one fat record; use `spillover()` for a row collection. See the `techniques` skill's `outline-on-overflow` reference.
|
|
779
779
|
|
|
780
780
|
## MCP-side list filtering
|
|
@@ -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.
|
|
7
|
+
version: "1.17"
|
|
8
8
|
audience: external
|
|
9
9
|
type: reference
|
|
10
10
|
---
|
|
@@ -262,6 +262,8 @@ export function getServerConfig(): ServerConfig {
|
|
|
262
262
|
|
|
263
263
|
**Env booleans — use `z.stringbool()`, never `z.coerce.boolean()`.** `z.coerce.boolean()` runs `Boolean(value)`, so `"false"`, `"0"`, and `"no"` all coerce to `true` — the flag becomes impossible to disable through the environment except by omitting it entirely. `z.stringbool()` parses `true/false/1/0/yes/no/on/off` (case-insensitive) and rejects anything else, so `MY_VERBOSE_LOGGING=false` actually disables and a typo fails loudly at startup instead of silently coercing. Empty string and unset both fall through to `.default()`.
|
|
264
264
|
|
|
265
|
+
**Unset means unset.** `parseEnvConfig` and the framework's own config both treat an empty string and a whole-value `${…}` placeholder — what an MCPB or plugin host forwards when a user leaves an option blank and nothing substitutes it — as the variable being absent: an optional field stays `undefined`, a defaulted field takes its default, and a required field fails as missing rather than as a format error against the literal text. A value that merely contains `${…}` is kept. No per-field `z.preprocess` guard is needed for either case.
|
|
266
|
+
|
|
265
267
|
**Why `parseEnvConfig`?** It maps Zod schema paths to env var names so validation errors name the actual variable at fault. A missing `MY_API_KEY` produces:
|
|
266
268
|
|
|
267
269
|
```
|
|
@@ -4,7 +4,7 @@ description: >
|
|
|
4
4
|
Canonical reference for the unified `Context` object passed to every tool and resource handler in `@cyanheads/mcp-ts-core`. Covers the full interface, its `RequestContext` base, all sub-APIs (`ctx.log`, `ctx.state`, `ctx.requestInput`, `ctx.inputs`, `ctx.enrich`, `ctx.content`), and when to use each.
|
|
5
5
|
metadata:
|
|
6
6
|
author: cyanheads
|
|
7
|
-
version: "2.
|
|
7
|
+
version: "2.3"
|
|
8
8
|
audience: external
|
|
9
9
|
type: reference
|
|
10
10
|
---
|
|
@@ -594,7 +594,7 @@ async handler(input, ctx) {
|
|
|
594
594
|
}
|
|
595
595
|
```
|
|
596
596
|
|
|
597
|
-
The contract is opt-in. See `skills/api-errors/SKILL.md` for the full type-driven pattern, lint rules, and baseline-codes guidance.
|
|
597
|
+
The contract is opt-in. See `framework-skills/api-errors/SKILL.md` for the full type-driven pattern, lint rules, and baseline-codes guidance.
|
|
598
598
|
|
|
599
599
|
---
|
|
600
600
|
|
|
@@ -737,7 +737,7 @@ async handler(input, ctx) {
|
|
|
737
737
|
|
|
738
738
|
The `capped-list-no-truncation` lint rule fires when a cap-like input + array output shape is present without any of: `truncated` or `totalCount` in the declared `enrichment`, or `truncated` or `totalCount` in `output`. Using `ctx.enrich.total(n)` (writes `totalCount`) is also recognized as honest disclosure.
|
|
739
739
|
|
|
740
|
-
See `add-tool`'s **Tool Response Design** and `skills/api-linter` (`enrichment-*` rules) for the full pattern. Test enrichment with `getEnrichment(ctx)` from `@cyanheads/mcp-ts-core/testing`.
|
|
740
|
+
See `add-tool`'s **Tool Response Design** and `framework-skills/api-linter` (`enrichment-*` rules) for the full pattern. Test enrichment with `getEnrichment(ctx)` from `@cyanheads/mcp-ts-core/testing`.
|
|
741
741
|
|
|
742
742
|
---
|
|
743
743
|
|
|
@@ -4,7 +4,7 @@ description: >
|
|
|
4
4
|
McpError constructor, JsonRpcErrorCode reference, and error handling patterns for `@cyanheads/mcp-ts-core`. Use when looking up error codes, understanding where errors should be thrown vs. caught, or using ErrorHandler.tryCatch in services.
|
|
5
5
|
metadata:
|
|
6
6
|
author: cyanheads
|
|
7
|
-
version: "1.
|
|
7
|
+
version: "1.10"
|
|
8
8
|
audience: external
|
|
9
9
|
type: reference
|
|
10
10
|
---
|
|
@@ -363,6 +363,7 @@ Important properties:
|
|
|
363
363
|
- **`data` propagation is restricted** to explicitly-thrown `McpError.data` and `ZodError.issues`. Auto-classified plain errors (`TypeError`, network errors, etc.) emit `code` + `message` only — no `data` — so internal classification context never leaks to clients.
|
|
364
364
|
- **Recovery hint mirroring is automatic.** When the thrown `McpError` carries `data.recovery.hint`, the handler factory appends it to the `content[]` text so the markdown surface matches the JSON surface. Authors don't need to format the hint manually.
|
|
365
365
|
- **Argument-schema rejection is a tool error with the same envelope.** An unknown root key, a wrong type, a missing required field, or a failed constraint returns `isError: true` with `structuredContent.error.code = -32602` (`InvalidParams`) and the readable `Invalid arguments for tool <name>: …` diagnostic in `content[]`. The handler never runs. Two neighbouring failures keep the protocol error path instead, arriving as a JSON-RPC error rather than a tool result: an unknown or disabled tool name, and a malformed request envelope.
|
|
366
|
+
- **A schema constraint cannot carry a declared reason.** Because the handler never runs, a rejection by `.max()`, `.regex()`, `.min()`, or any other Zod refinement bypasses `errors[]` entirely: it arrives as `InvalidParams` with `data.issues` and no `data.reason`, so a caller has nothing to branch on and gets no recovery hint. Decide per constraint which surface it belongs on. A bound that is purely structural — the input is the wrong shape and no guidance beyond the diagnostic would help — belongs on the schema, where it also advertises itself in `inputSchema`. A bound a caller is expected to recover from belongs in the handler as `ctx.fail('reason', message, ctx.recoveryFor('reason'))` against a declared `errors[]` entry, with the limit restated in the field's `.describe()` so it is still visible before the call. Enforcing the same bound in both places is the trap: the schema wins, and the contract entry becomes unreachable while still reading as covered.
|
|
366
367
|
|
|
367
368
|
**Handler — throw freely, no try/catch:**
|
|
368
369
|
|
|
@@ -4,7 +4,7 @@ description: >
|
|
|
4
4
|
MCP definition linter rules reference. Use when `bun run lint:mcp` or `bun run devcheck` reports a lint error or warning (`format-parity`, `schema-is-object`, `name-format`, `server-json-*`, etc.) and you need to understand the rule, its severity, and how to fix it. Every rule ID the linter emits has an entry in this doc.
|
|
5
5
|
metadata:
|
|
6
6
|
author: cyanheads
|
|
7
|
-
version: "1.
|
|
7
|
+
version: "1.14"
|
|
8
8
|
audience: external
|
|
9
9
|
type: reference
|
|
10
10
|
---
|
|
@@ -18,7 +18,7 @@ The linter validates tool, resource, and prompt definitions against the MCP spec
|
|
|
18
18
|
| `bun run lint:mcp` | Manual or CI | Prints errors + warnings, exits non-zero on errors. |
|
|
19
19
|
| `bun run devcheck` | Pre-commit workflow | Wraps `lint:mcp` alongside typecheck, format, `bun audit`, `bun outdated`. |
|
|
20
20
|
|
|
21
|
-
Both surface the same `LintReport` from `validateDefinitions()` (exported from `@cyanheads/mcp-ts-core/linter`). Each diagnostic has a stable `rule` ID — that's the anchor you land on via the `See: skills/api-linter/SKILL.md#<rule>` breadcrumb appended to every message.
|
|
21
|
+
Both surface the same `LintReport` from `validateDefinitions()` (exported from `@cyanheads/mcp-ts-core/linter`). Each diagnostic has a stable `rule` ID — that's the anchor you land on via the `See: framework-skills/api-linter/SKILL.md#<rule>` breadcrumb appended to every message.
|
|
22
22
|
|
|
23
23
|
**Severity:**
|
|
24
24
|
- **error** — MUST-level spec violation; blocks `devcheck`.
|
|
@@ -615,7 +615,7 @@ Validate the `landing` config passed to `createApp()` (the config object that dr
|
|
|
615
615
|
| `landing-theme-accent` | error | `theme.accent` is present but not a string |
|
|
616
616
|
| `landing-theme-accent-format` | error | `theme.accent` doesn't match the expected color format |
|
|
617
617
|
|
|
618
|
-
Diagnostic anchors for these rules are the rule ID — e.g. `skills/api-linter/SKILL.md#landing-shape`. Pass `landing` to `validateDefinitions({ landing, tools, resources, prompts })` to opt in.
|
|
618
|
+
Diagnostic anchors for these rules are the rule ID — e.g. `framework-skills/api-linter/SKILL.md#landing-shape`. Pass `landing` to `validateDefinitions({ landing, tools, resources, prompts })` to opt in.
|
|
619
619
|
|
|
620
620
|
---
|
|
621
621
|
|
|
@@ -692,7 +692,7 @@ throw serviceUnavailable('Upstream failed', { upstreamError: e }, { cause: e });
|
|
|
692
692
|
|
|
693
693
|
Validate the optional `errors[]` declarative contract on tool/resource definitions. Structural rules check the shape of contract entries; conformance rules cross-check the handler body against the declared codes.
|
|
694
694
|
|
|
695
|
-
When a contract is declared, the handler receives a typed `ctx.fail(reason, …)` keyed by the declared reason union. See `skills/api-errors/SKILL.md` for runtime semantics.
|
|
695
|
+
When a contract is declared, the handler receives a typed `ctx.fail(reason, …)` keyed by the declared reason union. See `framework-skills/api-errors/SKILL.md` for runtime semantics.
|
|
696
696
|
|
|
697
697
|
### error-contract-type
|
|
698
698
|
|
|
@@ -4,7 +4,7 @@ description: >
|
|
|
4
4
|
Stand up a persistent, self-refreshing local mirror of a bulk upstream dataset with the MirrorService (@cyanheads/mcp-ts-core/mirror). Use when a server wraps a large or slow API and should query a synced local index (embedded SQLite + FTS5) instead of paginating the live API per request.
|
|
5
5
|
metadata:
|
|
6
6
|
author: cyanheads
|
|
7
|
-
version: "1.
|
|
7
|
+
version: "1.2"
|
|
8
8
|
audience: external
|
|
9
9
|
type: reference
|
|
10
10
|
---
|
|
@@ -81,6 +81,8 @@ Why they can't merge: during a from-scratch init the records aren't ordered by t
|
|
|
81
81
|
|
|
82
82
|
For access paths the generic query can't express — junction tables for index-backed multi-value filtering, denormalized counters, bespoke `bm25` weighting — use the **raw handle**: `const db = await mirror.raw();` then run prepared statements against your own auxiliary tables (declare them via a migration). Add the auxiliary DDL in a `migrations` step; maintain it from your `sync` mapping or SQL triggers.
|
|
83
83
|
|
|
84
|
+
A migration runs identically on first creation and on upgrade: a fresh database runs every migration up to `version` right after the declarative DDL, an existing one runs only those above its stored version. So `up()` must tolerate a database that already has the current declarative shape — `CREATE TABLE IF NOT EXISTS` for auxiliary objects, never an `ALTER` that assumes an older layout of a declared column.
|
|
85
|
+
|
|
84
86
|
## Readiness — key off the completion marker, not live status
|
|
85
87
|
|
|
86
88
|
`status().ready` is `true` once a full sync has **ever completed** (`completedAt != null`), not when `status === 'complete'`. The dataset stays transactionally queryable during a refresh, so a mirror mid-refresh — or one whose last refresh failed — is still ready and should keep serving. Gate the mirror read path on `await mirror.ready()`; fall back to the live API only when it is `false` (cold, never-completed init).
|