@cyanheads/mcp-ts-core 0.8.17 → 0.8.19
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 +47 -46
- package/README.md +36 -38
- package/changelog/0.8.x/0.8.18.md +17 -0
- package/changelog/0.8.x/0.8.19.md +33 -0
- package/changelog/template.md +71 -44
- package/dist/cli/init.js +12 -5
- package/dist/cli/init.js.map +1 -1
- package/dist/logs/combined.log +6 -6
- package/dist/logs/error.log +4 -4
- package/dist/utils/internal/requestContext.d.ts +7 -0
- package/dist/utils/internal/requestContext.d.ts.map +1 -1
- package/dist/utils/internal/requestContext.js +1 -0
- package/dist/utils/internal/requestContext.js.map +1 -1
- package/package.json +20 -18
- package/scripts/build-changelog.ts +27 -18
- package/skills/api-telemetry/SKILL.md +222 -0
- package/skills/api-utils/SKILL.md +3 -1
- package/skills/maintenance/SKILL.md +16 -6
- package/skills/polish-docs-meta/references/package-meta.md +1 -1
- package/skills/report-issue-framework/SKILL.md +5 -3
- package/skills/report-issue-local/SKILL.md +5 -3
- package/skills/setup/SKILL.md +10 -9
- package/templates/AGENTS.md +20 -10
- package/templates/CLAUDE.md +20 -10
- package/templates/Dockerfile +2 -2
- package/templates/changelog/template.md +71 -44
- package/templates/package.json +2 -2
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: api-telemetry
|
|
3
|
+
description: >
|
|
4
|
+
Catalog of OpenTelemetry instrumentation built into framework `@cyanheads/mcp-ts-core` — spans, metrics, completion logs, env config, runtime caveats, custom instrumentation patterns, and cardinality rules. Use when enabling OTel export, adding custom spans or metrics in services, debugging missing telemetry, looking up attribute names, or deciding what's safe to put on a metric attribute vs. a span.
|
|
5
|
+
metadata:
|
|
6
|
+
author: cyanheads
|
|
7
|
+
version: "1.0"
|
|
8
|
+
audience: external
|
|
9
|
+
type: reference
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Overview
|
|
13
|
+
|
|
14
|
+
The framework auto-instruments every tool, resource, prompt, storage, LLM, speech, and graph call — each gets its own span and the standard counters/histograms. HTTP server requests pick up spans from `HttpInstrumentation` (or `@hono/otel` on the HTTP transport). Auth checks, session lifecycle, and task lifecycle are tracked as **metrics only** — auth decorates the active HTTP span with attributes, sessions and tasks emit counters.
|
|
15
|
+
|
|
16
|
+
`requestId`, `traceId`, and `tenantId` correlate automatically across spans, metrics, and logs. Pino logs get `trace_id`/`span_id` injected when a span is active.
|
|
17
|
+
|
|
18
|
+
For the helper API surface (`withSpan`, `createCounter`, `createHistogram`, `buildTraceparent`, etc.) — see the `api-utils` skill, `Telemetry` section. This skill is the catalog of **what** is emitted; that one is the reference for **how** to emit your own.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Enabling export
|
|
23
|
+
|
|
24
|
+
OTel is **off by default**. `OTEL_ENABLED=true` alone does nothing — you also need an OTLP endpoint. Without an endpoint the SDK is configured but nothing leaves the process.
|
|
25
|
+
|
|
26
|
+
| Env var | Default | Purpose |
|
|
27
|
+
|:--------|:--------|:--------|
|
|
28
|
+
| `OTEL_ENABLED` | `false` | Master switch. Must be `true` to start the SDK. |
|
|
29
|
+
| `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` | — | OTLP/HTTP traces endpoint (e.g. `http://localhost:4318/v1/traces`). |
|
|
30
|
+
| `OTEL_EXPORTER_OTLP_METRICS_ENDPOINT` | — | OTLP/HTTP metrics endpoint (e.g. `http://localhost:4318/v1/metrics`). |
|
|
31
|
+
| `OTEL_SERVICE_NAME` | `package.json` `name` | `service.name` resource attribute. |
|
|
32
|
+
| `OTEL_SERVICE_VERSION` | `package.json` `version` | `service.version` resource attribute. |
|
|
33
|
+
| `OTEL_TRACES_SAMPLER_ARG` | `1.0` | Trace sampling ratio (0–1) for `TraceIdRatioBasedSampler`. |
|
|
34
|
+
| `OTEL_LOG_LEVEL` | `INFO` | OTel diagnostic logger level (`NONE`/`ERROR`/`WARN`/`INFO`/`DEBUG`/`VERBOSE`/`ALL`). |
|
|
35
|
+
|
|
36
|
+
Metrics push via `PeriodicExportingMetricReader` every **15 seconds**. Traces use `BatchSpanProcessor`.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Runtime support
|
|
41
|
+
|
|
42
|
+
| Runtime | Behavior |
|
|
43
|
+
|:--------|:---------|
|
|
44
|
+
| **Node.js / Bun** | Full `NodeSDK`. Auto-instrumentations: HTTP server (Node http hooks; skips `/healthz`), Pino logs (`trace_id`/`span_id` injection). On the HTTP transport, when OTel is enabled and `@hono/otel` is installed, `httpInstrumentationMiddleware` is also wired onto the MCP endpoint — fills the gap on Bun, where the Node http auto-instrumentation silently no-ops. Manual spans, custom metrics, and OTLP export work on Bun regardless. |
|
|
45
|
+
| **Cloudflare Workers / V8 isolates** | `NodeSDK` is unavailable. SDK init no-ops silently. `createCounter`/`createHistogram`/`withSpan` calls still work via the global OTel API but produce no output unless you wire a Worker-compatible exporter and `ctx.waitUntil()` for flush. |
|
|
46
|
+
|
|
47
|
+
Cloud platform detection auto-populates resource attributes:
|
|
48
|
+
|
|
49
|
+
| Detected | Attributes set |
|
|
50
|
+
|:---------|:--------------|
|
|
51
|
+
| Cloudflare Workers | `cloud.provider=cloudflare`, `cloud.platform=cloudflare_workers` |
|
|
52
|
+
| AWS Lambda | `cloud.provider=aws`, `cloud.platform=aws_lambda`, `cloud.region` from `AWS_REGION` |
|
|
53
|
+
| GCP Cloud Run / Functions | `cloud.provider=gcp`, `cloud.platform=gcp_cloud_run` (or `gcp_cloud_functions`), `cloud.region` from `GCP_REGION` |
|
|
54
|
+
| All | `deployment.environment.name` from `config.environment` |
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Spans
|
|
59
|
+
|
|
60
|
+
Every handler call gets a span. Nested operations (storage, graph, LLM) become child spans on the same trace. All spans carry `code.function.name` and `code.namespace` for code-attribution. Errors are recorded via `span.recordException()` and `SpanStatusCode.ERROR`; `McpError` codes surface as the `*.error_code` attribute.
|
|
61
|
+
|
|
62
|
+
| Span name | Source | Key attributes |
|
|
63
|
+
|:----------|:-------|:---------------|
|
|
64
|
+
| `tool_execution:<tool>` | every tool call | `mcp.tool.input_bytes`, `mcp.tool.output_bytes`, `mcp.tool.duration_ms`, `mcp.tool.success`, `mcp.tool.error_code`, `mcp.tool.partial_success`, `mcp.tool.batch.{succeeded,failed}_count` |
|
|
65
|
+
| `resource_read:<resource>` | every resource handler | `mcp.resource.uri`, `mcp.resource.mime_type`, `mcp.resource.size_bytes`, `mcp.resource.duration_ms`, `mcp.resource.success`, `mcp.resource.error_code` |
|
|
66
|
+
| `prompt_generation:<prompt>` | every prompt handler | `mcp.prompt.input_bytes`, `mcp.prompt.output_bytes`, `mcp.prompt.message_count`, `mcp.prompt.duration_ms`, `mcp.prompt.success`, `mcp.prompt.error_code` |
|
|
67
|
+
| `storage:<op>` | `StorageService` (every call) | `mcp.storage.operation`, `mcp.storage.duration_ms`, `mcp.storage.success`, `mcp.storage.key_count` (batch ops) |
|
|
68
|
+
| `graph:<op>` | `GraphService` (every call) | `mcp.graph.operation`, `mcp.graph.duration_ms`, `mcp.graph.success` |
|
|
69
|
+
| `gen_ai.chat_completion` | OpenRouter LLM provider | `gen_ai.system=openrouter`, `gen_ai.request.model`, `gen_ai.request.{max_tokens,temperature,top_p,streaming}`, `gen_ai.response.model`, `gen_ai.usage.{input,output,total}_tokens` |
|
|
70
|
+
| `speech:tts` | ElevenLabs provider | `mcp.speech.provider`, `mcp.speech.operation`, `mcp.speech.input_bytes`, `mcp.speech.output_bytes`, `mcp.speech.duration_ms`, `mcp.speech.success` |
|
|
71
|
+
| `speech:stt` | Whisper provider | same as `speech:tts` |
|
|
72
|
+
|
|
73
|
+
Trace context propagates across boundaries via W3C `traceparent` headers. See `api-utils` → `telemetry/trace` for `withSpan`, `buildTraceparent`, `extractTraceparent`, `createContextWithParentTrace`, `injectCurrentContextInto`, `runInContext` signatures.
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## Metrics
|
|
78
|
+
|
|
79
|
+
All custom metrics are namespaced `mcp.*` (or `process.*` / `http.client.*` where standard semconv applies). Lazy-initialized on first emission; the universal ones are eagerly created at startup so series exist from the first export cycle.
|
|
80
|
+
|
|
81
|
+
### Tools, resources, prompts
|
|
82
|
+
|
|
83
|
+
| Metric | Type | Unit | Attributes |
|
|
84
|
+
|:-------|:-----|:-----|:-----------|
|
|
85
|
+
| `mcp.tool.calls` | counter | `{calls}` | `mcp.tool.name`, `mcp.tool.success` |
|
|
86
|
+
| `mcp.tool.duration` | histogram | `ms` | `mcp.tool.name`, `mcp.tool.success` |
|
|
87
|
+
| `mcp.tool.errors` | counter | `{errors}` | `mcp.tool.name`, `mcp.tool.error_category` (`upstream`/`server`/`client`) |
|
|
88
|
+
| `mcp.tool.input_bytes` | histogram | `bytes` | `mcp.tool.name` |
|
|
89
|
+
| `mcp.tool.output_bytes` | histogram | `bytes` | `mcp.tool.name` |
|
|
90
|
+
| `mcp.tool.param.usage` | counter | `{uses}` | `mcp.tool.name`, `mcp.tool.param` (top-level keys supplied by caller) |
|
|
91
|
+
| `mcp.resource.reads` | counter | `{reads}` | `mcp.resource.name`, `mcp.resource.success` |
|
|
92
|
+
| `mcp.resource.duration` | histogram | `ms` | `mcp.resource.name`, `mcp.resource.success` |
|
|
93
|
+
| `mcp.resource.errors` | counter | `{errors}` | `mcp.resource.name` |
|
|
94
|
+
| `mcp.resource.output_bytes` | histogram | `bytes` | `mcp.resource.name` |
|
|
95
|
+
| `mcp.prompt.generations` | counter | `{generations}` | `mcp.prompt.name`, `mcp.prompt.success` |
|
|
96
|
+
| `mcp.prompt.duration` | histogram | `ms` | `mcp.prompt.name`, `mcp.prompt.success` |
|
|
97
|
+
| `mcp.prompt.errors` | counter | `{errors}` | `mcp.prompt.name`, `mcp.prompt.error_category` |
|
|
98
|
+
| `mcp.prompt.input_bytes` | histogram | `bytes` | `mcp.prompt.name` |
|
|
99
|
+
| `mcp.prompt.output_bytes` | histogram | `bytes` | `mcp.prompt.name` |
|
|
100
|
+
| `mcp.prompt.message_count` | histogram | `{messages}` | `mcp.prompt.name` |
|
|
101
|
+
| `mcp.requests.active` | up/down counter | `{requests}` | — (in-flight handler executions, all three types) |
|
|
102
|
+
|
|
103
|
+
### Storage, LLM, speech, graph
|
|
104
|
+
|
|
105
|
+
| Metric | Type | Unit | Attributes |
|
|
106
|
+
|:-------|:-----|:-----|:-----------|
|
|
107
|
+
| `mcp.storage.operations` | counter | `{ops}` | `mcp.storage.operation`, `mcp.storage.success` |
|
|
108
|
+
| `mcp.storage.duration` | histogram | `ms` | `mcp.storage.operation`, `mcp.storage.success` |
|
|
109
|
+
| `mcp.storage.errors` | counter | `{errors}` | `mcp.storage.operation` |
|
|
110
|
+
| `mcp.llm.requests` | counter | `{requests}` | `gen_ai.system`, `gen_ai.request.model` |
|
|
111
|
+
| `mcp.llm.duration` | histogram | `ms` | `gen_ai.system`, `gen_ai.request.model` |
|
|
112
|
+
| `mcp.llm.errors` | counter | `{errors}` | `gen_ai.system`, `gen_ai.request.model` |
|
|
113
|
+
| `mcp.llm.tokens` | counter | `{tokens}` | `gen_ai.request.model`, `gen_ai.token.type` (`input`/`output`) |
|
|
114
|
+
| `mcp.speech.operations` | counter | `{ops}` | `mcp.speech.operation` (`tts`/`stt`), `mcp.speech.provider`, `mcp.speech.success` |
|
|
115
|
+
| `mcp.speech.duration` | histogram | `ms` | `mcp.speech.operation`, `mcp.speech.provider` |
|
|
116
|
+
| `mcp.speech.errors` | counter | `{errors}` | `mcp.speech.operation`, `mcp.speech.provider` |
|
|
117
|
+
| `mcp.graph.operations` | counter | `{ops}` | `mcp.graph.operation`, `mcp.graph.success` |
|
|
118
|
+
| `mcp.graph.duration` | histogram | `ms` | `mcp.graph.operation`, `mcp.graph.success` |
|
|
119
|
+
| `mcp.graph.errors` | counter | `{errors}` | `mcp.graph.operation` |
|
|
120
|
+
|
|
121
|
+
### Transport, auth, sessions, tasks
|
|
122
|
+
|
|
123
|
+
| Metric | Type | Unit | Attributes |
|
|
124
|
+
|:-------|:-----|:-----|:-----------|
|
|
125
|
+
| `mcp.auth.attempts` | counter | `{attempts}` | `mcp.auth.outcome` (`success`/`failure`/`missing`), `mcp.auth.failure_reason` |
|
|
126
|
+
| `mcp.auth.duration` | histogram | `ms` | `mcp.auth.outcome`, `mcp.auth.failure_reason` |
|
|
127
|
+
| `mcp.sessions.events` | counter | `{events}` | `mcp.session.event` (`created`/`terminated`/`rejected`/`stale_cleanup`) |
|
|
128
|
+
| `mcp.session.duration` | histogram | `s` | — |
|
|
129
|
+
| `mcp.sessions.active` | observable gauge | `{sessions}` | — |
|
|
130
|
+
| `mcp.heartbeat.failures` | counter | `{failures}` | `mcp.connection.transport` (`stdio`/`http`) |
|
|
131
|
+
| `mcp.http.close_failures` | counter | `{failures}` | `surface` (`transport`/`server`), `trigger` (`success`/`error`/`sse-abort`) — per-request close threw or timed out |
|
|
132
|
+
| `mcp.http.per_request.created` | counter | `{instances}` | `kind` (`server`/`transport`) — per-request `McpServer` and `McpSessionTransport` instances created |
|
|
133
|
+
| `mcp.http.per_request.finalized` | counter | `{instances}` | `kind` (`server`/`transport`) — per-request instances reclaimed by GC; persistent gap vs `created` indicates a leak |
|
|
134
|
+
| `mcp.tasks.created` | counter | `{tasks}` | `mcp.task.store_type` (`in-memory`/`storage`) |
|
|
135
|
+
| `mcp.tasks.status_changes` | counter | `{transitions}` | `mcp.task.status`, `mcp.task.store_type` |
|
|
136
|
+
| `mcp.tasks.active` | observable gauge | `{tasks}` | — (in-memory store only) |
|
|
137
|
+
|
|
138
|
+
### Errors, rate limits, HTTP client
|
|
139
|
+
|
|
140
|
+
| Metric | Type | Unit | Attributes |
|
|
141
|
+
|:-------|:-----|:-----|:-----------|
|
|
142
|
+
| `mcp.errors.classified` | counter | `{errors}` | `mcp.error.classified_code` (JSON-RPC code), `operation` |
|
|
143
|
+
| `mcp.ratelimit.rejections` | counter | `{rejections}` | `mcp.rate_limit.key` |
|
|
144
|
+
| `http.client.request.duration` | histogram | `s` | `http.request.method`, `server.address`, `http.response.status_code` (when > 0; absent on network errors before a response is received) |
|
|
145
|
+
|
|
146
|
+
### Process
|
|
147
|
+
|
|
148
|
+
Auto-registered when `process.memoryUsage` / `process.uptime` / `perf_hooks` are available (Node/Bun, not Workers). The three memory gauges share a single `process.memoryUsage()` snapshot per collection cycle, refreshed at most every 100 ms.
|
|
149
|
+
|
|
150
|
+
| Metric | Type | Unit | Notes |
|
|
151
|
+
|:-------|:-----|:-----|:------|
|
|
152
|
+
| `process.memory.rss` | observable gauge | `bytes` | Resident set size |
|
|
153
|
+
| `process.memory.heap_used` | observable gauge | `bytes` | V8 heap used |
|
|
154
|
+
| `process.memory.heap_total` | observable gauge | `bytes` | V8 total heap |
|
|
155
|
+
| `process.uptime` | observable gauge | `s` | Process uptime |
|
|
156
|
+
| `process.event_loop.delay` | observable gauge | `ms` | p99 delay (`monitorEventLoopDelay` resolution=20) |
|
|
157
|
+
| `process.event_loop.utilization` | observable gauge | `1` | 0 = idle, 1 = saturated |
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## Logs
|
|
162
|
+
|
|
163
|
+
Pino logs are auto-instrumented by `@opentelemetry/instrumentation-pino`. When a span is active, `trace_id` and `span_id` are injected into the record. Combined with the framework logger's automatic `requestId`/`tenantId` correlation, every log line is searchable by trace.
|
|
164
|
+
|
|
165
|
+
For domain logging inside handlers, use `ctx.log` (`debug`/`info`/`notice`/`warning`/`error`) — auto-includes `requestId`, `traceId`, `tenantId`, `spanId`. The completion log emitted at the end of every handler carries a `metrics` payload, with fields tuned to each surface:
|
|
166
|
+
|
|
167
|
+
| Handler | Log message | `metrics` fields |
|
|
168
|
+
|:--------|:------------|:-----------------|
|
|
169
|
+
| Tool | `Tool execution finished.` | `durationMs`, `isSuccess`, `errorCode`, `inputBytes`, `outputBytes`, plus `partialSuccess` / `batchSucceeded` / `batchFailed` when the result is a partial-success batch |
|
|
170
|
+
| Resource | `Resource read finished.` | `durationMs`, `isSuccess`, `errorCode`, `outputBytes`, `uri`, `mimeType` |
|
|
171
|
+
| Prompt | `Prompt generation finished.` (or `failed.`) | `durationMs`, `isSuccess`, `errorCode`, `inputBytes`, `outputBytes`, `messageCount` |
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## Custom instrumentation
|
|
176
|
+
|
|
177
|
+
Need a span or metric for your own service? Use the helpers from `@cyanheads/mcp-ts-core/utils` (full signatures in `api-utils` → `Telemetry`):
|
|
178
|
+
|
|
179
|
+
```ts
|
|
180
|
+
import { withSpan, createCounter, createHistogram } from '@cyanheads/mcp-ts-core/utils';
|
|
181
|
+
|
|
182
|
+
const myOps = createCounter('myservice.operations', 'My service ops', '{ops}');
|
|
183
|
+
const myDuration = createHistogram('myservice.duration', 'My service duration', 'ms');
|
|
184
|
+
|
|
185
|
+
export async function doWork() {
|
|
186
|
+
return withSpan('myservice.do_work', async (span) => {
|
|
187
|
+
const t0 = performance.now();
|
|
188
|
+
try {
|
|
189
|
+
const result = await reallyDoWork();
|
|
190
|
+
span.setAttribute('myservice.items', result.length);
|
|
191
|
+
return result;
|
|
192
|
+
} finally {
|
|
193
|
+
myDuration.record(performance.now() - t0);
|
|
194
|
+
myOps.add(1);
|
|
195
|
+
}
|
|
196
|
+
}, { 'myservice.region': 'us-west' });
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Span context propagates automatically — `withSpan` calls inside a `tool_execution:*` span appear as children. `runInContext(ctx, fn)` carries the active OTel context across async boundaries (`setTimeout`, `queueMicrotask`).
|
|
201
|
+
|
|
202
|
+
For attribute keys, prefer the `ATTR_*` constants exported from `@cyanheads/mcp-ts-core/utils` (telemetry/attributes) over hand-typed strings — keeps you in step with framework conventions and avoids typos. Standard OTel semantic conventions (HTTP, cloud, service, network, etc.) are NOT re-exported — import those directly from `@opentelemetry/semantic-conventions`.
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## Visualization
|
|
207
|
+
|
|
208
|
+
An example Grafana dashboard JSON and vendor-agnostic query recipes (Prometheus, Datadog, New Relic, Honeycomb) live at [`docs/telemetry/`](https://github.com/cyanheads/mcp-ts-core/tree/main/docs/telemetry) in the framework source — not bundled in the npm package, so consult the GitHub repo.
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## Cardinality discipline
|
|
213
|
+
|
|
214
|
+
Series are cheap to emit but expensive to store and query. The framework deliberately keeps high-cardinality identifiers off metric attributes and on spans only. Follow the same rule when adding your own metrics.
|
|
215
|
+
|
|
216
|
+
| On metrics | On spans / logs only |
|
|
217
|
+
|:-----------|:---------------------|
|
|
218
|
+
| `mcp.resource.name` (URI template) | `mcp.resource.uri` (full URI with IDs) |
|
|
219
|
+
| `gen_ai.request.model` (bounded enum) | `mcp.tenant.id`, `mcp.client.id`, `mcp.auth.subject` |
|
|
220
|
+
| Bounded enum / template strings | Per-request unique IDs, free-form user input, opaque tokens |
|
|
221
|
+
|
|
222
|
+
When in doubt: if the attribute can take more than ~100 distinct values across a fleet's runtime, it belongs on the span, not the metric.
|
|
@@ -4,7 +4,7 @@ description: >
|
|
|
4
4
|
API reference for all utilities exported from `@cyanheads/mcp-ts-core/utils`. Use when looking up utility method signatures, options, peer dependencies, or usage patterns.
|
|
5
5
|
metadata:
|
|
6
6
|
author: cyanheads
|
|
7
|
-
version: "2.
|
|
7
|
+
version: "2.2"
|
|
8
8
|
audience: external
|
|
9
9
|
type: reference
|
|
10
10
|
---
|
|
@@ -136,6 +136,8 @@ Both functions throw `McpError(InternalError)` only on unexpected heuristic fail
|
|
|
136
136
|
|
|
137
137
|
## `@cyanheads/mcp-ts-core/utils` — Telemetry
|
|
138
138
|
|
|
139
|
+
Helper API only. For the catalog of what the framework auto-emits (span names, metric names, attributes, completion log fields, env config, runtime support, cardinality rules), see the `api-telemetry` skill.
|
|
140
|
+
|
|
139
141
|
### `telemetry/instrumentation`
|
|
140
142
|
|
|
141
143
|
| Export | Signature | Notes |
|
|
@@ -4,7 +4,7 @@ description: >
|
|
|
4
4
|
Investigate, adopt, and verify dependency updates — with special handling for `@cyanheads/mcp-ts-core`. Captures what changed, understands why, cross-references against the codebase, adopts framework improvements, syncs project skills, and runs final checks. Supports two entry modes: run the full flow end-to-end, or review updates you already applied.
|
|
5
5
|
metadata:
|
|
6
6
|
author: cyanheads
|
|
7
|
-
version: "2.
|
|
7
|
+
version: "2.1"
|
|
8
8
|
audience: external
|
|
9
9
|
type: workflow
|
|
10
10
|
---
|
|
@@ -120,9 +120,11 @@ For each agent directory that exists:
|
|
|
120
120
|
|
|
121
121
|
If no agent directory exists, skip Phase B — the project hasn't opted in to per-agent skill copies.
|
|
122
122
|
|
|
123
|
-
**Phase C — Package
|
|
123
|
+
**Phase C — Package framework files → Project**
|
|
124
124
|
|
|
125
|
-
|
|
125
|
+
Two categories of framework-authored files ship into consumer projects and drift silently as the framework updates them. Both follow the same hash-compare-and-overwrite mechanic.
|
|
126
|
+
|
|
127
|
+
**Scripts** — `init` scaffolds a fixed set that underpin `bun run build`, `bun run devcheck`, `bun run lint:mcp`, `bun run tree`, and the changelog build. Iterate the package's shipped scripts directory:
|
|
126
128
|
|
|
127
129
|
```bash
|
|
128
130
|
for src in node_modules/@cyanheads/mcp-ts-core/scripts/*.ts; do
|
|
@@ -140,9 +142,17 @@ done
|
|
|
140
142
|
|
|
141
143
|
Scripts in `scripts/` that aren't present in the package directory are project-specific (custom deploy, codegen, etc.) — leave them alone. The package's `files:` field gates what ships into `node_modules/.../scripts/`, so enumerating that directory is the canonical "shipped scripts" set.
|
|
142
144
|
|
|
143
|
-
|
|
145
|
+
**Pristine reference files** — files explicitly documented as "never edit, rename, or move." The framework keeps the authoritative copy under `templates/`; the consumer's copy must track upstream as the format evolves (new frontmatter fields, section reorderings, etc.). Fixed src→dst mapping:
|
|
146
|
+
|
|
147
|
+
| Source (in package) | Destination (in project) |
|
|
148
|
+
|:--|:--|
|
|
149
|
+
| `templates/changelog/template.md` | `changelog/template.md` |
|
|
150
|
+
|
|
151
|
+
Apply the same compare-and-overwrite logic. Add new entries here only when a template is explicitly documented as pristine in the framework's CLAUDE.md or its own header.
|
|
152
|
+
|
|
153
|
+
If the consumer customized a framework script or pristine reference (against guidance), the overwrite discards those changes. After the sync runs, diff `scripts/` and the affected template paths to surface replacements — review before committing. If a specific local customization needs to be preserved, revert that file using your git tools.
|
|
144
154
|
|
|
145
|
-
**Report** which skills were added/updated in Phase A (with version deltas), which agent directories were refreshed in Phase B, and which scripts were resynced in Phase C. The user needs to know what new guidance and tooling is now in play.
|
|
155
|
+
**Report** which skills were added/updated in Phase A (with version deltas), which agent directories were refreshed in Phase B, and which scripts and pristine reference files were resynced in Phase C. The user needs to know what new guidance and tooling is now in play.
|
|
146
156
|
|
|
147
157
|
### 6. Adopt changes in the codebase
|
|
148
158
|
|
|
@@ -212,7 +222,7 @@ Present a concise numbered summary to the user:
|
|
|
212
222
|
- [ ] Every applicable framework adoption opportunity applied in this pass — no scope/effort/marginal-benefit deferrals; third-party adoptions evaluated on cost/benefit
|
|
213
223
|
- [ ] Project `skills/` synced from package (Phase A), with a change report
|
|
214
224
|
- [ ] Agent skill directories (`.claude/skills/`, `.agents/skills/`, etc.) refreshed from project `skills/` (Phase B)
|
|
215
|
-
- [ ] Framework `scripts/` resynced from package via content-hash compare (Phase C), with a change report;
|
|
225
|
+
- [ ] Framework `scripts/` and pristine reference files resynced from package via content-hash compare (Phase C), with a change report; diffs reviewed before committing
|
|
216
226
|
- [ ] `bun run rebuild` succeeds
|
|
217
227
|
- [ ] `bun run devcheck` passes (includes audit + outdated)
|
|
218
228
|
- [ ] `bun run test` passes
|
|
@@ -27,7 +27,7 @@ These are set by `init` and generally don't need changes. Verify they're present
|
|
|
27
27
|
| `main` | `"dist/index.js"` | Entry point after build |
|
|
28
28
|
| `types` | `"dist/index.d.ts"` | TypeScript declarations |
|
|
29
29
|
| `files` | `["dist/"]` | What npm publishes |
|
|
30
|
-
| `engines` | `{ "node": ">=
|
|
30
|
+
| `engines` | `{ "node": ">=24.0.0" }` | Add `"bun": ">=1.3.0"` alongside Node |
|
|
31
31
|
| `packageManager` | _(often missing)_ | `"bun@1.3.2"` (or current Bun version). Signals the intended package manager. |
|
|
32
32
|
| `scripts` | _(various)_ | Build, dev, test scripts |
|
|
33
33
|
| `dependencies` | `@cyanheads/mcp-ts-core` | Core framework |
|
|
@@ -4,7 +4,7 @@ description: >
|
|
|
4
4
|
File a bug or feature request against @cyanheads/mcp-ts-core when you hit a framework issue. Use when a builder, utility, context method, or config behaves contrary to the documented API — not for server-specific application bugs.
|
|
5
5
|
metadata:
|
|
6
6
|
author: cyanheads
|
|
7
|
-
version: "1.
|
|
7
|
+
version: "1.6"
|
|
8
8
|
audience: external
|
|
9
9
|
type: workflow
|
|
10
10
|
---
|
|
@@ -35,16 +35,18 @@ gh issue list -R cyanheads/mcp-ts-core --search "your error message or keyword"
|
|
|
35
35
|
|
|
36
36
|
## Writing Well-Structured Issues
|
|
37
37
|
|
|
38
|
-
Good issues are scannable, concrete, and self-contained. These patterns apply to both bugs and features — the guidance targets any prose block (Description, Additional context, feature proposals).
|
|
38
|
+
Good issues are scannable, concrete, and self-contained — terse and fact-dense. Default to one or two sentences per bullet; if a bullet runs long, split it or cut it. These patterns apply to both bugs and features — the guidance targets any prose block (Description, Additional context, feature proposals).
|
|
39
39
|
|
|
40
40
|
- **Lead with specifics.** Name the tool, function, module, or symptom. "Currently `createApp()` throws `ConfigurationError` when `MCP_HTTP_PORT` is set to `0`" beats "There's a problem with the config." A reader should know what's broken or missing before the end of the first sentence.
|
|
41
41
|
- **Embed library/service links on first mention.** `[Hono](https://hono.dev/)`, `[linkedom](https://github.com/WebReflection/linkedom)`. Link to the canonical repo or homepage so readers can verify the dependency and reach docs in one click.
|
|
42
42
|
- **Use `owner/repo#N` for cross-repo issue references.** GitHub auto-renders them as linked references (e.g. `cyanheads/pubmed-mcp-server#34`). Bare `#N` only works for same-repo issues.
|
|
43
43
|
- **Add a `Related: #N` line** near the top when the issue grows from prior context (discussions, other issues, PRs). Makes provenance clickable.
|
|
44
|
+
- **Cite cross-references once per body.** Link an issue/PR in `Related:`, the description, or Additional context — not all three. The reader sees them all; redundant linking dilutes signal.
|
|
44
45
|
- **Lead design sections with a philosophy sentence.** Bold a short principle before the tradeoff details — e.g. "Philosophy: **fail fast on config errors, degrade gracefully on runtime errors.**" Establishes the lens for the rest of the section.
|
|
45
46
|
- **Prefer Markdown tables for comparisons.** When showing options, tiers, strategies, or tradeoffs — tables are the highest-density format for scanning N rows × M attributes.
|
|
46
47
|
- **Separate `### Scope` from `### Out of scope`.** The latter is as important as the former — it pre-empts scope-creep debates in comments and signals you've thought about the boundaries.
|
|
47
48
|
- **Use `Depends on: owner/repo#N`** to declare ordering explicitly when implementation is blocked on another issue landing first.
|
|
49
|
+
- **Cut what dilutes the signal.** Mechanism walkthroughs (link the PR or doc instead), ceremonial framings ("This issue covers…"), conversation references ("as discussed", "per offline"), and kitchen-sink Additional context blocks. If a paragraph isn't pulling weight, drop it.
|
|
48
50
|
- **Skip collaborator-framing sign-offs.** Lines like "Happy to open a PR", "let me know if you'd like", "willing to contribute", "if that's the preferred flow" read as noise. A PR link beats an offer; if you're the maintainer filing against your own repo, the offer is redundant. End the body at the last substantive point.
|
|
49
51
|
|
|
50
52
|
## Redact Before Posting
|
|
@@ -81,7 +83,7 @@ Bun
|
|
|
81
83
|
|
|
82
84
|
### Runtime version
|
|
83
85
|
|
|
84
|
-
Bun 1.
|
|
86
|
+
Bun 1.3.x
|
|
85
87
|
|
|
86
88
|
### Transport
|
|
87
89
|
|
|
@@ -4,7 +4,7 @@ description: >
|
|
|
4
4
|
File a bug or feature request against this MCP server's own repo. Use for server-specific issues — tool logic, service integrations, config problems, or domain bugs that aren't caused by the framework.
|
|
5
5
|
metadata:
|
|
6
6
|
author: cyanheads
|
|
7
|
-
version: "1.
|
|
7
|
+
version: "1.5"
|
|
8
8
|
audience: external
|
|
9
9
|
type: workflow
|
|
10
10
|
---
|
|
@@ -44,16 +44,18 @@ gh issue list --search "your error message or keyword"
|
|
|
44
44
|
|
|
45
45
|
## Writing Well-Structured Issues
|
|
46
46
|
|
|
47
|
-
Good issues are scannable, concrete, and self-contained. These patterns apply to both bugs and features — the guidance targets any prose block (Description, Additional context, feature proposals).
|
|
47
|
+
Good issues are scannable, concrete, and self-contained — terse and fact-dense. Default to one or two sentences per bullet; if a bullet runs long, split it or cut it. These patterns apply to both bugs and features — the guidance targets any prose block (Description, Additional context, feature proposals).
|
|
48
48
|
|
|
49
49
|
- **Lead with specifics.** Name the tool, service, resource, or symptom. "Currently `search_docs` returns an empty array for queries containing `&`" beats "Search is broken." A reader should know what's wrong before the end of the first sentence.
|
|
50
50
|
- **Embed library/service links on first mention.** `[Hono](https://hono.dev/)`, `[Supabase](https://supabase.com/)`. Link to the canonical repo or homepage so readers can verify the dependency and reach docs in one click.
|
|
51
51
|
- **Use `owner/repo#N` for cross-repo issue references.** GitHub auto-renders them as linked references (e.g. `cyanheads/mcp-ts-core#46`). Bare `#N` only works for same-repo issues — useful when the bug depends on or relates to a framework issue.
|
|
52
52
|
- **Add a `Related: #N` line** near the top when the issue grows from prior context (discussions, other issues, PRs). Makes provenance clickable.
|
|
53
|
+
- **Cite cross-references once per body.** Link an issue/PR in `Related:`, the description, or Additional context — not all three. The reader sees them all; redundant linking dilutes signal.
|
|
53
54
|
- **Lead design sections with a philosophy sentence.** Bold a short principle before the tradeoff details — e.g. "Philosophy: **return best-effort data, don't fail the tool call on parsing edge cases.**" Establishes the lens for the rest of the section.
|
|
54
55
|
- **Prefer Markdown tables for comparisons.** When showing options, data sources, strategies, or tradeoffs — tables are the highest-density format for scanning N rows × M attributes.
|
|
55
56
|
- **Separate `### Scope` from `### Out of scope`.** The latter is as important as the former — it pre-empts scope-creep debates in comments and signals you've thought about the boundaries.
|
|
56
57
|
- **Use `Depends on: owner/repo#N`** to declare ordering explicitly when implementation is blocked on an upstream framework change or another issue landing first.
|
|
58
|
+
- **Cut what dilutes the signal.** Mechanism walkthroughs (link the PR or doc instead), ceremonial framings ("This issue covers…"), conversation references ("as discussed", "per offline"), and kitchen-sink Additional context blocks. If a paragraph isn't pulling weight, drop it.
|
|
57
59
|
- **Skip collaborator-framing sign-offs.** Lines like "Happy to open a PR", "let me know if you'd like", "willing to contribute", "if that's the preferred flow" read as noise. A PR link beats an offer; if you're the maintainer filing against your own repo, the offer is redundant. End the body at the last substantive point.
|
|
58
60
|
|
|
59
61
|
## Redact Before Posting
|
|
@@ -94,7 +96,7 @@ Bun
|
|
|
94
96
|
|
|
95
97
|
### Runtime version
|
|
96
98
|
|
|
97
|
-
Bun 1.
|
|
99
|
+
Bun 1.3.x
|
|
98
100
|
|
|
99
101
|
### Transport
|
|
100
102
|
|
package/skills/setup/SKILL.md
CHANGED
|
@@ -4,14 +4,14 @@ description: >
|
|
|
4
4
|
Post-init orientation for an MCP server built on @cyanheads/mcp-ts-core. Use after running `@cyanheads/mcp-ts-core init` to understand the project structure, conventions, and skill sync model. Also use when onboarding to an existing project for the first time.
|
|
5
5
|
metadata:
|
|
6
6
|
author: cyanheads
|
|
7
|
-
version: "1.
|
|
7
|
+
version: "1.7"
|
|
8
8
|
audience: external
|
|
9
9
|
type: workflow
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
## Context
|
|
13
13
|
|
|
14
|
-
This skill assumes `
|
|
14
|
+
This skill assumes `bunx @cyanheads/mcp-ts-core init [name]` has already run. The CLI created the project's `CLAUDE.md` and `AGENTS.md` for different agents, copied external skills to `skills/`, and scaffolded the directory structure with echo definitions as starting points. This skill covers what was created and what to do next.
|
|
15
15
|
|
|
16
16
|
## Agent Protocol File
|
|
17
17
|
|
|
@@ -22,7 +22,7 @@ The init CLI generates both `CLAUDE.md` and `AGENTS.md` with the same purpose. K
|
|
|
22
22
|
|
|
23
23
|
Both files serve the same purpose: project-specific agent instructions. Prefer committing one authoritative copy rather than trying to keep both in sync by hand.
|
|
24
24
|
|
|
25
|
-
For the full framework
|
|
25
|
+
For the full framework docs, read `node_modules/@cyanheads/mcp-ts-core/CLAUDE.md` once per session. It contains the exports catalog, tool/resource/prompt contracts, error codes, context API, and common import patterns.
|
|
26
26
|
|
|
27
27
|
## Project Structure
|
|
28
28
|
|
|
@@ -96,7 +96,7 @@ After init:
|
|
|
96
96
|
2. **Rename and replace what you keep.** The echo definitions and their tests show the pattern — swap them out for your real tools/resources/prompts.
|
|
97
97
|
3. **Definitions register directly in `src/index.ts`.** No barrel files, just import and add to the `tools` / `resources` / `prompts` arrays.
|
|
98
98
|
|
|
99
|
-
See the `add-tool`, `add-app-tool`, `add-resource`, `add-prompt`, and `add-test` skills for the scaffolding patterns when you start adding real definitions.
|
|
99
|
+
See the `add-tool`, `add-app-tool`, `add-resource`, `add-prompt`, `add-service`, and `add-test` skills for the scaffolding patterns when you start adding real definitions.
|
|
100
100
|
|
|
101
101
|
## Conventions
|
|
102
102
|
|
|
@@ -130,11 +130,11 @@ After `bun install`, complete these one-time setup tasks:
|
|
|
130
130
|
|
|
131
131
|
1. **Update dependencies to latest** — `bun update --latest`. The scaffolded `package.json` pins minimum versions from when the framework was published; updating ensures you start with the latest compatible releases.
|
|
132
132
|
2. **Initialize git** — use your git tools: init the repo, stage all files, and commit with message `chore: scaffold from @cyanheads/mcp-ts-core`
|
|
133
|
-
3. **Verify
|
|
133
|
+
3. **Verify the substituted server name** — when `init` runs without a `[name]` argument, the package name defaults to the cwd directory name. If that's not what you want as the published server name, update `package.json`, `CLAUDE.md`/`AGENTS.md`, and `server.json` to your actual server name.
|
|
134
134
|
|
|
135
135
|
## Changelog Convention
|
|
136
136
|
|
|
137
|
-
`changelog/template.md` ships as a **format reference** — never edit, rename, or move it. For each release, author a per-version file at `changelog/<major.minor>.x/<version>.md` (e.g. `changelog/0.1.x/0.1.0.md`) with YAML frontmatter (`summary:` + optional `breaking:`) and grouped sections (Added / Changed / Fixed / Removed). Then regenerate the rollup with `bun run changelog:build` — `CHANGELOG.md` is an auto-generated navigation index, never hand-edited. See the `release-and-publish` skill for the full release flow.
|
|
137
|
+
`changelog/template.md` ships as a **format reference** — never edit, rename, or move it. For each release, author a per-version file at `changelog/<major.minor>.x/<version>.md` (e.g. `changelog/0.1.x/0.1.0.md`) with YAML frontmatter (`summary:` + optional `breaking:` / `security:`) and grouped sections (Added / Changed / Fixed / Removed). Then regenerate the rollup with `bun run changelog:build` — `CHANGELOG.md` is an auto-generated navigation index, never hand-edited. See the `release-and-publish` skill for the full release flow.
|
|
138
138
|
|
|
139
139
|
## Next Steps
|
|
140
140
|
|
|
@@ -146,15 +146,16 @@ The included skills form a rough progression — not a rigid sequence, but the t
|
|
|
146
146
|
4. **`field-test`** — exercise the built surface with real and adversarial inputs; produces a report of issues and pain points
|
|
147
147
|
5. **`security-pass`** — audit handlers for MCP-specific security gaps: output injection, scope blast radius, input sinks, tenant isolation
|
|
148
148
|
6. **`polish-docs-meta`** — finalize README, metadata, and agent protocol before shipping
|
|
149
|
-
7. **`
|
|
149
|
+
7. **`release-and-publish`** — post-wrapup ship workflow: verification gate, push commits and tags, publish to npm/MCP Registry/GHCR
|
|
150
|
+
8. **`maintenance`** — after `bun update --latest`, investigate upstream changelogs and re-sync skills
|
|
150
151
|
|
|
151
152
|
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.
|
|
152
153
|
|
|
153
154
|
## Checklist
|
|
154
155
|
|
|
155
156
|
- [ ] Agent protocol file selected — keep one authoritative file (`CLAUDE.md` or `AGENTS.md`)
|
|
156
|
-
- [ ]
|
|
157
|
-
- [ ]
|
|
157
|
+
- [ ] Substituted server name verified in `package.json`, agent protocol file, and `server.json`
|
|
158
|
+
- [ ] Framework docs read (`node_modules/@cyanheads/mcp-ts-core/CLAUDE.md`)
|
|
158
159
|
- [ ] Unused echo definitions cleaned up (and unregistered from `src/index.ts`)
|
|
159
160
|
- [ ] Skills copied to agent directory (`cp -R skills/* .claude/skills/` or equivalent)
|
|
160
161
|
- [ ] Project structure understood (definitions directories, entry point)
|
package/templates/AGENTS.md
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Developer Protocol
|
|
2
2
|
|
|
3
3
|
**Server:** {{PACKAGE_NAME}}
|
|
4
4
|
**Version:** 0.1.0
|
|
5
|
-
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core)
|
|
5
|
+
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^{{FRAMEWORK_VERSION}}`
|
|
6
|
+
**Engines:** Bun ≥1.3.0, Node ≥24.0.0
|
|
7
|
+
**MCP SDK:** `@modelcontextprotocol/sdk` {{MCP_SDK_VERSION}}
|
|
8
|
+
**Zod:** {{ZOD_VERSION}}
|
|
6
9
|
|
|
7
10
|
> **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.
|
|
8
11
|
|
|
@@ -10,17 +13,20 @@
|
|
|
10
13
|
|
|
11
14
|
## First Session
|
|
12
15
|
|
|
16
|
+
This project was just scaffolded with `bunx @cyanheads/mcp-ts-core init`. The framework, skills, and example definitions are in place — the domain isn't. The user's first messages will set direction; wait for them before proceeding.
|
|
17
|
+
|
|
13
18
|
> **Remove this section** from CLAUDE.md / AGENTS.md after completing these steps. The skills and conventions below remain — this block is one-time onboarding only.
|
|
14
19
|
|
|
15
|
-
1. **
|
|
16
|
-
2. **
|
|
17
|
-
3. **
|
|
20
|
+
1. **Get your bearings.** Take stock of your current environment — think through the project tree, the skills in `skills/`, and the tools/MCP servers you have available. Light tool use is fine if something isn't already in context; you're building a mental map for later, not committing to anything yet.
|
|
21
|
+
2. **Read the framework docs** — `node_modules/@cyanheads/mcp-ts-core/CLAUDE.md` (builders, Context, errors, exports, conventions)
|
|
22
|
+
3. **Run the `setup` skill** — read `skills/setup/SKILL.md` and follow its checklist (project orientation, agent protocol file selection, echo definition cleanup, skill sync)
|
|
23
|
+
4. **Design the server** — read `skills/design-mcp-server/SKILL.md` and work through it with the user to map the domain into tools, resources, and services before scaffolding
|
|
18
24
|
|
|
19
25
|
---
|
|
20
26
|
|
|
21
27
|
## What's Next?
|
|
22
28
|
|
|
23
|
-
When the user asks what to do next, what's left, or needs direction, suggest relevant options based on the current project state:
|
|
29
|
+
When the user asks what to do next, what's left, or needs direction, you can suggest relevant options based on the current project state. Some common next steps:
|
|
24
30
|
|
|
25
31
|
1. **Re-run the `setup` skill** — ensures CLAUDE.md, skills, structure, and metadata are populated and up to date with the current codebase
|
|
26
32
|
2. **Run the `design-mcp-server` skill** — if the tool/resource surface hasn't been mapped yet, work through domain design
|
|
@@ -271,7 +277,8 @@ Available skills:
|
|
|
271
277
|
| `api-errors` | McpError, JsonRpcErrorCode, error patterns |
|
|
272
278
|
| `api-services` | LLM, Speech, Graph services |
|
|
273
279
|
| `api-testing` | createMockContext, test patterns |
|
|
274
|
-
| `api-utils` | Formatting, parsing, security, pagination, scheduling |
|
|
280
|
+
| `api-utils` | Formatting, parsing, security, pagination, scheduling, telemetry helpers |
|
|
281
|
+
| `api-telemetry` | OTel catalog: spans, metrics, completion logs, env config, cardinality rules |
|
|
275
282
|
| `api-workers` | Cloudflare Workers runtime |
|
|
276
283
|
|
|
277
284
|
When you complete a skill's checklist, check the boxes and add a completion timestamp at the end (e.g., `Completed: 2026-03-11`).
|
|
@@ -306,15 +313,18 @@ Each per-version file opens with YAML frontmatter:
|
|
|
306
313
|
|
|
307
314
|
```markdown
|
|
308
315
|
---
|
|
309
|
-
summary: One-line headline, ≤250 chars # required — powers the rollup index
|
|
310
|
-
breaking: false
|
|
316
|
+
summary: "One-line headline, ≤250 chars" # required — powers the rollup index
|
|
317
|
+
breaking: false # optional — true flags breaking changes
|
|
318
|
+
security: false # optional — true flags security fixes
|
|
311
319
|
---
|
|
312
320
|
|
|
313
321
|
# 0.1.0 — YYYY-MM-DD
|
|
314
322
|
...
|
|
315
323
|
```
|
|
316
324
|
|
|
317
|
-
`breaking: true` renders a `· ⚠️ Breaking` badge
|
|
325
|
+
`breaking: true` renders a `· ⚠️ Breaking` badge — use it when consumers must update code on upgrade (signature changes, removed APIs, config renames). `security: true` renders a `· 🛡️ Security` badge and pairs with a `## Security` body section. When both are set, badges render `· ⚠️ Breaking · 🛡️ Security`.
|
|
326
|
+
|
|
327
|
+
**Section order** (Keep a Changelog): Added, Changed, Deprecated, Removed, Fixed, Security. Include only sections with entries — don't ship empty headers.
|
|
318
328
|
|
|
319
329
|
---
|
|
320
330
|
|
package/templates/CLAUDE.md
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Developer Protocol
|
|
2
2
|
|
|
3
3
|
**Server:** {{PACKAGE_NAME}}
|
|
4
4
|
**Version:** 0.1.0
|
|
5
|
-
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core)
|
|
5
|
+
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^{{FRAMEWORK_VERSION}}`
|
|
6
|
+
**Engines:** Bun ≥1.3.0, Node ≥24.0.0
|
|
7
|
+
**MCP SDK:** `@modelcontextprotocol/sdk` {{MCP_SDK_VERSION}}
|
|
8
|
+
**Zod:** {{ZOD_VERSION}}
|
|
6
9
|
|
|
7
10
|
> **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.
|
|
8
11
|
|
|
@@ -10,17 +13,20 @@
|
|
|
10
13
|
|
|
11
14
|
## First Session
|
|
12
15
|
|
|
16
|
+
This project was just scaffolded with `bunx @cyanheads/mcp-ts-core init`. The framework, skills, and example definitions are in place — the domain isn't. The user's first messages will set direction; wait for them before proceeding.
|
|
17
|
+
|
|
13
18
|
> **Remove this section** from CLAUDE.md / AGENTS.md after completing these steps. The skills and conventions below remain — this block is one-time onboarding only.
|
|
14
19
|
|
|
15
|
-
1. **
|
|
16
|
-
2. **
|
|
17
|
-
3. **
|
|
20
|
+
1. **Get your bearings.** Take stock of your current environment — think through the project tree, the skills in `skills/`, and the tools/MCP servers you have available. Light tool use is fine if something isn't already in context; you're building a mental map for later, not committing to anything yet.
|
|
21
|
+
2. **Read the framework docs** — `node_modules/@cyanheads/mcp-ts-core/CLAUDE.md` (builders, Context, errors, exports, conventions)
|
|
22
|
+
3. **Run the `setup` skill** — read `skills/setup/SKILL.md` and follow its checklist (project orientation, agent protocol file selection, echo definition cleanup, skill sync)
|
|
23
|
+
4. **Design the server** — read `skills/design-mcp-server/SKILL.md` and work through it with the user to map the domain into tools, resources, and services before scaffolding
|
|
18
24
|
|
|
19
25
|
---
|
|
20
26
|
|
|
21
27
|
## What's Next?
|
|
22
28
|
|
|
23
|
-
When the user asks what to do next, what's left, or needs direction, suggest relevant options based on the current project state:
|
|
29
|
+
When the user asks what to do next, what's left, or needs direction, you can suggest relevant options based on the current project state. Some common next steps:
|
|
24
30
|
|
|
25
31
|
1. **Re-run the `setup` skill** — ensures CLAUDE.md, skills, structure, and metadata are populated and up to date with the current codebase
|
|
26
32
|
2. **Run the `design-mcp-server` skill** — if the tool/resource surface hasn't been mapped yet, work through domain design
|
|
@@ -271,7 +277,8 @@ Available skills:
|
|
|
271
277
|
| `api-errors` | McpError, JsonRpcErrorCode, error patterns |
|
|
272
278
|
| `api-services` | LLM, Speech, Graph services |
|
|
273
279
|
| `api-testing` | createMockContext, test patterns |
|
|
274
|
-
| `api-utils` | Formatting, parsing, security, pagination, scheduling |
|
|
280
|
+
| `api-utils` | Formatting, parsing, security, pagination, scheduling, telemetry helpers |
|
|
281
|
+
| `api-telemetry` | OTel catalog: spans, metrics, completion logs, env config, cardinality rules |
|
|
275
282
|
| `api-workers` | Cloudflare Workers runtime |
|
|
276
283
|
|
|
277
284
|
When you complete a skill's checklist, check the boxes and add a completion timestamp at the end (e.g., `Completed: 2026-03-11`).
|
|
@@ -306,15 +313,18 @@ Each per-version file opens with YAML frontmatter:
|
|
|
306
313
|
|
|
307
314
|
```markdown
|
|
308
315
|
---
|
|
309
|
-
summary: One-line headline, ≤250 chars # required — powers the rollup index
|
|
310
|
-
breaking: false
|
|
316
|
+
summary: "One-line headline, ≤250 chars" # required — powers the rollup index
|
|
317
|
+
breaking: false # optional — true flags breaking changes
|
|
318
|
+
security: false # optional — true flags security fixes
|
|
311
319
|
---
|
|
312
320
|
|
|
313
321
|
# 0.1.0 — YYYY-MM-DD
|
|
314
322
|
...
|
|
315
323
|
```
|
|
316
324
|
|
|
317
|
-
`breaking: true` renders a `· ⚠️ Breaking` badge
|
|
325
|
+
`breaking: true` renders a `· ⚠️ Breaking` badge — use it when consumers must update code on upgrade (signature changes, removed APIs, config renames). `security: true` renders a `· 🛡️ Security` badge and pairs with a `## Security` body section. When both are set, badges render `· ⚠️ Breaking · 🛡️ Security`.
|
|
326
|
+
|
|
327
|
+
**Section order** (Keep a Changelog): Added, Changed, Deprecated, Removed, Fixed, Security. Include only sections with entries — don't ship empty headers.
|
|
318
328
|
|
|
319
329
|
---
|
|
320
330
|
|
package/templates/Dockerfile
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# This stage installs all dependencies (including dev), builds the TypeScript
|
|
5
5
|
# source code into JavaScript, and prepares the production assets.
|
|
6
6
|
# ==============================================================================
|
|
7
|
-
FROM oven/bun:1 AS build
|
|
7
|
+
FROM oven/bun:1.3 AS build
|
|
8
8
|
|
|
9
9
|
WORKDIR /usr/src/app
|
|
10
10
|
|
|
@@ -28,7 +28,7 @@ RUN bun run build
|
|
|
28
28
|
# application. It uses a slim base image and only includes production
|
|
29
29
|
# dependencies and build artifacts.
|
|
30
30
|
# ==============================================================================
|
|
31
|
-
FROM oven/bun:1-slim AS production
|
|
31
|
+
FROM oven/bun:1.3-slim AS production
|
|
32
32
|
|
|
33
33
|
WORKDIR /usr/src/app
|
|
34
34
|
|