@cyanheads/mcp-ts-core 0.4.1 → 0.5.2

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.
@@ -4,7 +4,7 @@ description: >
4
4
  Reference for core and server configuration in `@cyanheads/mcp-ts-core`. Covers env var tables with defaults, priority order, server-specific Zod schema pattern, and Workers lazy-parsing requirement.
5
5
  metadata:
6
6
  author: cyanheads
7
- version: "1.1"
7
+ version: "1.2"
8
8
  audience: external
9
9
  type: reference
10
10
  ---
@@ -189,9 +189,10 @@ Use the lazy init/accessor pattern — do not parse `process.env` at module top-
189
189
  ```ts
190
190
  // src/config/server-config.ts
191
191
  import { z } from '@cyanheads/mcp-ts-core';
192
+ import { parseEnvConfig } from '@cyanheads/mcp-ts-core/config';
192
193
 
193
194
  const ServerConfigSchema = z.object({
194
- myApiKey: z.string().describe('External API key'),
195
+ apiKey: z.string().describe('External API key'),
195
196
  maxResults: z.coerce.number().default(100),
196
197
  });
197
198
 
@@ -200,12 +201,23 @@ export type ServerConfig = z.infer<typeof ServerConfigSchema>;
200
201
  let _config: ServerConfig | undefined;
201
202
 
202
203
  export function getServerConfig(): ServerConfig {
203
- _config ??= ServerConfigSchema.parse({
204
- myApiKey: process.env.MY_API_KEY,
205
- maxResults: process.env.MY_MAX_RESULTS,
204
+ _config ??= parseEnvConfig(ServerConfigSchema, {
205
+ apiKey: 'MY_API_KEY',
206
+ maxResults: 'MY_MAX_RESULTS',
206
207
  });
207
208
  return _config;
208
209
  }
209
210
  ```
210
211
 
212
+ **Why `parseEnvConfig`?** It maps Zod schema paths to env var names so validation errors name the actual variable at fault. A missing `MY_API_KEY` produces:
213
+
214
+ ```
215
+ Server config validation failed:
216
+ - MY_API_KEY (apiKey): Invalid input: expected string, received undefined
217
+ ```
218
+
219
+ Instead of a raw `ZodError` dump at startup. The framework catches the resulting `ConfigurationError` and prints a clean banner (full stack behind `DEBUG=true`).
220
+
221
+ Direct `ServerConfigSchema.parse(...)` still works — the framework intercepts raw `ZodError` thrown from `setup()` and converts it — but error messages won't know about env var names, so they show the Zod path (`apiKey`) instead of the variable name (`MY_API_KEY`).
222
+
211
223
  **Workers:** Do not parse `process.env` at module top-level. In Workers, env bindings are injected at request time via `injectEnvVars()`, after all static imports. Lazy parsing is required.
@@ -4,7 +4,7 @@ description: >
4
4
  Exercise tools, resources, and prompts with real-world inputs to verify behavior end-to-end. Use after adding or modifying definitions, or when the user asks to test, try out, or verify their MCP surface. Calls each definition with realistic and adversarial inputs and produces a report of issues, pain points, and recommendations.
5
5
  metadata:
6
6
  author: cyanheads
7
- version: "1.1"
7
+ version: "1.2"
8
8
  audience: external
9
9
  type: debug
10
10
  ---
@@ -36,7 +36,7 @@ For every tool, resource, and prompt, run through these categories:
36
36
  | Category | What to test |
37
37
  |:---------|:-------------|
38
38
  | **Happy path** | Realistic input that should succeed. Verify output shape matches the output schema. Verify format function produces sensible content blocks. |
39
- | **`structuredContent` parity** | Compare the raw handler return, the data captured in `structuredContent`, and what `format()` renders into `content[]`. Flag fields or records that exist in the handler result or `structuredContent` but are absent from `content[]` unless the omission is explicit and acceptable for the tool's purpose. Most LLM clients only see `content[]`, so silent formatter drops are real bugs. |
39
+ | **`structuredContent` parity** | The `format-parity` lint rule already asserts every terminal field in the output schema appears in `format()`'s rendered text (via sentinel injection at startup). Field testing layers real-data checks on top: are values rendered accurately (not just their labels)? Do conditional-render branches in `format()` still render every field when specific values are present? Does the content look right to a human reading the LLM's view? |
40
40
  | **Variations** | Different valid input combinations — optional fields omitted, optional fields included, different enum values, min/max boundaries. |
41
41
  | **Field selection / projection** | For tools with `fields`, `include`, `expand`, `view`, or similar parameters, call the tool with non-default selections. Verify the handler returns the requested fields and `format()` renders each requested field rather than a hardcoded summary subset. |
42
42
  | **Edge cases** | Empty strings, zero values, very long inputs, special characters, Unicode. |
@@ -1,48 +1,167 @@
1
1
  ---
2
2
  name: maintenance
3
3
  description: >
4
- Sync skills and dependencies after package updates. Use after running `bun update @cyanheads/mcp-ts-core` to ensure project skills are up to date, or periodically to check for drift.
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: "1.2"
7
+ version: "1.3"
8
8
  audience: external
9
9
  type: workflow
10
10
  ---
11
11
 
12
- ## Context
12
+ ## When to Use
13
13
 
14
- Skills flow from the package to the project:
14
+ - After running `bun update --latest` yourself and wanting to review the impact (**Mode B** — typical)
15
+ - To run the whole flow end-to-end — outdated check → update → investigate → adopt → verify (**Mode A**)
16
+ - Periodically, to check for skill drift from the package
15
17
 
16
- 1. **Package** — `node_modules/@cyanheads/mcp-ts-core/skills/` (canonical source, updated via `bun update`)
17
- 2. **Project** — `skills/` at project root (working copy, can have local overrides or server-specific skills)
18
+ ## Entry Modes
18
19
 
19
- After `bun update @cyanheads/mcp-ts-core`, the package may have newer skills than the project. This skill syncs them and handles general dependency upkeep.
20
+ | Mode | Starting Point | First Step |
21
+ |:-----|:---------------|:-----------|
22
+ | **A — Full flow** | Lockfile is current; want to update | Step 1 |
23
+ | **B — Post-update review** | User already ran `bun update --latest` + `bun run rebuild` + `bun run test` | Skip to Step 3 with the update output or `git diff bun.lock` |
24
+
25
+ Both modes converge at Step 3 and end at Step 8.
20
26
 
21
27
  ## Steps
22
28
 
23
- ### Sync project skills (Package Project)
29
+ ### 1. Survey what's outdated (Mode A only)
30
+
31
+ ```bash
32
+ bun outdated
33
+ ```
34
+
35
+ Note: `bun update --latest` crosses semver majors; `bun update` alone respects ranges. Use `--latest` unless a package is intentionally pinned.
36
+
37
+ ### 2. Apply the update (Mode A only)
38
+
39
+ ```bash
40
+ bun update --latest
41
+ ```
42
+
43
+ Capture the `↑ package old → new` lines from stdout — these feed Step 3. Alternatively, `git diff bun.lock` surfaces version deltas after the fact.
44
+
45
+ ### 3. Investigate changelogs
46
+
47
+ Invoke the **`changelog`** skill with the captured list of updated packages. It resolves each repo, fetches release notes (or CHANGELOG entries) between old and new versions, and cross-references changes against actual imports in `src/`. Output per package: what changed, impact on this project, action items.
48
+
49
+ Do not redo this investigation inline — the `changelog` skill handles tag-format detection, monorepo patterns, and fallbacks.
50
+
51
+ ### 4. Framework review (`@cyanheads/mcp-ts-core`)
52
+
53
+ If `@cyanheads/mcp-ts-core` was updated, do a deeper pass beyond what the `changelog` skill covers. Read:
54
+
55
+ ```bash
56
+ node_modules/@cyanheads/mcp-ts-core/CHANGELOG.md
57
+ ```
58
+
59
+ Extract entries between the old and new version. Scan specifically for:
60
+
61
+ | Area | Adoption Check |
62
+ |:-----|:---------------|
63
+ | New error factories in `/errors` | Replace ad-hoc `new McpError(...)` with factories where applicable |
64
+ | New utilities in `/utils` | Identify any that supersede local helper code |
65
+ | New context capabilities | Added `ctx.*` methods worth adopting |
66
+ | Provider/service APIs | Updates to `OpenRouterProvider`, `SpeechService`, `GraphService`, etc. |
67
+ | Deprecations | Migrate now, before the next breaking release |
68
+ | Config changes | New env vars, renamed keys, changed defaults |
69
+ | Linter rules | New definition-lint rules that may now flag existing tools/resources |
70
+
71
+ Cross-reference each finding against the server's code. Collect adoption opportunities for Step 6.
72
+
73
+ **Template review.** The framework also ships `templates/CLAUDE.md` and `templates/AGENTS.md` as scaffolding for consumer agent protocol files. The consumer's `CLAUDE.md`/`AGENTS.md` was copied at init time and has since diverged (local customizations, echo replacements, server-specific sections). Read the upstream template fresh:
74
+
75
+ ```bash
76
+ node_modules/@cyanheads/mcp-ts-core/templates/CLAUDE.md
77
+ ```
78
+
79
+ Skip the mechanical diff — consumer customizations create too much noise to filter. Instead, read end-to-end with fresh eyes, mentally comparing against the current `CLAUDE.md`. Look for: new conventions, updated skill references, expanded checklists, new callouts, clearer explanations, restructured sections. Present findings; let the user cherry-pick what to adopt. Never auto-merge — the consumer's file is theirs.
80
+
81
+ ### 5. Sync project skills
82
+
83
+ Skills flow in two hops: package → project `skills/` → agent directories.
84
+
85
+ **Phase A — Package → Project `skills/`**
86
+
87
+ 1. **Package** — `node_modules/@cyanheads/mcp-ts-core/skills/` (canonical source)
88
+ 2. **Project** — `skills/` at project root (working copy; may contain local overrides or server-specific skills)
89
+
90
+ Procedure:
24
91
 
25
92
  1. List all skill directories in `node_modules/@cyanheads/mcp-ts-core/skills/`
26
93
  2. For each skill with `metadata.audience: external` in its `SKILL.md` frontmatter:
27
- - If the skill does not exist in project `skills/`, copy the full directory
28
- - If it exists, compare `metadata.version` — if the package version is newer, replace the full directory
94
+ - If missing in project `skills/`, copy the full directory
95
+ - If present, compare `metadata.version` — replace if the package version is newer
29
96
  - If the local version is equal or newer, skip (local override)
30
97
  3. Do not touch skills in `skills/` that don't exist in the package (server-specific)
31
98
 
32
- ### Dependency updates
99
+ **Phase B — Project `skills/` → Agent directories**
100
+
101
+ The `setup` skill instructs consumers to copy `skills/*` into their agent's skill directory at init time. Those copies go stale unless re-synced. Detect which agent directories exist and propagate:
102
+
103
+ | Agent | Directory |
104
+ |:------|:----------|
105
+ | Claude Code | `.claude/skills/` |
106
+ | Generic / shared | `.agents/skills/` |
107
+ | Codex | `.codex/skills/` |
108
+ | Cursor | `.cursor/skills/` |
109
+ | Windsurf | `.windsurf/skills/` |
110
+
111
+ For each agent directory that exists:
112
+
113
+ 1. For every directory in project `skills/`, copy it into the agent dir (overwrite on match, add if missing)
114
+ 2. Do **not** delete skills in the agent dir that aren't in project `skills/` — they may be general-purpose skills sourced elsewhere (e.g., `code-security`, `cloudflare`, `changelog`)
115
+
116
+ If no agent directory exists, skip Phase B — the project hasn't opted in to per-agent skill copies.
117
+
118
+ **Report** which skills were added/updated in Phase A (with version deltas) and which agent directories were refreshed in Phase B. The user needs to know what new guidance is now available and where.
119
+
120
+ ### 6. Adopt changes in the codebase
121
+
122
+ Apply the findings from Steps 3 and 4:
123
+
124
+ - **Breaking changes** — fix call sites
125
+ - **Deprecations** — migrate now, while context is fresh
126
+ - **New framework features** — refactor targeted spots only; don't cargo-cult everywhere
127
+ - **New configuration** — update `.env.example`, server config schema, README if user-facing
128
+
129
+ Keep diffs focused. Don't sweep refactors beyond the update's scope.
130
+
131
+ ### 7. Rebuild and verify
132
+
133
+ ```bash
134
+ bun run rebuild
135
+ bun run devcheck
136
+ bun run test
137
+ ```
138
+
139
+ `rebuild` (clean + build) catches API surface and type-alignment issues that `devcheck` alone may miss — module resolution, path aliases, post-build processing. `devcheck` includes `bun audit` and `bun outdated`, so no separate audit step is needed.
140
+
141
+ In **Mode B**, the user already ran rebuild + test before invoking this skill, but run them again here — Step 6 made code changes that need verification.
142
+
143
+ Fix anything that fails. Re-run until clean.
144
+
145
+ ### 8. Summary
146
+
147
+ Present a concise numbered summary to the user:
33
148
 
34
- 1. Run `bun outdated` to see what's available
35
- 2. For any major version bumps, review changelogs before proceeding
36
- 3. Run `bun update` to apply updates
37
- 4. Run `bun audit` to check for vulnerabilities introduced by the update
38
- 5. Run `bun run devcheck` to confirm lint, definitions, types, and dependency/security checks still pass
39
- 6. Run `bun run test` to confirm runtime behavior still passes
149
+ 1. **Updated packages** short list with version deltas (N total)
150
+ 2. **Breaking changes handled** call sites fixed
151
+ 3. **Features adopted** new framework APIs now in use
152
+ 4. **Skills synced** added/updated with versions (Phase A) and agent directories refreshed (Phase B)
153
+ 5. **Needs attention** anything deferred, flagged for decision, or risky
154
+ 6. **Status** rebuild / devcheck / test results
40
155
 
41
156
  ## Checklist
42
157
 
43
- - [ ] Package skills compared against project `skills/` (version check)
44
- - [ ] New or updated skills copied to project `skills/`
45
- - [ ] Dependencies updated (`bun update`)
46
- - [ ] `bun audit` passes (no new vulnerabilities)
47
- - [ ] `bun run devcheck` passes
158
+ - [ ] Update applied (`bun update --latest`) Mode A, or already done by user — Mode B
159
+ - [ ] `changelog` skill invoked for each updated package
160
+ - [ ] Framework CHANGELOG reviewed if `@cyanheads/mcp-ts-core` was updated
161
+ - [ ] Adoption opportunities identified and applied
162
+ - [ ] Project `skills/` synced from package (Phase A), with a change report
163
+ - [ ] Agent skill directories (`.claude/skills/`, `.agents/skills/`, etc.) refreshed from project `skills/` (Phase B)
164
+ - [ ] `bun run rebuild` succeeds
165
+ - [ ] `bun run devcheck` passes (includes audit + outdated)
48
166
  - [ ] `bun run test` passes
167
+ - [ ] Numbered summary presented to user
@@ -4,7 +4,7 @@ description: >
4
4
  Finalize documentation and project metadata for a ship-ready MCP server. Use after implementation is complete, tests pass, and devcheck is clean. Safe to run at any stage — each step checks current state and only acts on what still needs work.
5
5
  metadata:
6
6
  author: cyanheads
7
- version: "1.3"
7
+ version: "1.4"
8
8
  audience: external
9
9
  type: workflow
10
10
  ---
@@ -48,7 +48,7 @@ Capture: tool count, resource count, prompt count, service count, required env v
48
48
 
49
49
  Read `references/readme.md` for structure and conventions. If `README.md` doesn't exist, create it from scratch. If it exists, diff the current content against the audit — update tool/resource/prompt tables, env var lists, and descriptions to match the actual surface area. Don't rewrite sections that are already accurate.
50
50
 
51
- The header tagline (`<p><b>...</b></p>`) must match the `package.json` `description`.
51
+ The bold header tagline (the `<b>` text inside the first `<p>`) must match the `package.json` `description`. The surface count is a nested `<div>` inside the same `<p>`, separated by `•`.
52
52
 
53
53
  ### 3. Agent Protocol (CLAUDE.md / AGENTS.md)
54
54