@cyanheads/mcp-ts-core 0.3.4 → 0.3.5
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/README.md +6 -8
- package/biome.json +1 -1
- package/package.json +14 -14
- package/skills/add-test/SKILL.md +2 -2
- package/skills/design-mcp-server/SKILL.md +10 -19
- package/templates/AGENTS.md +2 -1
- package/templates/CLAUDE.md +3 -2
package/README.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
<h1>@cyanheads/mcp-ts-core</h1>
|
|
3
|
-
<p><b>Agent-native TypeScript framework for building MCP servers. Build tools, not infrastructure. Declarative definitions with auth, multi-backend storage, OpenTelemetry, and first-class support for Node
|
|
3
|
+
<p><b>Agent-native TypeScript framework for building MCP servers. Build tools, not infrastructure. Declarative definitions with auth, multi-backend storage, OpenTelemetry, and first-class support for Bun/Node/Cloudflare Workers.</b></p>
|
|
4
4
|
</div>
|
|
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
|
|
|
@@ -243,18 +243,16 @@ Also exports `fuzzResource`, `fuzzPrompt`, `zodToArbitrary`, and `ADVERSARIAL_ST
|
|
|
243
243
|
|
|
244
244
|
## Documentation
|
|
245
245
|
|
|
246
|
-
- **[CLAUDE.md](CLAUDE.md)** —
|
|
246
|
+
- **[CLAUDE.md](CLAUDE.md)** — Framework reference: exports catalog, patterns, Context interface, error codes, auth, config, testing. Ships in the npm package.
|
|
247
247
|
- **[CHANGELOG.md](CHANGELOG.md)** — Version history
|
|
248
248
|
|
|
249
249
|
## Development
|
|
250
250
|
|
|
251
251
|
```bash
|
|
252
|
-
bun run
|
|
252
|
+
bun run rebuild # tsc && tsc-alias
|
|
253
253
|
bun run devcheck # lint, format, typecheck, security
|
|
254
254
|
bun run lint:mcp # validate MCP definitions against spec
|
|
255
|
-
bun run test # vitest
|
|
256
|
-
bun run dev:stdio # dev mode (stdio)
|
|
257
|
-
bun run dev:http # dev mode (HTTP)
|
|
255
|
+
bun run test:all # vitest
|
|
258
256
|
```
|
|
259
257
|
|
|
260
258
|
## Contributing
|
|
@@ -263,7 +261,7 @@ Issues and pull requests welcome. Run checks before submitting:
|
|
|
263
261
|
|
|
264
262
|
```bash
|
|
265
263
|
bun run devcheck
|
|
266
|
-
bun run test
|
|
264
|
+
bun run test:all
|
|
267
265
|
```
|
|
268
266
|
|
|
269
267
|
## License
|
package/biome.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cyanheads/mcp-ts-core",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.5",
|
|
4
4
|
"mcpName": "io.github.cyanheads/mcp-ts-core",
|
|
5
5
|
"description": "Agent-native TypeScript framework for building MCP servers. Build tools, not infrastructure. Declarative definitions with auth, multi-backend storage, OpenTelemetry, and first-class support for Node.js and Cloudflare Workers.",
|
|
6
6
|
"main": "dist/core/index.js",
|
|
@@ -141,10 +141,10 @@
|
|
|
141
141
|
"publish-mcp": "bunx mcp-publisher publish"
|
|
142
142
|
},
|
|
143
143
|
"resolutions": {
|
|
144
|
-
"@hono/node-server": "1.19.
|
|
144
|
+
"@hono/node-server": "1.19.14",
|
|
145
145
|
"chrono-node": "2.9.0",
|
|
146
146
|
"diff": "8.0.4",
|
|
147
|
-
"dotenv": "17.4.
|
|
147
|
+
"dotenv": "17.4.2",
|
|
148
148
|
"brace-expansion": "1.1.13",
|
|
149
149
|
"flatted": "3.4.2",
|
|
150
150
|
"handlebars": "4.7.9",
|
|
@@ -156,8 +156,8 @@
|
|
|
156
156
|
"zod": "4.3.6"
|
|
157
157
|
},
|
|
158
158
|
"devDependencies": {
|
|
159
|
-
"@biomejs/biome": "2.4.
|
|
160
|
-
"@cloudflare/workers-types": "^4.
|
|
159
|
+
"@biomejs/biome": "2.4.11",
|
|
160
|
+
"@cloudflare/workers-types": "^4.20260413.1",
|
|
161
161
|
"@hono/otel": "^1.1.1",
|
|
162
162
|
"@opentelemetry/instrumentation-http": "^0.214.0",
|
|
163
163
|
"@opentelemetry/exporter-metrics-otlp-http": "^0.214.0",
|
|
@@ -168,17 +168,17 @@
|
|
|
168
168
|
"@opentelemetry/sdk-node": "^0.214.0",
|
|
169
169
|
"@opentelemetry/sdk-trace-node": "^2.6.1",
|
|
170
170
|
"@opentelemetry/semantic-conventions": "^1.40.0",
|
|
171
|
-
"@supabase/supabase-js": "^2.
|
|
172
|
-
"@types/bun": "^1.3.
|
|
171
|
+
"@supabase/supabase-js": "^2.103.0",
|
|
172
|
+
"@types/bun": "^1.3.12",
|
|
173
173
|
"@types/diff": "^8.0.0",
|
|
174
174
|
"@types/js-yaml": "^4.0.9",
|
|
175
|
-
"@types/node": "^25.
|
|
175
|
+
"@types/node": "^25.6.0",
|
|
176
176
|
"@types/papaparse": "^5.5.2",
|
|
177
177
|
"@types/sanitize-html": "^2.16.1",
|
|
178
178
|
"@types/validator": "^13.15.10",
|
|
179
|
-
"@vitest/coverage-istanbul": "4.1.
|
|
180
|
-
"@vitest/ui": "4.1.
|
|
181
|
-
"bun-types": "^1.3.
|
|
179
|
+
"@vitest/coverage-istanbul": "4.1.4",
|
|
180
|
+
"@vitest/ui": "4.1.4",
|
|
181
|
+
"bun-types": "^1.3.12",
|
|
182
182
|
"chrono-node": "^2.9.0",
|
|
183
183
|
"clipboardy": "^5.3.1",
|
|
184
184
|
"depcheck": "^1.4.7",
|
|
@@ -196,12 +196,12 @@
|
|
|
196
196
|
"sanitize-html": "^2.17.2",
|
|
197
197
|
"repomix": "^1.13.1",
|
|
198
198
|
"tsc-alias": "^1.8.16",
|
|
199
|
-
"typedoc": "^0.28.
|
|
199
|
+
"typedoc": "^0.28.19",
|
|
200
200
|
"typescript": "^6.0.2",
|
|
201
|
-
"unpdf": "^1.
|
|
201
|
+
"unpdf": "^1.5.0",
|
|
202
202
|
"validator": "^13.15.35",
|
|
203
203
|
"vite": "8.0.8",
|
|
204
|
-
"vitest": "^4.1.
|
|
204
|
+
"vitest": "^4.1.4"
|
|
205
205
|
},
|
|
206
206
|
"keywords": [
|
|
207
207
|
"agent",
|
package/skills/add-test/SKILL.md
CHANGED
|
@@ -4,14 +4,14 @@ 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.3"
|
|
8
8
|
audience: external
|
|
9
9
|
type: reference
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
## Context
|
|
13
13
|
|
|
14
|
-
Tests use Vitest and `createMockContext` from `@cyanheads/mcp-ts-core/testing`.
|
|
14
|
+
Tests use Vitest and `createMockContext` from `@cyanheads/mcp-ts-core/testing`. If the repo already has tests, match the existing layout. If the repo has no existing tests, create a root `tests/` directory that mirrors the `src/` structure (e.g. `tests/mcp-server/tools/definitions/echo.tool.test.ts` for `src/mcp-server/tools/definitions/echo.tool.ts`).
|
|
15
15
|
|
|
16
16
|
For the full `createMockContext` API and testing patterns, read:
|
|
17
17
|
|
|
@@ -4,7 +4,7 @@ description: >
|
|
|
4
4
|
Design the tool surface, resources, and service layer for a new MCP server. Use when starting a new server, planning a major feature expansion, or when the user describes a domain/API they want to expose via MCP. Produces a design doc at docs/design.md that drives implementation.
|
|
5
5
|
metadata:
|
|
6
6
|
author: cyanheads
|
|
7
|
-
version: "2.
|
|
7
|
+
version: "2.2"
|
|
8
8
|
audience: external
|
|
9
9
|
type: workflow
|
|
10
10
|
---
|
|
@@ -117,9 +117,7 @@ const gitBranch = tool('git_branch', {
|
|
|
117
117
|
```ts
|
|
118
118
|
// Workflow tool — search + local filter pipeline, not a raw API proxy
|
|
119
119
|
const findEligibleStudies = tool('clinicaltrials_find_eligible_studies', {
|
|
120
|
-
description: 'Matches patient demographics and medical profile to eligible clinical trials. '
|
|
121
|
-
+ 'Filters by age, sex, conditions, location, and healthy volunteer status. '
|
|
122
|
-
+ 'Returns ranked list of matching studies with eligibility explanations.',
|
|
120
|
+
description: 'Matches patient demographics and medical profile to eligible clinical trials. Filters by age, sex, conditions, location, and healthy volunteer status. Returns ranked list of matching studies with eligibility explanations.',
|
|
123
121
|
// handler: listStudies() → filter by eligibility → rank by location proximity → slice
|
|
124
122
|
});
|
|
125
123
|
```
|
|
@@ -142,21 +140,20 @@ The description is the LLM's primary signal for tool selection. It must answer:
|
|
|
142
140
|
|
|
143
141
|
- **Be concrete about capability.** "Search for clinical trial studies using queries and filters" beats "Interact with studies."
|
|
144
142
|
- **Include operational guidance when it matters.** If the tool has prerequisites, constraints, or gotchas the LLM needs to know, say so in the description. Don't add boilerplate workflow hints when the tool is self-explanatory.
|
|
143
|
+
- **Don't leak implementation details.** Descriptions are for the consumer, not the author. Internal endpoint paths, API call counts, internal parameter name mappings, and routing logic don't belong — describe what the tool does and when to use it, not how it's wired up.
|
|
145
144
|
|
|
146
145
|
```ts
|
|
147
146
|
// Good — describes a prerequisite the LLM must know
|
|
148
|
-
description: 'Set the session working directory for all git operations. '
|
|
149
|
-
+ 'This allows subsequent git commands to omit the path parameter.'
|
|
147
|
+
description: 'Set the session working directory for all git operations. This allows subsequent git commands to omit the path parameter.'
|
|
150
148
|
|
|
151
149
|
// Good — self-explanatory, no workflow hints needed
|
|
152
150
|
description: 'Show the working tree status including staged, unstaged, and untracked files.'
|
|
153
151
|
|
|
154
152
|
// Good — warns about constraints
|
|
155
|
-
description: 'Fetches trial results data for completed studies. '
|
|
156
|
-
+ 'Only available for studies where hasResults is true.'
|
|
153
|
+
description: 'Fetches trial results data for completed studies. Only available for studies where hasResults is true.'
|
|
157
154
|
```
|
|
158
155
|
|
|
159
|
-
|
|
156
|
+
Descriptions should be as long as needed — concise but complete. Don't artificially truncate, and don't pad with filler.
|
|
160
157
|
|
|
161
158
|
#### Parameter descriptions
|
|
162
159
|
|
|
@@ -171,14 +168,11 @@ Every `.describe()` is prompt text the LLM reads. Parameters should convey: what
|
|
|
171
168
|
```ts
|
|
172
169
|
// Good — explains cost, recommends action, names the alternative
|
|
173
170
|
fields: z.array(z.string()).optional()
|
|
174
|
-
.describe('Specific fields to return (reduces payload size). '
|
|
175
|
-
+ 'STRONGLY RECOMMENDED — without this, the full study record (~70KB each) is returned. '
|
|
176
|
-
+ 'Use full data only when you need detailed eligibility criteria, locations, or results.'),
|
|
171
|
+
.describe('Specific fields to return (reduces payload size). Without this, the full study record (~70KB each) is returned. Use full data only when you need detailed eligibility criteria, locations, or results.'),
|
|
177
172
|
|
|
178
173
|
// Good — explains what the flag does AND how to override
|
|
179
174
|
autoExclude: z.boolean().default(true)
|
|
180
|
-
.describe('Automatically exclude lock files and generated files from diff output '
|
|
181
|
-
+ 'to reduce context bloat. Set to false if you need to inspect these files.'),
|
|
175
|
+
.describe('Automatically exclude lock files and generated files from diff output to reduce context bloat. Set to false if you need to inspect these files.'),
|
|
182
176
|
|
|
183
177
|
// Good — names the format and gives one example
|
|
184
178
|
nctIds: z.union([z.string(), z.array(z.string()).max(5)])
|
|
@@ -201,8 +195,7 @@ The output schema and `format` function control what the LLM reads back. Design
|
|
|
201
195
|
output: z.object({
|
|
202
196
|
diff: z.string().describe('Unified diff output.'),
|
|
203
197
|
excludedFiles: z.array(z.string()).optional()
|
|
204
|
-
.describe('Files automatically excluded from the diff (e.g., lock files). '
|
|
205
|
-
+ 'Call again with autoExclude=false to include them.'),
|
|
198
|
+
.describe('Files automatically excluded from the diff (e.g., lock files). Call again with autoExclude=false to include them.'),
|
|
206
199
|
}),
|
|
207
200
|
```
|
|
208
201
|
|
|
@@ -244,9 +237,7 @@ When a tool wraps a complex query language or filter system, provide a simple sh
|
|
|
244
237
|
```ts
|
|
245
238
|
// text_search handles the common case; query handles everything else
|
|
246
239
|
text_search: z.string().optional()
|
|
247
|
-
.describe('Convenience shortcut: full-text search across title and abstract. '
|
|
248
|
-
+ 'Equivalent to {"_or":[{"_text_any":{"title":"..."}},{"_text_any":{"abstract":"..."}}]}. '
|
|
249
|
-
+ 'For more control, use the query parameter directly.'),
|
|
240
|
+
.describe('Convenience shortcut: full-text search across title and abstract. For structured filters or field-specific matching, use the query parameter instead.'),
|
|
250
241
|
query: z.record(z.unknown()).optional()
|
|
251
242
|
.describe('Full query object for structured filters. Supports operators: _eq, _gt, _and, _or, ...'),
|
|
252
243
|
```
|
package/templates/AGENTS.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Agent Protocol
|
|
2
2
|
|
|
3
3
|
**Server:** {{PACKAGE_NAME}}
|
|
4
|
-
**Version:** 0.1.
|
|
4
|
+
**Version:** 0.1.1
|
|
5
5
|
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core)
|
|
6
6
|
|
|
7
7
|
> **Read the framework docs first:** `node_modules/@cyanheads/mcp-ts-core/CLAUDE.md` contains the full API reference — builders, Context, error codes, exports, patterns. This file covers server-specific conventions only.
|
|
@@ -224,6 +224,7 @@ Available skills:
|
|
|
224
224
|
| `setup` | Post-init project orientation |
|
|
225
225
|
| `design-mcp-server` | Design tool surface, resources, and services for a new server |
|
|
226
226
|
| `add-tool` | Scaffold a new tool definition |
|
|
227
|
+
| `add-app-tool` | Scaffold an MCP App tool + paired UI resource |
|
|
227
228
|
| `add-resource` | Scaffold a new resource definition |
|
|
228
229
|
| `add-prompt` | Scaffold a new prompt definition |
|
|
229
230
|
| `add-service` | Scaffold a new service integration |
|
package/templates/CLAUDE.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Agent Protocol
|
|
2
2
|
|
|
3
3
|
**Server:** {{PACKAGE_NAME}}
|
|
4
|
-
**Version:** 0.1.
|
|
4
|
+
**Version:** 0.1.1
|
|
5
5
|
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core)
|
|
6
6
|
|
|
7
7
|
> **Read the framework docs first:** `node_modules/@cyanheads/mcp-ts-core/CLAUDE.md` contains the full API reference — builders, Context, error codes, exports, patterns. This file covers server-specific conventions only.
|
|
@@ -25,7 +25,7 @@ When the user asks what to do next, what's left, or needs direction, suggest rel
|
|
|
25
25
|
|
|
26
26
|
1. **Re-run the `setup` skill** — ensures CLAUDE.md, skills, structure, and metadata are populated and up to date with the current codebase
|
|
27
27
|
2. **Run the `design-mcp-server` skill** — if the tool/resource surface hasn't been mapped yet, work through domain design
|
|
28
|
-
3. **Add tools/resources/prompts** — scaffold new definitions using the `add-tool`, `add-resource`, `add-prompt` skills
|
|
28
|
+
3. **Add tools/resources/prompts** — scaffold new definitions using the `add-tool`, `add-app-tool`, `add-resource`, `add-prompt` skills
|
|
29
29
|
4. **Add services** — scaffold domain service integrations using the `add-service` skill
|
|
30
30
|
5. **Add tests** — scaffold tests for existing definitions using the `add-test` skill
|
|
31
31
|
6. **Field-test definitions** — exercise tools/resources/prompts with real inputs using the `field-test` skill, get a report of issues and pain points
|
|
@@ -224,6 +224,7 @@ Available skills:
|
|
|
224
224
|
| `setup` | Post-init project orientation |
|
|
225
225
|
| `design-mcp-server` | Design tool surface, resources, and services for a new server |
|
|
226
226
|
| `add-tool` | Scaffold a new tool definition |
|
|
227
|
+
| `add-app-tool` | Scaffold an MCP App tool + paired UI resource |
|
|
227
228
|
| `add-resource` | Scaffold a new resource definition |
|
|
228
229
|
| `add-prompt` | Scaffold a new prompt definition |
|
|
229
230
|
| `add-service` | Scaffold a new service integration |
|