@cyanheads/mcp-ts-core 0.6.13 → 0.6.15
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 +2 -1
- package/README.md +2 -2
- package/changelog/0.6.x/0.6.14.md +22 -0
- package/changelog/0.6.x/0.6.15.md +26 -0
- package/dist/cli/init.js +1 -0
- package/dist/cli/init.js.map +1 -1
- package/dist/logs/combined.log +4 -4
- package/dist/logs/error.log +4 -4
- package/package.json +2 -1
- package/scripts/check-skills-sync.ts +150 -0
- package/scripts/devcheck.ts +27 -0
- package/skills/polish-docs-meta/SKILL.md +2 -0
- package/skills/release-and-publish/SKILL.md +1 -0
- package/skills/security-pass/SKILL.md +323 -0
- package/skills/setup/SKILL.md +3 -2
- package/templates/AGENTS.md +4 -2
- package/templates/CLAUDE.md +4 -2
- package/templates/devcheck.config.json +1 -0
- package/templates/package.json +1 -0
package/CLAUDE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Agent Protocol
|
|
2
2
|
|
|
3
|
-
**Package:** `@cyanheads/mcp-ts-core` · **Version:** 0.6.
|
|
3
|
+
**Package:** `@cyanheads/mcp-ts-core` · **Version:** 0.6.15
|
|
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.
|
|
@@ -461,6 +461,7 @@ Detailed method signatures, options, and examples live in skill files. Read the
|
|
|
461
461
|
| `add-service` | `skills/add-service/SKILL.md` | Scaffold a new domain service |
|
|
462
462
|
| `add-test` | `skills/add-test/SKILL.md` | Scaffold test file for a tool, resource, or service |
|
|
463
463
|
| `field-test` | `skills/field-test/SKILL.md` | Exercise tools/resources/prompts with real inputs, verify behavior, report issues |
|
|
464
|
+
| `security-pass` | `skills/security-pass/SKILL.md` | Review server for MCP-flavored security gaps: output injection, scope blast radius, elicit gaps, upstream auth, input sinks, tenant isolation, leakage, resource bounds |
|
|
464
465
|
| `add-provider` | `skills/add-provider/SKILL.md` | Add a new provider implementation |
|
|
465
466
|
| `add-export` | `skills/add-export/SKILL.md` | Add a new subpath export |
|
|
466
467
|
| `design-mcp-server` | `skills/design-mcp-server/SKILL.md` | Design tool surface, resources, and service layer for a new server |
|
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
<div align="center">
|
|
7
7
|
|
|
8
|
-
[](./CHANGELOG.md) [](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/docs/specification/2025-11-25/changelog.mdx) [](https://modelcontextprotocol.io/) [](./LICENSE)
|
|
9
9
|
|
|
10
10
|
[](https://www.typescriptlang.org/) [](https://bun.sh/)
|
|
11
11
|
|
|
@@ -43,7 +43,7 @@ bun install
|
|
|
43
43
|
|
|
44
44
|
You get a scaffolded project with `CLAUDE.md`, Agent Skills, and a `src/` tree ready for your tools. Infrastructure — transports, auth, storage, telemetry, lifecycle, linting — lives in `node_modules`. What's left is domain: which APIs to wrap, which workflows to expose.
|
|
45
45
|
|
|
46
|
-
Start your coding agent (Claude Code, Codex, Cursor), describe the system you want to expose, and it drives the build. The included skills cover the full cycle: `setup`, `design-mcp-server`, scaffolding, testing, `release-and-publish`.
|
|
46
|
+
Start your coding agent (Claude Code, Codex, Cursor), describe the system you want to expose, and it drives the build. The included skills cover the full cycle: `setup`, `design-mcp-server`, scaffolding, testing, `security-pass`, `release-and-publish`.
|
|
47
47
|
|
|
48
48
|
### What you get
|
|
49
49
|
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: New security-pass skill (8-axis MCP server audit) and devcheck Skills Sync step verifying skills/ propagated to local agent mirrors
|
|
3
|
+
breaking: false
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 0.6.14 — 2026-04-23
|
|
7
|
+
|
|
8
|
+
Adds a structured pre-release security review path and closes the silent-drift gap between `skills/` and local agent mirrors. No code-runtime changes.
|
|
9
|
+
|
|
10
|
+
## Added
|
|
11
|
+
|
|
12
|
+
- **`skills/security-pass/`** (v1.0). New audit skill that walks an MCP server through eight axes shaped around what the server builder actually controls — tool output as LLM injection vector, scope granularity, destructive ops without `ctx.elicit`, upstream auth shape, input sinks (URL/path/shell/proto-pollution), tenant isolation (module-scope state in services), leakage back (errors/outputs/logs), and resource bounds. Produces grouped findings (critical → high → medium → low) and a numbered, cherry-pickable options list. Cross-referenced from `polish-docs-meta`, `release-and-publish`, `setup`, `templates/AGENTS.md`/`CLAUDE.md` "What's Next?" sequence (now slot 8), and the root agent protocol skill table.
|
|
13
|
+
- **`Skills Sync` devcheck step** (`scripts/check-skills-sync.ts`, 150 lines). Compares canonical `skills/` against `.agents/skills/` and `.claude/skills/` mirrors and reports missing or content-drifted files. Skipped automatically when `skills/` or both mirrors are absent (non-mirrored projects). Drift is demoted to a warning in devcheck so it surfaces without blocking. Per-skill or per-file ignores live in `devcheck.config.json` `skillsSync.ignore`. Script is shipped via `package.json` `files` and copied into new servers by the init CLI.
|
|
14
|
+
|
|
15
|
+
## Changed
|
|
16
|
+
|
|
17
|
+
- **`templates/AGENTS.md`** / **`templates/CLAUDE.md`** — "What's Next?" sequence reordered to insert `security-pass` between `devcheck` and `polish-docs-meta` (steps renumbered 8 → 10). Skill table updated.
|
|
18
|
+
- **`README.md`** — `security-pass` added to the included-skills lifecycle blurb between `testing` and `release-and-publish`.
|
|
19
|
+
|
|
20
|
+
## Removed
|
|
21
|
+
|
|
22
|
+
- **`scripts/make-executable.ts`** (123 lines). Unreferenced — not in `package.json` `files`, not in `SCAFFOLD_SCRIPTS`, not invoked by any build script. The framework's CLI binary uses Node's shebang directly; chmod handling at install time is npm's job.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: Scaffolded devcheck passes green on a fresh `init` (depcheck wired up); security-pass skill v1.1 expands coverage to resources, prompts, HTTP deployment surface, sampling, roots, telemetry, and schema strictness
|
|
3
|
+
breaking: false
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 0.6.15 — 2026-04-23
|
|
7
|
+
|
|
8
|
+
Fixes a broken first-run experience in scaffolded servers and ships a substantial expansion of the `security-pass` audit skill.
|
|
9
|
+
|
|
10
|
+
## Fixed
|
|
11
|
+
|
|
12
|
+
- **`templates/package.json`** — added `"depcheck": "^1.4.7"` to `devDependencies`. `scripts/devcheck.ts` (copied verbatim into scaffolds) invokes `node_modules/.bin/depcheck` directly, but the template never declared the dependency — so `bun install && bun run devcheck` on a fresh `@cyanheads/mcp-ts-core init` project failed the Unused Dependencies step with `ENOENT`.
|
|
13
|
+
- **`templates/devcheck.config.json`** — appended `"depcheck"` to `depcheck.ignores`. `depcheck` is CLI-only (never `import`ed), so once added to `devDependencies` it self-flags as unused unless ignored. Resolves [#49](https://github.com/cyanheads/mcp-ts-core/issues/49).
|
|
14
|
+
|
|
15
|
+
## Changed
|
|
16
|
+
|
|
17
|
+
- **`skills/security-pass/`** — bumped from v1.0 → v1.1. Broadened injection-surface coverage, added HTTP deployment surface as a first-class section, and strengthened several axes:
|
|
18
|
+
- **Axis 1 (injection vector)** now covers resource content, prompt templates, and definition metadata (`description`, `title`, `annotations`, `inputSchema` field descriptions). Adds checks for templated descriptions ("tool poisoning") and mid-session description mutation ("rug-pull").
|
|
19
|
+
- **New deployment-surface section** under "Build the map" for HTTP/SSE transports: bind address, Origin allowlist (DNS rebinding), session ID source and auth binding, unauthenticated route leakage, MCP Authorization spec compliance (PKCE, token `aud`, resource indicators).
|
|
20
|
+
- **Axis 3 (destructive ops)** — requires elicit responses to be schema-validated (the returned payload is LLM-mediated, not user-direct) and consent scoped to a concrete target, not generic.
|
|
21
|
+
- **Axis 5 (input sinks)** — adds sampling responses (`ctx.sample` result is untrusted input), roots-derived paths, schema strictness (`.strict()` on inputs, no `.passthrough()` / `.catchall()` on outputs), and ReDoS-safe regex/glob bounds.
|
|
22
|
+
- **Axis 7 (leakage back)** — broadened beyond `ctx.log` to `console.*`, OpenTelemetry span attributes, Sentry breadcrumbs, and constant-time comparison requirements for secret / token / HMAC equality checks.
|
|
23
|
+
- **Axis 8 (resource bounds)** — adds `JSON.parse` / Zod parse size+depth limits, per-tenant per-tool rate limits, and concurrency caps on long-running tools.
|
|
24
|
+
- **Quick sanity pass** — adds npm provenance check for new security-critical deps.
|
|
25
|
+
- **`fuzzTool`** guidance moved to Step 1 so it runs in parallel with manual axis walks, feeding Axis 5 / Axis 8 triage.
|
|
26
|
+
- Mirrored to `.agents/skills/security-pass/` and `.claude/skills/security-pass/` to clear the devcheck Skills Sync warning introduced with the sync check in 0.6.14.
|
package/dist/cli/init.js
CHANGED
package/dist/cli/init.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"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"}
|
package/dist/logs/combined.log
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
{"level":50,"time":
|
|
2
|
-
{"level":50,"time":
|
|
3
|
-
{"level":50,"time":
|
|
4
|
-
{"level":50,"time":
|
|
1
|
+
{"level":50,"time":1776994404554,"env":"testing","version":"0.0.0-test","pid":90736,"requestId":"2HYYK-DP0GV","timestamp":"2026-04-24T01:33:24.553Z","operation":"HandleToolRequest","input":{"message":"blocked"},"critical":false,"errorCode":-32005,"originalErrorType":"McpError","finalErrorType":"McpError","sessionId":"f334772c59555f74dab21cde1a66ce1ed8b6584137f26a0b2c522936e8f77d9e","toolName":"scoped_echo","tenantId":"authz-tenant","auth":{"sub":"authz-user","scopes":["tool:other:read"],"clientId":"authz-client","tenantId":"authz-tenant"},"errorData":{"sessionId":"f334772c59555f74dab21cde1a66ce1ed8b6584137f26a0b2c522936e8f77d9e","toolName":"scoped_echo","input":{"message":"blocked"},"requestId":"2HYYK-DP0GV","timestamp":"2026-04-24T01:33:24.553Z","tenantId":"authz-tenant","operation":"HandleToolRequest","auth":{"sub":"authz-user","scopes":["tool:other:read"],"clientId":"authz-client","tenantId":"authz-tenant"},"originalErrorName":"McpError","originalMessage":"Insufficient permissions.","originalStack":"McpError: Insufficient permissions.\n at forbidden (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:84:58)\n at withRequiredScopes (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/lib/authUtils.js:61:15)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:68:17)\n at executeToolHandler (/Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:231:34)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:126:43)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Insufficient permissions.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:168:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:101:42)\n at executeToolHandler (/Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:231:34)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:126:43)\n at processTicksAndRejections (native:7:39)","msg":"Error in tool:scoped_echo: Insufficient permissions."}
|
|
2
|
+
{"level":50,"time":1776994404869,"env":"testing","version":"0.6.15","pid":90768,"requestId":"SM09A-GLQJP","timestamp":"2026-04-24T01:33:24.868Z","operation":"httpErrorHandler","critical":false,"errorCode":-32006,"originalErrorType":"McpError","finalErrorType":"McpError","path":"/mcp","method":"POST","errorData":{"path":"/mcp","method":"POST","requestId":"SM09A-GLQJP","timestamp":"2026-04-24T01:33:24.868Z","operation":"httpErrorHandler","originalErrorName":"McpError","originalMessage":"Missing or invalid Authorization header. Bearer scheme required.","originalStack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at unauthorized (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:86:61)\n at authMiddleware (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/authMiddleware.js:64:19)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpTransport.js:119:22)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at cors2 (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/middleware/cors/index.js:82:11)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:168:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpErrorHandler.js:59:39)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:26:25)\n at processTicksAndRejections (native:7:39)","msg":"Error in httpTransport: Missing or invalid Authorization header. Bearer scheme required."}
|
|
3
|
+
{"level":50,"time":1776994404882,"env":"testing","version":"0.6.15","pid":90768,"requestId":"NWSZB-RSSE7","timestamp":"2026-04-24T01:33:24.882Z","operation":"httpErrorHandler","critical":false,"errorCode":-32006,"originalErrorType":"McpError","finalErrorType":"McpError","path":"/mcp","method":"POST","errorData":{"path":"/mcp","method":"POST","requestId":"NWSZB-RSSE7","timestamp":"2026-04-24T01:33:24.882Z","operation":"httpErrorHandler","originalErrorName":"McpError","originalMessage":"Token has expired.","originalStack":"McpError: Token has expired.\n at unauthorized (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:86:61)\n at handleJoseVerifyError (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/lib/claimParser.js:56:11)\n at verify (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/strategies/jwtStrategy.js:91:13)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Token has expired.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:168:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpErrorHandler.js:59:39)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:26:25)\n at processTicksAndRejections (native:7:39)","msg":"Error in httpTransport: Token has expired."}
|
|
4
|
+
{"level":50,"time":1776994404886,"env":"testing","version":"0.6.15","pid":90768,"requestId":"U3CD0-HCUAL","timestamp":"2026-04-24T01:33:24.886Z","operation":"httpErrorHandler","critical":false,"errorCode":-32006,"originalErrorType":"McpError","finalErrorType":"McpError","path":"/mcp","method":"GET","errorData":{"path":"/mcp","method":"GET","requestId":"U3CD0-HCUAL","timestamp":"2026-04-24T01:33:24.886Z","operation":"httpErrorHandler","originalErrorName":"McpError","originalMessage":"Missing or invalid Authorization header. Bearer scheme required.","originalStack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at unauthorized (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:86:61)\n at authMiddleware (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/authMiddleware.js:64:19)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpTransport.js:119:22)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at cors2 (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/middleware/cors/index.js:82:11)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:168:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpErrorHandler.js:59:39)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:26:25)\n at processTicksAndRejections (native:7:39)","msg":"Error in httpTransport: Missing or invalid Authorization header. Bearer scheme required."}
|
package/dist/logs/error.log
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
{"level":50,"time":
|
|
2
|
-
{"level":50,"time":
|
|
3
|
-
{"level":50,"time":
|
|
4
|
-
{"level":50,"time":
|
|
1
|
+
{"level":50,"time":1776994404554,"env":"testing","version":"0.0.0-test","pid":90736,"requestId":"2HYYK-DP0GV","timestamp":"2026-04-24T01:33:24.553Z","operation":"HandleToolRequest","input":{"message":"blocked"},"critical":false,"errorCode":-32005,"originalErrorType":"McpError","finalErrorType":"McpError","sessionId":"f334772c59555f74dab21cde1a66ce1ed8b6584137f26a0b2c522936e8f77d9e","toolName":"scoped_echo","tenantId":"authz-tenant","auth":{"sub":"authz-user","scopes":["tool:other:read"],"clientId":"authz-client","tenantId":"authz-tenant"},"errorData":{"sessionId":"f334772c59555f74dab21cde1a66ce1ed8b6584137f26a0b2c522936e8f77d9e","toolName":"scoped_echo","input":{"message":"blocked"},"requestId":"2HYYK-DP0GV","timestamp":"2026-04-24T01:33:24.553Z","tenantId":"authz-tenant","operation":"HandleToolRequest","auth":{"sub":"authz-user","scopes":["tool:other:read"],"clientId":"authz-client","tenantId":"authz-tenant"},"originalErrorName":"McpError","originalMessage":"Insufficient permissions.","originalStack":"McpError: Insufficient permissions.\n at forbidden (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:84:58)\n at withRequiredScopes (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/lib/authUtils.js:61:15)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:68:17)\n at executeToolHandler (/Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:231:34)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:126:43)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Insufficient permissions.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:168:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:101:42)\n at executeToolHandler (/Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:231:34)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:126:43)\n at processTicksAndRejections (native:7:39)","msg":"Error in tool:scoped_echo: Insufficient permissions."}
|
|
2
|
+
{"level":50,"time":1776994404869,"env":"testing","version":"0.6.15","pid":90768,"requestId":"SM09A-GLQJP","timestamp":"2026-04-24T01:33:24.868Z","operation":"httpErrorHandler","critical":false,"errorCode":-32006,"originalErrorType":"McpError","finalErrorType":"McpError","path":"/mcp","method":"POST","errorData":{"path":"/mcp","method":"POST","requestId":"SM09A-GLQJP","timestamp":"2026-04-24T01:33:24.868Z","operation":"httpErrorHandler","originalErrorName":"McpError","originalMessage":"Missing or invalid Authorization header. Bearer scheme required.","originalStack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at unauthorized (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:86:61)\n at authMiddleware (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/authMiddleware.js:64:19)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpTransport.js:119:22)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at cors2 (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/middleware/cors/index.js:82:11)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:168:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpErrorHandler.js:59:39)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:26:25)\n at processTicksAndRejections (native:7:39)","msg":"Error in httpTransport: Missing or invalid Authorization header. Bearer scheme required."}
|
|
3
|
+
{"level":50,"time":1776994404882,"env":"testing","version":"0.6.15","pid":90768,"requestId":"NWSZB-RSSE7","timestamp":"2026-04-24T01:33:24.882Z","operation":"httpErrorHandler","critical":false,"errorCode":-32006,"originalErrorType":"McpError","finalErrorType":"McpError","path":"/mcp","method":"POST","errorData":{"path":"/mcp","method":"POST","requestId":"NWSZB-RSSE7","timestamp":"2026-04-24T01:33:24.882Z","operation":"httpErrorHandler","originalErrorName":"McpError","originalMessage":"Token has expired.","originalStack":"McpError: Token has expired.\n at unauthorized (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:86:61)\n at handleJoseVerifyError (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/lib/claimParser.js:56:11)\n at verify (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/strategies/jwtStrategy.js:91:13)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Token has expired.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:168:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpErrorHandler.js:59:39)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:26:25)\n at processTicksAndRejections (native:7:39)","msg":"Error in httpTransport: Token has expired."}
|
|
4
|
+
{"level":50,"time":1776994404886,"env":"testing","version":"0.6.15","pid":90768,"requestId":"U3CD0-HCUAL","timestamp":"2026-04-24T01:33:24.886Z","operation":"httpErrorHandler","critical":false,"errorCode":-32006,"originalErrorType":"McpError","finalErrorType":"McpError","path":"/mcp","method":"GET","errorData":{"path":"/mcp","method":"GET","requestId":"U3CD0-HCUAL","timestamp":"2026-04-24T01:33:24.886Z","operation":"httpErrorHandler","originalErrorName":"McpError","originalMessage":"Missing or invalid Authorization header. Bearer scheme required.","originalStack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at unauthorized (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:86:61)\n at authMiddleware (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/authMiddleware.js:64:19)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpTransport.js:119:22)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at cors2 (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/middleware/cors/index.js:82:11)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:168:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpErrorHandler.js:59:39)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:26:25)\n at processTicksAndRejections (native:7:39)","msg":"Error in httpTransport: Missing or invalid Authorization header. Bearer scheme required."}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cyanheads/mcp-ts-core",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.15",
|
|
4
4
|
"mcpName": "io.github.cyanheads/mcp-ts-core",
|
|
5
5
|
"description": "Agent-native TypeScript framework for building MCP servers. Declarative definitions with auth, multi-backend storage, OpenTelemetry, and first-class support for Bun/Node/Cloudflare Workers.",
|
|
6
6
|
"main": "dist/core/index.js",
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"scripts/build-changelog.ts",
|
|
12
12
|
"scripts/build.ts",
|
|
13
13
|
"scripts/check-docs-sync.ts",
|
|
14
|
+
"scripts/check-skills-sync.ts",
|
|
14
15
|
"scripts/clean.ts",
|
|
15
16
|
"scripts/devcheck.ts",
|
|
16
17
|
"scripts/lint-mcp.ts",
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview Verifies that `skills/` (canonical) has been propagated to the
|
|
4
|
+
* local mirrors `.agents/skills/` and `.claude/skills/`. The maintenance skill
|
|
5
|
+
* updates `skills/` for downstream servers; the mirrors are what local agent
|
|
6
|
+
* toolchains actually read, and silent drift means agents run on stale guidance.
|
|
7
|
+
*
|
|
8
|
+
* Propagation is one-way (`skills/` → mirrors), so only missing or
|
|
9
|
+
* content-drifted files are reported. Files that exist *only* in a mirror are
|
|
10
|
+
* typically unrelated skills (globally installed, other sources) and are left
|
|
11
|
+
* alone.
|
|
12
|
+
*
|
|
13
|
+
* Behavior:
|
|
14
|
+
* • In sync → pass
|
|
15
|
+
* • Mirrors missing entirely → skip (no mirrors to sync)
|
|
16
|
+
* • Drift (missing or changed files) → exit 1 with details (devcheck demotes to warning)
|
|
17
|
+
*
|
|
18
|
+
* Ignore specific skills or files via `devcheck.config.json`:
|
|
19
|
+
*
|
|
20
|
+
* {
|
|
21
|
+
* "skillsSync": {
|
|
22
|
+
* "ignore": ["some-skill", "other-skill/SKILL.md"]
|
|
23
|
+
* }
|
|
24
|
+
* }
|
|
25
|
+
*
|
|
26
|
+
* Patterns match relative paths under `skills/`. A bare name like `add-tool`
|
|
27
|
+
* ignores the whole directory; `add-tool/SKILL.md` ignores a single file.
|
|
28
|
+
* `.DS_Store` and other OS cruft are ignored by default.
|
|
29
|
+
*
|
|
30
|
+
* Runs as a devcheck step and standalone: `bun run scripts/check-skills-sync.ts`.
|
|
31
|
+
*
|
|
32
|
+
* @module scripts/check-skills-sync
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
import { existsSync, readdirSync, readFileSync } from 'node:fs';
|
|
36
|
+
import { relative, resolve, sep } from 'node:path';
|
|
37
|
+
import process from 'node:process';
|
|
38
|
+
|
|
39
|
+
const ROOT = resolve('.');
|
|
40
|
+
const SKILLS_DIR = resolve(ROOT, 'skills');
|
|
41
|
+
const MIRRORS: { label: string; path: string }[] = [
|
|
42
|
+
{ label: '.agents/skills', path: resolve(ROOT, '.agents/skills') },
|
|
43
|
+
{ label: '.claude/skills', path: resolve(ROOT, '.claude/skills') },
|
|
44
|
+
];
|
|
45
|
+
|
|
46
|
+
interface DevcheckConfig {
|
|
47
|
+
skillsSync?: { ignore?: string[] };
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** OS/editor noise we never want to flag as drift. */
|
|
51
|
+
const DEFAULT_IGNORES = ['.DS_Store', 'Thumbs.db'];
|
|
52
|
+
|
|
53
|
+
function loadIgnorePatterns(): string[] {
|
|
54
|
+
try {
|
|
55
|
+
const cfg = JSON.parse(
|
|
56
|
+
readFileSync(resolve(ROOT, 'devcheck.config.json'), 'utf-8'),
|
|
57
|
+
) as DevcheckConfig;
|
|
58
|
+
return [...DEFAULT_IGNORES, ...(cfg.skillsSync?.ignore ?? [])];
|
|
59
|
+
} catch {
|
|
60
|
+
return [...DEFAULT_IGNORES];
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function isIgnored(relPath: string, patterns: string[]): boolean {
|
|
65
|
+
const basename = relPath.split('/').pop() ?? relPath;
|
|
66
|
+
return patterns.some((p) => p === relPath || p === basename || relPath.startsWith(`${p}/`));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function walkFiles(root: string): string[] {
|
|
70
|
+
const files: string[] = [];
|
|
71
|
+
const walk = (dir: string) => {
|
|
72
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
73
|
+
const full = resolve(dir, entry.name);
|
|
74
|
+
if (entry.isDirectory()) walk(full);
|
|
75
|
+
else if (entry.isFile()) files.push(relative(root, full).split(sep).join('/'));
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
walk(root);
|
|
79
|
+
return files;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (!existsSync(SKILLS_DIR)) {
|
|
83
|
+
console.log('Skipped: no skills/ directory.');
|
|
84
|
+
process.exit(0);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const presentMirrors = MIRRORS.filter((m) => existsSync(m.path));
|
|
88
|
+
if (presentMirrors.length === 0) {
|
|
89
|
+
console.log('Skipped: no skill mirrors (.agents/skills, .claude/skills) present.');
|
|
90
|
+
process.exit(0);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const ignore = loadIgnorePatterns();
|
|
94
|
+
const canonical = walkFiles(SKILLS_DIR).filter((f) => !isIgnored(f, ignore));
|
|
95
|
+
|
|
96
|
+
const missing: Record<string, string[]> = {};
|
|
97
|
+
const drifted: Record<string, string[]> = {};
|
|
98
|
+
|
|
99
|
+
for (const mirror of presentMirrors) {
|
|
100
|
+
const missingHere: string[] = [];
|
|
101
|
+
const driftedHere: string[] = [];
|
|
102
|
+
for (const file of canonical) {
|
|
103
|
+
const mirrorFile = resolve(mirror.path, file);
|
|
104
|
+
if (!existsSync(mirrorFile)) {
|
|
105
|
+
missingHere.push(file);
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
const a = readFileSync(resolve(SKILLS_DIR, file), 'utf-8');
|
|
109
|
+
const b = readFileSync(mirrorFile, 'utf-8');
|
|
110
|
+
if (a !== b) driftedHere.push(file);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (missingHere.length) missing[mirror.label] = missingHere.sort();
|
|
114
|
+
if (driftedHere.length) drifted[mirror.label] = driftedHere.sort();
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const totals = {
|
|
118
|
+
missing: Object.values(missing).reduce((n, arr) => n + arr.length, 0),
|
|
119
|
+
drifted: Object.values(drifted).reduce((n, arr) => n + arr.length, 0),
|
|
120
|
+
};
|
|
121
|
+
const driftCount = totals.missing + totals.drifted;
|
|
122
|
+
|
|
123
|
+
if (driftCount === 0) {
|
|
124
|
+
console.log(`skills/ is in sync with ${presentMirrors.map((m) => m.label).join(' and ')}.`);
|
|
125
|
+
process.exit(0);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const lines: string[] = [];
|
|
129
|
+
lines.push(
|
|
130
|
+
`skills/ has drifted from ${presentMirrors.length > 1 ? 'mirrors' : 'its mirror'} ` +
|
|
131
|
+
`(${totals.missing} missing, ${totals.drifted} changed).`,
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
const renderSection = (title: string, groups: Record<string, string[]>) => {
|
|
135
|
+
for (const [label, files] of Object.entries(groups)) {
|
|
136
|
+
lines.push('');
|
|
137
|
+
lines.push(`${title} ${label}/:`);
|
|
138
|
+
for (const file of files) lines.push(` - ${file}`);
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
renderSection('Missing in', missing);
|
|
143
|
+
renderSection('Content differs in', drifted);
|
|
144
|
+
|
|
145
|
+
lines.push('');
|
|
146
|
+
lines.push('Fix: propagate skills/ to the mirror(s), or add entries to');
|
|
147
|
+
lines.push(' devcheck.config.json `skillsSync.ignore` to silence specific paths.');
|
|
148
|
+
|
|
149
|
+
console.log(lines.join('\n'));
|
|
150
|
+
process.exit(1);
|
package/scripts/devcheck.ts
CHANGED
|
@@ -239,6 +239,9 @@ interface DevcheckConfig {
|
|
|
239
239
|
outdated?: {
|
|
240
240
|
allowlist?: string[];
|
|
241
241
|
};
|
|
242
|
+
skillsSync?: {
|
|
243
|
+
ignore?: string[];
|
|
244
|
+
};
|
|
242
245
|
}
|
|
243
246
|
|
|
244
247
|
function loadDevcheckConfig(rootDir: string): DevcheckConfig {
|
|
@@ -421,6 +424,30 @@ const ALL_CHECKS: Check[] = [
|
|
|
421
424
|
tip: (c) =>
|
|
422
425
|
`Edit both files together, or run ${c.bold('cp CLAUDE.md AGENTS.md')} (or reverse) to resync.`,
|
|
423
426
|
},
|
|
427
|
+
{
|
|
428
|
+
name: 'Skills Sync',
|
|
429
|
+
flag: '--no-skills-sync',
|
|
430
|
+
canFix: false,
|
|
431
|
+
// Compares canonical skills/ against local mirrors (.agents/skills, .claude/skills).
|
|
432
|
+
// Skipped when skills/ or both mirrors are absent (non-mirrored projects).
|
|
433
|
+
// Drift is demoted to a warning via isSuccess — intentional ignores live in
|
|
434
|
+
// devcheck.config.json `skillsSync.ignore`.
|
|
435
|
+
getCommand: () => {
|
|
436
|
+
const hasSkills = existsSync(path.join(ROOT_DIR, 'skills'));
|
|
437
|
+
const hasMirrors =
|
|
438
|
+
existsSync(path.join(ROOT_DIR, '.agents/skills')) ||
|
|
439
|
+
existsSync(path.join(ROOT_DIR, '.claude/skills'));
|
|
440
|
+
if (!hasSkills || !hasMirrors) return null;
|
|
441
|
+
return ['bun', 'run', 'scripts/check-skills-sync.ts'];
|
|
442
|
+
},
|
|
443
|
+
isSuccess: (result) => {
|
|
444
|
+
if (result.exitCode === 0) return true;
|
|
445
|
+
const firstLine = result.stdout.split('\n')[0]?.trim() || 'Skills mirrors have drifted.';
|
|
446
|
+
return { success: true, warning: firstLine };
|
|
447
|
+
},
|
|
448
|
+
tip: (c) =>
|
|
449
|
+
`Propagate ${c.bold('skills/')} to ${c.bold('.agents/skills/')} and ${c.bold('.claude/skills/')}, or add entries to ${c.bold('devcheck.config.json')} ${c.bold('skillsSync.ignore')}.`,
|
|
450
|
+
},
|
|
424
451
|
{
|
|
425
452
|
name: 'Changelog Sync',
|
|
426
453
|
flag: '--no-changelog-sync',
|
|
@@ -19,6 +19,8 @@ metadata:
|
|
|
19
19
|
|
|
20
20
|
Prefer running after implementation is complete, but safe to re-run at any point — steps are idempotent.
|
|
21
21
|
|
|
22
|
+
**Companion:** pair with `security-pass` for a full pre-ship review — this skill polishes docs and metadata; `security-pass` audits handlers for MCP-specific security gaps.
|
|
23
|
+
|
|
22
24
|
## Prerequisites
|
|
23
25
|
|
|
24
26
|
- [ ] All tools/resources/prompts implemented and registered
|
|
@@ -13,6 +13,7 @@ metadata:
|
|
|
13
13
|
|
|
14
14
|
This skill runs **after** git wrapup. By the time it's invoked:
|
|
15
15
|
|
|
16
|
+
- Pre-wrapup verification is done (`field-test`, `security-pass`, `polish-docs-meta` as applicable)
|
|
16
17
|
- `package.json` version is bumped
|
|
17
18
|
- `changelog/<major.minor>.x/<version>.md` is authored
|
|
18
19
|
- `CHANGELOG.md` is regenerated
|
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: security-pass
|
|
3
|
+
description: >
|
|
4
|
+
Review an MCP server for common security gaps: LLM-facing surfaces as injection vector (tools, resources, prompts, descriptions), scope blast radius, destructive ops without consent, upstream auth shape, input sinks (URL / path / roots / shell / sampling / schema strictness / ReDoS), tenant isolation, leakage through errors and telemetry, unbounded resources, and HTTP-mode deployment surface. Use before a release, after a batch of handler changes, or when the user asks for a security review, audit, or hardening pass. Produces grouped findings and a numbered options list.
|
|
5
|
+
metadata:
|
|
6
|
+
author: cyanheads
|
|
7
|
+
version: "1.1"
|
|
8
|
+
audience: external
|
|
9
|
+
type: audit
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Context
|
|
13
|
+
|
|
14
|
+
An MCP server is a new attack surface with unique properties — tool output feeds back into the LLM's context, scopes gate what the model can do on the user's behalf, and per-request state must stay tenant-scoped. This skill walks a server through eight axes shaped around what the server builder actually controls. Framework-level concerns (transport, JSON-RPC parsing, auto-correlation, error classification) are out of scope — `mcp-ts-core` handles those.
|
|
15
|
+
|
|
16
|
+
**Read the code. Don't trust patterns from memory.**
|
|
17
|
+
|
|
18
|
+
## When to Use
|
|
19
|
+
|
|
20
|
+
- Before a release
|
|
21
|
+
- After adding or modifying a batch of handlers or services
|
|
22
|
+
- Periodically (quarterly-ish)
|
|
23
|
+
- User asks for a "security review", "audit", "hardening pass", or similar
|
|
24
|
+
|
|
25
|
+
## Inputs
|
|
26
|
+
|
|
27
|
+
Gather before starting. Ask if unclear:
|
|
28
|
+
|
|
29
|
+
1. **Scope** — whole server, specific module, or recent diff?
|
|
30
|
+
2. **Known concerns** — anything the user already suspects?
|
|
31
|
+
3. **Deployment context** — multi-tenant? public network? auth mode? (stdio / local-http / public-http behave differently)
|
|
32
|
+
4. **Severity floor** — report all findings, or skip medium/low?
|
|
33
|
+
|
|
34
|
+
## Steps
|
|
35
|
+
|
|
36
|
+
### 1. Build the map
|
|
37
|
+
|
|
38
|
+
Surface what you're auditing before diving in. Paths below assume the `mcp-ts-core` layout — adjust to your repo.
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
find src/mcp-server/tools/definitions -name "*.tool.ts" | sort
|
|
42
|
+
find src/mcp-server/resources/definitions -name "*.resource.ts" 2>/dev/null | sort
|
|
43
|
+
find src/mcp-server/prompts/definitions -name "*.prompt.ts" 2>/dev/null | sort
|
|
44
|
+
find src/services -maxdepth 1 -mindepth 1 -type d | sort
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Note: tool / resource / prompt counts, auth mode, storage provider, upstream APIs, which tools have `destructiveHint`, which handlers use `ctx.sample` or `ctx.elicit`, which services hold module-scope state, whether the server reads `roots`.
|
|
48
|
+
|
|
49
|
+
**If transport is streamable HTTP or SSE**, also capture:
|
|
50
|
+
|
|
51
|
+
- Bind address (`127.0.0.1` for local, or `0.0.0.0` / public interface?)
|
|
52
|
+
- Origin allowlist (DNS rebinding mitigation) — configured, or wildcard / missing?
|
|
53
|
+
- Session ID source (framework CSPRNG, or builder-supplied?) and binding to auth identity
|
|
54
|
+
- Any unauthenticated routes (`/healthz`, `/sse`, metadata endpoints) — do they leak tool lists or tenant hints?
|
|
55
|
+
- MCP Authorization spec: if implemented, PKCE enforced, token audience (`aud`) checked, resource indicators used
|
|
56
|
+
|
|
57
|
+
Use `TaskCreate` — one task per axis. Mark complete as you go.
|
|
58
|
+
|
|
59
|
+
**Run `fuzzTool` in parallel.** `@cyanheads/mcp-ts-core/testing/fuzz` catches crashes, memory leaks, and prototype pollution automatically on each tool — start it now so results are ready when you reach Axis 5.
|
|
60
|
+
|
|
61
|
+
### 2. Walk the eight axes
|
|
62
|
+
|
|
63
|
+
#### Axis 1 — LLM-facing surfaces as injection vector
|
|
64
|
+
|
|
65
|
+
Anything the server sends to the client that reaches the LLM's context is a potential injection surface: tool output, resource content, prompt text, and the metadata the LLM reads to decide what to call. Relayed upstream content (tickets, scraped text, emails, DB rows) can carry adversarial instructions even when your code is honest.
|
|
66
|
+
|
|
67
|
+
**Look in:**
|
|
68
|
+
|
|
69
|
+
- Every `*.tool.ts` — `output` schema + `format()`
|
|
70
|
+
- Every `*.resource.ts` — content returned from `resources/read`
|
|
71
|
+
- Every `*.prompt.ts` — templated message content
|
|
72
|
+
- Every definition file — `description`, `title`, `annotations`, and `inputSchema` field descriptions (templated from untrusted data?)
|
|
73
|
+
|
|
74
|
+
**Check:**
|
|
75
|
+
|
|
76
|
+
- Handlers that return raw upstream text / DB rows without structural framing?
|
|
77
|
+
- Does `format()` wrap untrusted content in delimiters (blockquote, fenced code, `<data>` tags)?
|
|
78
|
+
- Output schema distinguishes "data" fields from free-form text?
|
|
79
|
+
- Resource content (`resources/read`) framed the same way tool output is?
|
|
80
|
+
- Prompt templates interpolate untrusted data without escaping — treating tenant-controlled strings as trusted instructions?
|
|
81
|
+
- Tool / resource / prompt **descriptions** templated from runtime data? Static strings are safer; templated descriptions enable "tool poisoning" (adversarial metadata steering the LLM toward a dangerous tool).
|
|
82
|
+
- Descriptions mutated mid-session? Rug-pull surface: client approved the v1 description, server now advertises v2 behavior.
|
|
83
|
+
|
|
84
|
+
**Smell:** `return { body: await fetch(url).then(r => r.text()) }` rendered directly in `format()`. Or: `description: \`Look up ${tenant.customLabel}\`` where `customLabel` is tenant-supplied.
|
|
85
|
+
|
|
86
|
+
#### Axis 2 — Scope granularity
|
|
87
|
+
|
|
88
|
+
Every `auth: [...]` entry is a blast-radius dial.
|
|
89
|
+
|
|
90
|
+
**Look in:** every `*.tool.ts` — `auth:` array.
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
grep -rn "auth: \[" src/mcp-server/tools/definitions/
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**Check:**
|
|
97
|
+
|
|
98
|
+
- Tools with `['admin']`, `['*']`, or `[]`?
|
|
99
|
+
- A single scope covering two capabilities that should be separated (read vs write)?
|
|
100
|
+
- Read-only tools never require write scopes?
|
|
101
|
+
|
|
102
|
+
**Smell:** every tool shares the same scope string.
|
|
103
|
+
|
|
104
|
+
#### Axis 3 — Destructive ops without elicit
|
|
105
|
+
|
|
106
|
+
`ctx.elicit` moves consent off the LLM and onto the user. Destructive tools without it trust the LLM not to be tricked.
|
|
107
|
+
|
|
108
|
+
**Look in:** handlers with `destructiveHint: true` or side-effecting verbs in names (`delete_*`, `send_*`, `pay_*`, `publish_*`, `drop_*`).
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
grep -rn "destructiveHint" src/mcp-server/tools/definitions/
|
|
112
|
+
grep -rn "ctx.elicit" src/mcp-server/tools/definitions/
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**Check:**
|
|
116
|
+
|
|
117
|
+
- Each destructive handler calls `ctx.elicit` before the side effect?
|
|
118
|
+
- Fallback when client doesn't support elicit — refuses, not silently proceeds?
|
|
119
|
+
- Elicit **response** validated against a Zod schema before use? The returned payload is LLM-mediated, not user-direct — "user confirmed" does not mean "user authored these exact fields."
|
|
120
|
+
- Consent is scoped to the specific target (e.g., record ID rendered in the prompt), not a generic "proceed?"
|
|
121
|
+
|
|
122
|
+
**Smell:** `destructiveHint: true` file with no `ctx.elicit?.(...)` in it. Or: `const { confirmed } = await ctx.elicit(...)` without a schema — `confirmed` could be anything.
|
|
123
|
+
|
|
124
|
+
#### Axis 4 — Upstream auth shape
|
|
125
|
+
|
|
126
|
+
What credentials the server holds, and the blast radius if one leaks.
|
|
127
|
+
|
|
128
|
+
**Look in:** `src/services/*`, `src/config/server-config.ts`.
|
|
129
|
+
|
|
130
|
+
**Check:**
|
|
131
|
+
|
|
132
|
+
- Each upstream API key scoped to minimum required? (No admin keys for read workflows.)
|
|
133
|
+
- Services re-mint downstream tokens with correct `aud`, or passthrough the caller's?
|
|
134
|
+
- Server holds OAuth for N services × M tenants — what does one-tenant compromise expose?
|
|
135
|
+
- Per-tenant rate limits on upstream calls?
|
|
136
|
+
|
|
137
|
+
**Smell:** one global `API_KEY` used across all tenants + retry loop with no upper bound.
|
|
138
|
+
|
|
139
|
+
#### Axis 5 — Input sinks
|
|
140
|
+
|
|
141
|
+
LLM-supplied inputs feel internal but aren't. Classic sinks apply, amplified. Sampling responses and roots-derived paths are MCP-specific sinks that look internal but carry LLM/client trust.
|
|
142
|
+
|
|
143
|
+
**Look in:** all handlers.
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
# URL sinks — SSRF
|
|
147
|
+
grep -rn "z.string().url()" src/
|
|
148
|
+
|
|
149
|
+
# Path sinks — traversal
|
|
150
|
+
grep -rn "readFile\|writeFile\|readdirSync\|createReadStream\|statSync" src/
|
|
151
|
+
|
|
152
|
+
# Shell sinks — command injection
|
|
153
|
+
grep -rnE "\b(exec|spawn|execSync|spawnSync)\b" src/
|
|
154
|
+
|
|
155
|
+
# Merges — prototype pollution
|
|
156
|
+
grep -rn "Object.assign\b\|structuredClone" src/
|
|
157
|
+
|
|
158
|
+
# Sampling — LLM-generated content flowing back into server logic
|
|
159
|
+
grep -rn "ctx.sample\|sampling/createMessage" src/
|
|
160
|
+
|
|
161
|
+
# Roots — client-shared filesystem
|
|
162
|
+
grep -rn "roots/list\|ctx.roots" src/
|
|
163
|
+
|
|
164
|
+
# Schema laxity — fields sneaking past validation
|
|
165
|
+
grep -rn "\.passthrough()\|\.catchall(" src/mcp-server/
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
**Check:**
|
|
169
|
+
|
|
170
|
+
- URL-taking tools block private IPs, `file://`, `ftp://`, `localhost`, DNS rebind?
|
|
171
|
+
- Path-taking tools canonicalize (`path.resolve` + assert `startsWith(root + sep)`)?
|
|
172
|
+
- Roots-derived paths: resolved result stays within *one* declared root (iterate and assert), not assumed-safe because "the client said so"?
|
|
173
|
+
- Shell-using tools use an allowlist (never string-concat)?
|
|
174
|
+
- Regex / glob / filter inputs bounded (length cap, complexity limits, execution timeout) — ReDoS-safe?
|
|
175
|
+
- User-JSON merges reject `__proto__`, `constructor`, `prototype` keys?
|
|
176
|
+
- **Input schemas `.strict()`** — unknown fields rejected, not silently passed to downstream code that destructures with `...rest`?
|
|
177
|
+
- **Output schemas without `.passthrough()` / `.catchall()`** — no accidental exfiltration of fields your schema didn't declare?
|
|
178
|
+
- Sampling responses (`ctx.sample` result) treated as untrusted input — schema-validated before reaching any other sink, never concatenated into prompts, shells, or queries?
|
|
179
|
+
|
|
180
|
+
**Smell:** `z.string().url()` with no allowlist; `readFile(input.path)` with no canonicalization; `await ctx.sample(...)` result interpolated into a shell, SQL, or URL.
|
|
181
|
+
|
|
182
|
+
#### Axis 6 — Tenant isolation
|
|
183
|
+
|
|
184
|
+
`ctx.state` is tenant-scoped. Module-scope state is not.
|
|
185
|
+
|
|
186
|
+
**Look in:** `src/services/*`.
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
grep -rnE "^(const|let) .* = new (Map|Set|WeakMap|Array)" src/services/
|
|
190
|
+
grep -rn "^let " src/services/
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
**Check:**
|
|
194
|
+
|
|
195
|
+
- Module-scope `Map` / `Set` / cache near tenant-handling code?
|
|
196
|
+
- Upstream connections pooled per-tenant or shared?
|
|
197
|
+
- Any code path uses the global `logger` while carrying per-tenant data (bypassing auto-correlated `ctx.log`)?
|
|
198
|
+
- Could tenant B, served after tenant A, read tenant A's cached data?
|
|
199
|
+
|
|
200
|
+
**Smell:** service file with top-level `const cache = new Map()`.
|
|
201
|
+
|
|
202
|
+
#### Axis 7 — Leakage back
|
|
203
|
+
|
|
204
|
+
What accidentally reaches the LLM, user, or observability sinks.
|
|
205
|
+
|
|
206
|
+
**Look in:** `throw new McpError(...)` sites, `McpError.data` fields, output schemas, and every logging / telemetry surface — not just `ctx.log`.
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
grep -rn "new McpError" src/
|
|
210
|
+
grep -rnE "\b(ctx\.log|console\.(log|info|warn|error|debug)|logger\.)" src/
|
|
211
|
+
grep -rnE "(Sentry\.|captureException|setTag|setContext|addBreadcrumb)" src/
|
|
212
|
+
grep -rnE "(setAttribute|setAttributes|span\.)" src/ # OpenTelemetry
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
**Check:**
|
|
216
|
+
|
|
217
|
+
- Error `data` fields carry upstream response bodies, auth headers, stack traces?
|
|
218
|
+
- Output schemas include token prefixes, internal IDs, session identifiers?
|
|
219
|
+
- `format()` renders fields that shouldn't leave the server?
|
|
220
|
+
- `ctx.log.info(msg, body)` where `body` is the raw request (may contain secrets)?
|
|
221
|
+
- `console.*` calls near auth / token / request-body handling — bypasses structured redaction?
|
|
222
|
+
- OpenTelemetry span attributes / Sentry breadcrumbs carry tokens, PII, or full request bodies?
|
|
223
|
+
- Secret / token / HMAC comparisons use `===` or `==` instead of constant-time (`timingSafeEqual` / `crypto.timingSafeEqual`) — leaks length and prefix via timing?
|
|
224
|
+
|
|
225
|
+
**Smell:** `throw new McpError(code, upstream.message, { raw: upstream.body })`. Or: `if (apiKey === expected)` on a request-auth path.
|
|
226
|
+
|
|
227
|
+
#### Axis 8 — Resource bounds
|
|
228
|
+
|
|
229
|
+
Unbounded = DoS of self, upstream, or the LLM's context window (billing-DoS is real).
|
|
230
|
+
|
|
231
|
+
**Look in:** handlers with loops, pagination, retries, or inputs that feed `JSON.parse` / schema validation.
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
grep -rnE "while\s*\(|for\s*\(.*of" src/mcp-server/tools/definitions/
|
|
235
|
+
grep -rn "cursor\|nextPage\|paginate" src/
|
|
236
|
+
grep -rn "JSON.parse\b" src/
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
**Check:**
|
|
240
|
+
|
|
241
|
+
- Pagination loops have a total-items cap?
|
|
242
|
+
- Retry logic has max attempts + exponential backoff?
|
|
243
|
+
- Output size proportional to input — is there a ceiling?
|
|
244
|
+
- Tools callable in a loop fail-fast on degenerate input (empty string, `0`, `null`)?
|
|
245
|
+
- `JSON.parse` / Zod `.parse()` inputs have a size + nesting-depth limit applied before parse?
|
|
246
|
+
- **Per-tenant per-tool** call rate limit (a single tenant looping `delete_record` 10k/sec hits you before it hits upstream)?
|
|
247
|
+
- Concurrency cap on long-running tools so one tenant can't starve the event loop?
|
|
248
|
+
|
|
249
|
+
**Smell:** `while (cursor) { results.push(...); cursor = next; }` with no max count. Or: `JSON.parse(await req.text())` with no `Content-Length` check upstream.
|
|
250
|
+
|
|
251
|
+
### 3. Quick sanity pass
|
|
252
|
+
|
|
253
|
+
Fast, sometimes high-leverage. Outside the eight axes.
|
|
254
|
+
|
|
255
|
+
- `bun audit` — any direct high/critical?
|
|
256
|
+
- `package.json` — `postinstall` / lifecycle scripts on added deps?
|
|
257
|
+
- New deps have npm provenance? `npm view <pkg> --json | jq .dist.attestations` — missing attestation on a security-critical dep is a yellow flag
|
|
258
|
+
- `.env.example` — placeholder values only, never real?
|
|
259
|
+
- Server-specific `ConfigSchema` — fails loudly on missing required keys (not silent defaults)?
|
|
260
|
+
- Any `process.env.*` reads outside the config parser (bypasses validation)?
|
|
261
|
+
- Collect `fuzzTool` results from Step 1 — triage crashes / leaks as Axis 5 / Axis 8 findings.
|
|
262
|
+
|
|
263
|
+
### 4. Report
|
|
264
|
+
|
|
265
|
+
Three sections. Summary → findings → numbered options.
|
|
266
|
+
|
|
267
|
+
#### Summary (1 paragraph)
|
|
268
|
+
|
|
269
|
+
Definitions reviewed, axes covered, count by severity, the single most important finding.
|
|
270
|
+
|
|
271
|
+
#### Findings
|
|
272
|
+
|
|
273
|
+
Group by severity. Each 3–5 lines.
|
|
274
|
+
|
|
275
|
+
| Severity | Meaning |
|
|
276
|
+
|:---------|:--------|
|
|
277
|
+
| **critical** | Exploitable now: auth bypass, exfiltration, arbitrary code/file/network access |
|
|
278
|
+
| **high** | Structural gap with clear attacker benefit even without immediate PoC (destructive op without elicit, admin scope on read tool, SSRF-capable URL input) |
|
|
279
|
+
| **medium** | Defense-in-depth gap weakening a boundary (missing per-tenant rate limit, error carries upstream response) |
|
|
280
|
+
| **low** | Hardening / polish (tighter output schema, narrower error data, minor comment) |
|
|
281
|
+
|
|
282
|
+
Format:
|
|
283
|
+
|
|
284
|
+
```
|
|
285
|
+
**<file_or_tool> — Axis <N> — <critical|high|medium|low>**
|
|
286
|
+
Issue: <one line: what's wrong>
|
|
287
|
+
Impact: <one line: what can go wrong>
|
|
288
|
+
Fix: <one line: the change>
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
#### Options
|
|
292
|
+
|
|
293
|
+
Numbered, cherry-pickable.
|
|
294
|
+
|
|
295
|
+
```
|
|
296
|
+
1. Add SSRF guard to `fetch_url.tool.ts` — block private IPs + non-http schemes (critical, #1)
|
|
297
|
+
2. Gate `delete_record.tool.ts` behind `ctx.elicit` (high, #3)
|
|
298
|
+
3. Split `admin` into `record:read` + `record:write` across 4 tools (high, #4)
|
|
299
|
+
4. Move `const tokenCache = new Map()` out of module scope in `auth-service.ts` (medium, #7)
|
|
300
|
+
5. Cap pagination loop in `list_all_tickets` at 1000 items (medium, #9)
|
|
301
|
+
6. Strip upstream response body from `McpError.data` in `sync-service.ts` (low, #11)
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
End with:
|
|
305
|
+
|
|
306
|
+
> Pick by number (e.g. "do 1, 3, 5" or "expand on 2").
|
|
307
|
+
|
|
308
|
+
## Checklist
|
|
309
|
+
|
|
310
|
+
- [ ] Scope confirmed (whole server / module / diff)
|
|
311
|
+
- [ ] Map built: tools / resources / prompts, services, upstream APIs, auth mode, sampling / elicit / roots usage
|
|
312
|
+
- [ ] Deployment surface reviewed (if HTTP): bind address, Origin allowlist, session ID, unauth routes, auth-spec compliance
|
|
313
|
+
- [ ] `fuzzTool` started in parallel
|
|
314
|
+
- [ ] Axis 1 — LLM-facing surfaces (tool / resource / prompt output + descriptions) framed and static
|
|
315
|
+
- [ ] Axis 2 — scope granularity audited
|
|
316
|
+
- [ ] Axis 3 — destructive ops verified to elicit, elicit response schema-validated
|
|
317
|
+
- [ ] Axis 4 — upstream auth + token passthrough reviewed
|
|
318
|
+
- [ ] Axis 5 — input sinks (URL / path / roots / shell / proto / sampling / schema strictness / ReDoS) checked
|
|
319
|
+
- [ ] Axis 6 — tenant isolation: module-scope state swept
|
|
320
|
+
- [ ] Axis 7 — leakage back: errors / outputs / `ctx.log` / `console.*` / telemetry / constant-time comparisons
|
|
321
|
+
- [ ] Axis 8 — resource bounds on loops / retries / pagination / parse size+depth / per-tenant rate
|
|
322
|
+
- [ ] Quick sanity pass: `bun audit`, lifecycle scripts, `.env.example`, config validation, new-dep provenance
|
|
323
|
+
- [ ] Report: summary → grouped findings → numbered options
|
package/skills/setup/SKILL.md
CHANGED
|
@@ -142,8 +142,9 @@ The included skills form a rough progression — not a rigid sequence, but the t
|
|
|
142
142
|
2. **`add-tool`** / **`add-app-tool`** / **`add-resource`** / **`add-prompt`** / **`add-service`** — scaffold each piece as you go
|
|
143
143
|
3. **`add-test`** — pair tests with each definition (or retrofit later)
|
|
144
144
|
4. **`field-test`** — exercise the built surface with real and adversarial inputs; produces a report of issues and pain points
|
|
145
|
-
5. **`
|
|
146
|
-
6. **`
|
|
145
|
+
5. **`security-pass`** — audit handlers for MCP-specific security gaps: output injection, scope blast radius, input sinks, tenant isolation
|
|
146
|
+
6. **`polish-docs-meta`** — finalize README, metadata, and agent protocol before shipping
|
|
147
|
+
7. **`maintenance`** — after `bun update --latest`, investigate upstream changelogs and re-sync skills
|
|
147
148
|
|
|
148
149
|
Skip or reorder as the project calls for it. The agent protocol's "What's Next?" section is the authoritative map once the first session is over.
|
|
149
150
|
|
package/templates/AGENTS.md
CHANGED
|
@@ -29,8 +29,9 @@ When the user asks what to do next, what's left, or needs direction, suggest rel
|
|
|
29
29
|
5. **Add tests** — scaffold tests for existing definitions using the `add-test` skill
|
|
30
30
|
6. **Field-test definitions** — exercise tools/resources/prompts with real inputs using the `field-test` skill, get a report of issues and pain points
|
|
31
31
|
7. **Run `devcheck`** — lint, format, typecheck, and security audit
|
|
32
|
-
8. **Run the `
|
|
33
|
-
9. **Run the `
|
|
32
|
+
8. **Run the `security-pass` skill** — audit handlers for MCP-specific security gaps: output injection, scope blast radius, input sinks, tenant isolation
|
|
33
|
+
9. **Run the `polish-docs-meta` skill** — finalize README, CHANGELOG, metadata, and agent protocol for shipping
|
|
34
|
+
10. **Run the `maintenance` skill** — investigate changelogs, adopt upstream changes, and sync skills after `bun update --latest`
|
|
34
35
|
|
|
35
36
|
Tailor suggestions to what's actually missing or stale — don't recite the full list every time.
|
|
36
37
|
|
|
@@ -237,6 +238,7 @@ Available skills:
|
|
|
237
238
|
| `add-service` | Scaffold a new service integration |
|
|
238
239
|
| `add-test` | Scaffold test file for a tool, resource, or service |
|
|
239
240
|
| `field-test` | Exercise tools/resources/prompts with real inputs, verify behavior, report issues |
|
|
241
|
+
| `security-pass` | Audit server for MCP-flavored security gaps: output injection, scope blast radius, input sinks, tenant isolation |
|
|
240
242
|
| `devcheck` | Lint, format, typecheck, audit |
|
|
241
243
|
| `polish-docs-meta` | Finalize docs, README, metadata, and agent protocol for shipping |
|
|
242
244
|
| `maintenance` | Investigate changelogs, adopt upstream changes, sync skills to agent dirs |
|
package/templates/CLAUDE.md
CHANGED
|
@@ -29,8 +29,9 @@ When the user asks what to do next, what's left, or needs direction, suggest rel
|
|
|
29
29
|
5. **Add tests** — scaffold tests for existing definitions using the `add-test` skill
|
|
30
30
|
6. **Field-test definitions** — exercise tools/resources/prompts with real inputs using the `field-test` skill, get a report of issues and pain points
|
|
31
31
|
7. **Run `devcheck`** — lint, format, typecheck, and security audit
|
|
32
|
-
8. **Run the `
|
|
33
|
-
9. **Run the `
|
|
32
|
+
8. **Run the `security-pass` skill** — audit handlers for MCP-specific security gaps: output injection, scope blast radius, input sinks, tenant isolation
|
|
33
|
+
9. **Run the `polish-docs-meta` skill** — finalize README, CHANGELOG, metadata, and agent protocol for shipping
|
|
34
|
+
10. **Run the `maintenance` skill** — investigate changelogs, adopt upstream changes, and sync skills after `bun update --latest`
|
|
34
35
|
|
|
35
36
|
Tailor suggestions to what's actually missing or stale — don't recite the full list every time.
|
|
36
37
|
|
|
@@ -237,6 +238,7 @@ Available skills:
|
|
|
237
238
|
| `add-service` | Scaffold a new service integration |
|
|
238
239
|
| `add-test` | Scaffold test file for a tool, resource, or service |
|
|
239
240
|
| `field-test` | Exercise tools/resources/prompts with real inputs, verify behavior, report issues |
|
|
241
|
+
| `security-pass` | Audit server for MCP-flavored security gaps: output injection, scope blast radius, input sinks, tenant isolation |
|
|
240
242
|
| `devcheck` | Lint, format, typecheck, audit |
|
|
241
243
|
| `polish-docs-meta` | Finalize docs, README, metadata, and agent protocol for shipping |
|
|
242
244
|
| `maintenance` | Investigate changelogs, adopt upstream changes, sync skills to agent dirs |
|