@cyanheads/mcp-ts-core 0.1.8 → 0.1.9
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 -2
- package/README.md +2 -2
- package/biome.json +1 -1
- package/package.json +1 -1
- package/scripts/tree.ts +1 -1
- package/skills/README.md +1 -1
- package/skills/add-export/SKILL.md +4 -0
- package/skills/add-provider/SKILL.md +4 -0
- package/skills/api-auth/SKILL.md +1 -0
- package/skills/api-utils/SKILL.md +1 -1
- package/skills/api-utils/references/formatting.md +3 -3
- package/skills/api-utils/references/parsing.md +1 -0
- package/skills/design-mcp-server/SKILL.md +1 -0
- package/skills/polish-docs-meta/SKILL.md +1 -0
- package/skills/polish-docs-meta/references/agent-protocol.md +1 -0
- package/skills/release/SKILL.md +2 -2
- package/skills/setup/SKILL.md +2 -2
- package/templates/AGENTS.md +1 -1
- package/templates/CLAUDE.md +1 -1
package/CLAUDE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Agent Protocol
|
|
2
2
|
|
|
3
|
-
**Package:** `@cyanheads/mcp-ts-core` · **Version:** 0.1.
|
|
3
|
+
**Package:** `@cyanheads/mcp-ts-core` · **Version:** 0.1.9
|
|
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.
|
|
@@ -128,7 +128,7 @@ interface ServerHandle {
|
|
|
128
128
|
|
|
129
129
|
## Server Structure
|
|
130
130
|
|
|
131
|
-
```
|
|
131
|
+
```text
|
|
132
132
|
src/
|
|
133
133
|
index.ts # createApp() entry point
|
|
134
134
|
worker.ts # createWorkerHandler() (if using Workers)
|
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
|
|
|
@@ -107,7 +107,7 @@ It also works on Cloudflare Workers with `createWorkerHandler()` — same defini
|
|
|
107
107
|
|
|
108
108
|
## Server structure
|
|
109
109
|
|
|
110
|
-
```
|
|
110
|
+
```text
|
|
111
111
|
my-mcp-server/
|
|
112
112
|
src/
|
|
113
113
|
index.ts # createApp() entry point
|
package/biome.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cyanheads/mcp-ts-core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
4
4
|
"mcpName": "io.github.cyanheads/mcp-ts-core",
|
|
5
5
|
"description": "TypeScript framework for building Model Context Protocol (MCP) servers. Declarative tool/resource/prompt definitions, pluggable auth, multi-backend storage, OpenTelemetry observability, and support for both local (stdio/HTTP) and edge (Cloudflare Workers) runtimes.",
|
|
6
6
|
"main": "dist/core/app.js",
|
package/scripts/tree.ts
CHANGED
|
@@ -241,7 +241,7 @@ function buildOutputContent(projectName: string, treeContent: string, maxDepth:
|
|
|
241
241
|
const timestamp = new Date().toISOString().replace(/T/, ' ').replace(/\..+/, '');
|
|
242
242
|
const header = `# ${projectName} - Directory Structure\n\nGenerated on: ${timestamp}\n`;
|
|
243
243
|
const depthInfo = maxDepth !== Infinity ? `\n_Depth limited to ${maxDepth} levels_\n\n` : '\n';
|
|
244
|
-
const treeBlock =
|
|
244
|
+
const treeBlock = `\`\`\`text\n${projectName}/\n${treeContent}\`\`\`\n`;
|
|
245
245
|
const footer = `\n_Note: This tree excludes files and directories matched by .gitignore and default patterns._\n`;
|
|
246
246
|
return header + depthInfo + treeBlock + footer;
|
|
247
247
|
}
|
package/skills/README.md
CHANGED
|
@@ -19,6 +19,7 @@ The build uses `tsconfig.build.json` (not `tsconfig.json`) with `rootDir: ./src`
|
|
|
19
19
|
|
|
20
20
|
1. **Create the entry point** source file under `src/` (e.g., `src/utils/new-util.ts`)
|
|
21
21
|
2. **Add the subpath** to `package.json` `exports`, mirroring the source path:
|
|
22
|
+
|
|
22
23
|
```jsonc
|
|
23
24
|
// source: src/utils/new-util.ts → dist: dist/utils/new-util.js
|
|
24
25
|
"./newutil": {
|
|
@@ -26,9 +27,11 @@ The build uses `tsconfig.build.json` (not `tsconfig.json`) with `rootDir: ./src`
|
|
|
26
27
|
"import": "./dist/utils/new-util.js"
|
|
27
28
|
}
|
|
28
29
|
```
|
|
30
|
+
|
|
29
31
|
3. **Update the exports catalog** in `CLAUDE.md` — add a row to the table
|
|
30
32
|
4. **Build** with `bun run build` to generate `dist/` output
|
|
31
33
|
5. **Verify the export** by inspecting the compiled output directly:
|
|
34
|
+
|
|
32
35
|
```bash
|
|
33
36
|
# Confirm the compiled file exists at the expected dist path
|
|
34
37
|
ls dist/utils/new-util.js
|
|
@@ -36,6 +39,7 @@ The build uses `tsconfig.build.json` (not `tsconfig.json`) with `rootDir: ./src`
|
|
|
36
39
|
# Confirm the declared exports resolve to real files
|
|
37
40
|
bun -e "import('./dist/utils/new-util.js').then(m => console.log(Object.keys(m)))"
|
|
38
41
|
```
|
|
42
|
+
|
|
39
43
|
6. **Run `bun run devcheck`** to verify
|
|
40
44
|
|
|
41
45
|
## Naming conventions
|
|
@@ -49,6 +49,7 @@ Provider file location and naming differ by domain:
|
|
|
49
49
|
2. **Create the provider file** following the file convention for its domain (see above).
|
|
50
50
|
3. **Implement the interface** — all methods must be implemented.
|
|
51
51
|
4. **Lazy-load dependencies** if Tier 3:
|
|
52
|
+
|
|
52
53
|
```typescript
|
|
53
54
|
let _client: SomeClient | undefined;
|
|
54
55
|
async function getClient(): Promise<SomeClient> {
|
|
@@ -59,6 +60,7 @@ Provider file location and naming differ by domain:
|
|
|
59
60
|
return _client;
|
|
60
61
|
}
|
|
61
62
|
```
|
|
63
|
+
|
|
62
64
|
5. **Register the provider** — the registration point differs by domain:
|
|
63
65
|
|
|
64
66
|
- **Storage** — add a `case` to the `switch` in `src/storage/core/storageFactory.ts`
|
|
@@ -79,10 +81,12 @@ Provider file location and naming differ by domain:
|
|
|
79
81
|
6. **Update the Worker-compatible provider list** if the new storage provider runs in
|
|
80
82
|
Cloudflare Workers. The list is an inline array in `storageFactory.ts` at the
|
|
81
83
|
`isServerless()` guard:
|
|
84
|
+
|
|
82
85
|
```typescript
|
|
83
86
|
// src/storage/core/storageFactory.ts ~line 112
|
|
84
87
|
!['in-memory', 'cloudflare-r2', 'cloudflare-kv', 'cloudflare-d1'].includes(providerType)
|
|
85
88
|
```
|
|
89
|
+
|
|
86
90
|
Add the new provider string to this array. Non-storage providers have no equivalent
|
|
87
91
|
gate.
|
|
88
92
|
|
package/skills/api-auth/SKILL.md
CHANGED
|
@@ -50,6 +50,7 @@ handler: async (input, ctx) => {
|
|
|
50
50
|
**Signature:** `checkScopes(ctx: Context, requiredScopes: string[]): void`
|
|
51
51
|
|
|
52
52
|
**Throws:**
|
|
53
|
+
|
|
53
54
|
- `McpError(Forbidden)` — auth is active and one or more required scopes are missing
|
|
54
55
|
- `McpError(Unauthorized)` — auth is enabled but no auth context exists on the request
|
|
55
56
|
- No-ops when `MCP_AUTH_MODE=none`
|
|
@@ -56,7 +56,7 @@ Utility exports from `@cyanheads/mcp-ts-core/utils`. Utilities with complex APIs
|
|
|
56
56
|
|
|
57
57
|
| Export | API | Notes |
|
|
58
58
|
|:-------|:----|:------|
|
|
59
|
-
| `schedulerService` | `.schedule(id, schedule, taskFunction, description) -> Promise<Job>` `.start(id) -> void` `.stop(id) -> void` `.remove(id) -> void` `.listJobs() -> Job[]` | **Async** `schedule()` — Tier 3 peer: `node-cron`. **Node-only** (throws `ConfigurationError` in Workers). Jobs start in stopped state; call `start(id)` to activate. Skips overlapping executions. Each tick gets fresh `RequestContext`. `Job: { id, schedule, description, isRunning, task }`. `taskFunction: (context: RequestContext) => void
|
|
59
|
+
| `schedulerService` | `.schedule(id, schedule, taskFunction, description) -> Promise<Job>` `.start(id) -> void` `.stop(id) -> void` `.remove(id) -> void` `.listJobs() -> Job[]` | **Async** `schedule()` — Tier 3 peer: `node-cron`. **Node-only** (throws `ConfigurationError` in Workers). Jobs start in stopped state; call `start(id)` to activate. Skips overlapping executions. Each tick gets fresh `RequestContext`. `Job: { id, schedule, description, isRunning, task }`. `taskFunction: (context: RequestContext) => void` \| `Promise<void>`. |
|
|
60
60
|
|
|
61
61
|
---
|
|
62
62
|
|
|
@@ -24,7 +24,7 @@ import { markdown, MarkdownBuilder, diffFormatter, tableFormatter, treeFormatter
|
|
|
24
24
|
| `codeBlock` | `(content, language?) -> this` | Fenced block; `language` defaults to `''` |
|
|
25
25
|
| `inlineCode` | `(code) -> this` | Backtick-wrapped; no trailing newline |
|
|
26
26
|
| `paragraph` | `(text) -> this` | Text + `\n\n` |
|
|
27
|
-
| `blockquote` | `(text) -> this` | Each line prefixed with
|
|
27
|
+
| `blockquote` | `(text) -> this` | Each line prefixed with `>` + space |
|
|
28
28
|
| `hr` | `() -> this` | `---` |
|
|
29
29
|
| `link` | `(text, url) -> this` | `[text](url)`; no trailing newline |
|
|
30
30
|
| `table` | `(headers, rows) -> this` | GFM table; no-ops if headers or rows empty |
|
|
@@ -150,7 +150,7 @@ interface TableFormatterOptions {
|
|
|
150
150
|
| Style | Description |
|
|
151
151
|
|:------|:------------|
|
|
152
152
|
| `markdown` | GFM pipes with alignment indicators in separator row |
|
|
153
|
-
| `ascii` |
|
|
153
|
+
| `ascii` | `+`/`-`/`\|` box drawing |
|
|
154
154
|
| `grid` | Unicode box drawing (`┌─┬─┐` / `│` / `├─┼─┤` / `└─┴─┘`) |
|
|
155
155
|
| `compact` | Space-separated, no borders |
|
|
156
156
|
|
|
@@ -211,7 +211,7 @@ interface TreeFormatterOptions {
|
|
|
211
211
|
| Style | Connectors |
|
|
212
212
|
|:------|:-----------|
|
|
213
213
|
| `unicode` | `├──` / `└──` / `│` |
|
|
214
|
-
| `ascii` | `+--` / `\--` /
|
|
214
|
+
| `ascii` | `+--` / `\--` / `\|` |
|
|
215
215
|
| `compact` | Indented list, no connectors |
|
|
216
216
|
|
|
217
217
|
### Usage
|
|
@@ -7,6 +7,7 @@ import { yamlParser, xmlParser, csvParser, jsonParser, pdfParser, dateParser, fr
|
|
|
7
7
|
All parsers are **Tier 3** — lazy-load their peer dependency on first call. All methods are **async** unless noted.
|
|
8
8
|
|
|
9
9
|
**Common behavior:**
|
|
10
|
+
|
|
10
11
|
- Singleton instances exported alongside classes
|
|
11
12
|
- `<think>...</think>` blocks at the start of input are automatically stripped and logged at `debug` level (except `dateParser` and `pdfParser`)
|
|
12
13
|
- All `context?: RequestContext` parameters are optional (synthetic context created if omitted)
|
|
@@ -240,6 +240,7 @@ For each resource:
|
|
|
240
240
|
### 6. Design Prompts (if needed)
|
|
241
241
|
|
|
242
242
|
Optional. Use when the server has recurring interaction patterns worth structuring:
|
|
243
|
+
|
|
243
244
|
- Analysis frameworks, report templates, multi-step workflows
|
|
244
245
|
|
|
245
246
|
Skip for purely data/action-oriented servers.
|
|
@@ -34,6 +34,7 @@ If these aren't met, address them first.
|
|
|
34
34
|
Read all tool, resource, and prompt definitions. Build a mental model of what the server actually does — names, descriptions, input/output shapes, auth scopes. This inventory drives every document below.
|
|
35
35
|
|
|
36
36
|
Read:
|
|
37
|
+
|
|
37
38
|
- `src/index.ts` (what's registered in `createApp()`)
|
|
38
39
|
- All files in `src/mcp-server/tools/definitions/`
|
|
39
40
|
- All files in `src/mcp-server/resources/definitions/`
|
|
@@ -27,6 +27,7 @@ The scaffolded template includes a `## First Session` section with one-time onbo
|
|
|
27
27
|
Check the Patterns section for generic template examples (e.g., `searchItems`, `itemData`, `reviewCode`). If still present, replace them with actual tool/resource/prompt definitions from the server — or the most representative ones if there are many. If the examples already reflect real definitions, verify they're still accurate.
|
|
28
28
|
|
|
29
29
|
Pick examples that:
|
|
30
|
+
|
|
30
31
|
- Show the most common or important capability
|
|
31
32
|
- Demonstrate any non-trivial patterns the server uses (e.g., `ctx.state`, `ctx.elicit`, `task: true`, services)
|
|
32
33
|
- Include a handler with real business logic, not just passthrough
|
package/skills/release/SKILL.md
CHANGED
|
@@ -82,7 +82,7 @@ bun run build
|
|
|
82
82
|
|
|
83
83
|
### 9. Commit
|
|
84
84
|
|
|
85
|
-
```
|
|
85
|
+
```text
|
|
86
86
|
chore: release v{{VERSION}}
|
|
87
87
|
```
|
|
88
88
|
|
|
@@ -96,7 +96,7 @@ git tag -a v{{VERSION}} -m "v{{VERSION}}: <one-line summary of key changes>"
|
|
|
96
96
|
|
|
97
97
|
The tag message should capture the most important change(s) — not the full changelog, just enough to orient someone browsing tags. Examples:
|
|
98
98
|
|
|
99
|
-
```
|
|
99
|
+
```text
|
|
100
100
|
v0.2.0: Cloudflare Workers support, task tools, Graph service
|
|
101
101
|
v0.1.7: OTel instrumentation refactor, lighter semconv
|
|
102
102
|
v0.1.6: Error factory functions, auto-classification patterns
|
package/skills/setup/SKILL.md
CHANGED
|
@@ -32,7 +32,7 @@ Read that file once per session. It contains the exports catalog, tool/resource/
|
|
|
32
32
|
|
|
33
33
|
What `init` actually creates:
|
|
34
34
|
|
|
35
|
-
```
|
|
35
|
+
```text
|
|
36
36
|
CLAUDE.md # Agent protocol (project-specific)
|
|
37
37
|
AGENTS.md # Same content — delete whichever you don't use
|
|
38
38
|
skills/ # Project skills (source of truth)
|
|
@@ -49,7 +49,7 @@ src/
|
|
|
49
49
|
|
|
50
50
|
Add these as needed:
|
|
51
51
|
|
|
52
|
-
```
|
|
52
|
+
```text
|
|
53
53
|
src/
|
|
54
54
|
worker.ts # createWorkerHandler() — only for Cloudflare Workers
|
|
55
55
|
config/
|
package/templates/AGENTS.md
CHANGED