When to Use
You've isolated a problem to @cyanheads/mcp-ts-core itself — not your server code, not a misconfiguration, not a missing peer dependency. Typical triggers:
- Framework builder (
tool(), resource(), prompt()) rejects valid input or produces incorrect output
createApp() or createWorkerHandler() fails on a valid config
Context properties (ctx.log, ctx.state, ctx.inputs, etc.) behave contrary to docs
- A utility from
/utils, /errors, /auth, /storage, /services returns wrong results or throws unexpectedly
- Type exports are incorrect or missing (compile error on documented usage)
- The definition linter (
bun run lint:mcp) produces false positives or misses real violations
For general gh CLI workflows outside issue filing (PRs, workflows, API access), see the github-cli skill.
Before Filing
- Confirm framework version —
bun pm ls @cyanheads/mcp-ts-core or check node_modules/@cyanheads/mcp-ts-core/package.json
- Check you're on latest —
bun outdated @cyanheads/mcp-ts-core. If behind, update and retest before filing.
- Isolate the issue — reproduce with a minimal handler or standalone script. Strip server-specific services, config, and dependencies. If the bug disappears when isolated, it's likely in your server code.
- Search existing issues — don't file duplicates:
gh issue list -R cyanheads/mcp-ts-core --search "your error message or keyword" --state all
# Assess a close match before commenting — is it already linked to a fix or referenced elsewhere?
gh issue view <number> -R cyanheads/mcp-ts-core --comments
gh api 'repos/cyanheads/mcp-ts-core/issues/<number>/timeline' --paginate \
--jq '.[] | select(.event=="cross-referenced") | .source.issue | "\(.repository.full_name)#\(.number) — \(.title)"'
- For documentation- or contract-shaped requests, audit all three doc layers first — proposals to add reference docs, public-API conventions, attribute/event catalogs, or stability commitments often duplicate surface that already exists. Check
src/ for behavior, docs/ for human-facing reference, and skills/ for agent-facing reference. Skill files marked audience: external are the framework's public contract — treat them as authoritative when evaluating whether a documentation gap exists. Also verify the constants or types you'd reference aren't already exported from @cyanheads/mcp-ts-core or one of its subpaths.
Writing Well-Structured Issues
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).
- 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.
- 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.
- 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.
- Add a
Related: #N line near the top when the issue grows from prior context (discussions, other issues, PRs). Makes provenance clickable.
- 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.
- 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.
- Prefer Markdown tables for comparisons. When showing options, tiers, strategies, or tradeoffs — tables are the highest-density format for scanning N rows × M attributes.
- 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.
- Use
Depends on: owner/repo#N to declare ordering explicitly when implementation is blocked on another issue landing first.
- 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.
- 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.
Redact Before Posting
GitHub issues are public. Do not include secrets, credentials, API keys, or tokens. Redact sensitive values from env vars, headers, and logs before submitting. Replace with obvious placeholders: REDACTED, sk-...REDACTED. Do not rely on partial masking — partial keys can still be exploited.
Filing a Bug
The repo has YAML form issue templates. Use --web to open the form in the browser (preferred when available), or pass --title + --body for non-interactive use.
Browser (interactive)
gh issue create -R cyanheads/mcp-ts-core --template "Bug Report" --web
CLI (non-interactive)
Structure the --body to match the template's form fields:
gh issue create -R cyanheads/mcp-ts-core \
--title "bug(scope): concise description" \
--label "bug" \
--assignee "@me" \
--body "$(cat <<'ISSUE'
### mcp-ts-core version
0.1.29
### Runtime
Bun
### Runtime version
Bun 1.3.x
### Transport
stdio
### OS
macOS 15.x
### Description
Brief explanation of the bug — what you expected vs what happened.
### Reproduction
```ts
import { tool, z } from '@cyanheads/mcp-ts-core';
export const broken = tool('broken_example', {
description: 'Minimal repro.',
input: z.object({ id: z.string().describe('ID') }),
output: z.object({
name: z.string().describe('Name'),
extra: z.string().optional().describe('Optional field'),
}),
async handler(input, ctx) {
return { name: 'test' }; // omitting optional field causes validation error
},
});
```
### Actual behavior
```
Error: Output validation failed: ...
```
### Expected behavior
Omitting an optional output field should pass validation.
### Additional context
Any workarounds, related issues, or observations.
ISSUE
)"
Title conventions
Format: bug(<scope>): concise description
| Scope |
When |
tool |
Tool builder, handler, format, annotations |
resource |
Resource builder, handler, list, params |
prompt |
Prompt builder, generate, args |
context |
Context, logger, state, progress, elicit |
config |
AppConfig, parseConfig, env parsing |
errors |
McpError, error factories, typed contracts (errors[] / ctx.fail), conformance lint, httpErrorFromResponse, auto-classification |
auth |
Auth modes, scope checking, JWT/OAuth |
storage |
StorageService, providers |
transport |
stdio/http transport, SSE, session handling |
worker |
createWorkerHandler, Worker runtime |
utils |
Utilities (formatting, parsing, pagination, etc.) |
linter |
Definition linter false positives/negatives |
types |
Type exports, type inference |
services |
LLM, Speech, Graph services |
deps |
Dependency issues, peer dep conflicts |
Labels
Every issue needs exactly one primary label. Stack secondary labels on top when applicable.
Primary (required — pick one):
| Label |
When |
bug |
Something broken |
enhancement |
Feature request or improvement |
documentation |
Documentation is wrong, missing, or misleading |
Secondary (optional — stack on top of primary):
| Label |
When |
regression |
Worked before, broken after an update |
performance |
Memory, CPU, latency, or resource usage |
security |
Vulnerability, CVE, or hardening work |
breaking-change |
Fix/feature will break public API; requires a major bump |
surplus-token-idea |
Worth exploring when token budget allows |
Combine labels: --label "bug" --label "regression".
Attaching logs or stack traces
For long output, write to a file and attach. Note: --body-file replaces the entire body — it does not supplement a --body flag. For structured bugs with logs, either embed the log content in the Additional context section of a normal --body, or file the issue first and add the log as a comment:
bun run rebuild && bun run start:stdio 2>&1 | head -100 > /tmp/mcp-error.log
# As part of a new issue (the log becomes the entire body — no template fields)
gh issue create -R cyanheads/mcp-ts-core \
--title "bug(transport): stdio crashes on large payload" \
--label "bug" \
--assignee "@me" \
--body-file /tmp/mcp-error.log
# Or as a comment on an existing issue
gh issue comment <number> -R cyanheads/mcp-ts-core --body-file /tmp/mcp-error.log
Filing a Feature Request
Browser (interactive)
gh issue create -R cyanheads/mcp-ts-core --template "Feature Request" --web
CLI (non-interactive)
Template below demonstrates the richer structure. Omit sections you don't need — simple requests don't require Flow / Design / Dependencies blocks.
gh issue create -R cyanheads/mcp-ts-core \
--title "feat(scope): concise description" \
--label "enhancement" \
--assignee "@me" \
--body "$(cat <<'ISSUE'
Concrete statement of what's currently missing or broken in the framework. Name the specific builder, utility, context method, or config field. Two or three sentences — the reader should know the gap before the end of the paragraph.
Related: #N
## Proposal
What you want the framework to do, in one paragraph. Link external libraries on first mention: [lib name](https://github.com/owner/repo). Include a short justification — what this gives us that we don't have today.
### Proposed API
```ts
import { withRetry } from '@cyanheads/mcp-ts-core/utils';
const result = await withRetry(() => fetchExternal(url), {
maxAttempts: 3,
backoff: 'exponential',
});
```
### Flow (optional)
Ordered steps — e.g. `trigger → resolve → fetch → degrade`. Useful when the change spans multiple phases or fallbacks.
### Design / Tradeoffs (optional)
Philosophy: **one-line principle in bold.**
| Option | Strengths | Weaknesses |
|:---|:---|:---|
| A | ... | ... |
| B | ... | ... |
### Scope
- Files or modules touched
- New exports, env vars, or config keys
- Tier (Tier 1 core / Tier 2 standard / Tier 3 optional peer dep)
### Out of scope
- What we're deliberately not doing
- Adjacent work that belongs in a separate issue
### Dependencies (optional)
- Depends on: owner/repo#N
### Alternatives considered
What you tried or evaluated instead, and why it didn't fit.
ISSUE
)"
Following Up
# Check issue status (with comment thread)
gh issue view <number> -R cyanheads/mcp-ts-core --comments
# Add context or respond to maintainer questions
gh issue comment <number> -R cyanheads/mcp-ts-core --body "Additional context..."
# List your open issues
gh issue list -R cyanheads/mcp-ts-core --author @me
Checklist
1---
2name: report-issue-framework
3description: >
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.
5metadata:
6 author: cyanheads
7 version: "1.9"
8 audience: external
9 type: workflow
10---
11
12## When to Use
13
14You've isolated a problem to `@cyanheads/mcp-ts-core` itself — not your server code, not a misconfiguration, not a missing peer dependency. Typical triggers:
15
16- Framework builder (`tool()`, `resource()`, `prompt()`) rejects valid input or produces incorrect output
17- `createApp()` or `createWorkerHandler()` fails on a valid config
18- `Context` properties (`ctx.log`, `ctx.state`, `ctx.inputs`, etc.) behave contrary to docs
19- A utility from `/utils`, `/errors`, `/auth`, `/storage`, `/services` returns wrong results or throws unexpectedly
20- Type exports are incorrect or missing (compile error on documented usage)
21- The definition linter (`bun run lint:mcp`) produces false positives or misses real violations
22
23For general `gh` CLI workflows outside issue filing (PRs, workflows, API access), see the `github-cli` skill.
24
25## Before Filing
26
271. **Confirm framework version** — `bun pm ls @cyanheads/mcp-ts-core` or check `node_modules/@cyanheads/mcp-ts-core/package.json`
282. **Check you're on latest** — `bun outdated @cyanheads/mcp-ts-core`. If behind, update and retest before filing.
293. **Isolate the issue** — reproduce with a minimal handler or standalone script. Strip server-specific services, config, and dependencies. If the bug disappears when isolated, it's likely in your server code.
304. **Search existing issues** — don't file duplicates:
31
32```bash
33gh issue list -R cyanheads/mcp-ts-core --search "your error message or keyword" --state all
34
35# Assess a close match before commenting — is it already linked to a fix or referenced elsewhere?
36gh issue view <number> -R cyanheads/mcp-ts-core --comments
37gh api 'repos/cyanheads/mcp-ts-core/issues/<number>/timeline' --paginate \
38 --jq '.[] | select(.event=="cross-referenced") | .source.issue | "\(.repository.full_name)#\(.number) — \(.title)"'
39```
40
415. **For documentation- or contract-shaped requests, audit all three doc layers first** — proposals to add reference docs, public-API conventions, attribute/event catalogs, or stability commitments often duplicate surface that already exists. Check `src/` for behavior, `docs/` for human-facing reference, and `skills/` for agent-facing reference. Skill files marked `audience: external` are the framework's public contract — treat them as authoritative when evaluating whether a documentation gap exists. Also verify the constants or types you'd reference aren't already exported from `@cyanheads/mcp-ts-core` or one of its subpaths.
42
43## Writing Well-Structured Issues
44
45Good 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).
46
47- **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.
48- **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.
49- **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.
50- **Add a `Related: #N` line** near the top when the issue grows from prior context (discussions, other issues, PRs). Makes provenance clickable.
51- **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.
52- **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.
53- **Prefer Markdown tables for comparisons.** When showing options, tiers, strategies, or tradeoffs — tables are the highest-density format for scanning N rows × M attributes.
54- **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.
55- **Use `Depends on: owner/repo#N`** to declare ordering explicitly when implementation is blocked on another issue landing first.
56- **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- **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
59## Redact Before Posting
60
61GitHub issues are **public**. Do not include secrets, credentials, API keys, or tokens. Redact sensitive values from env vars, headers, and logs before submitting. Replace with obvious placeholders: `REDACTED`, `sk-...REDACTED`. Do not rely on partial masking — partial keys can still be exploited.
62
63## Filing a Bug
64
65The repo has YAML form issue templates. Use `--web` to open the form in the browser (preferred when available), or pass `--title` + `--body` for non-interactive use.
66
67### Browser (interactive)
68
69```bash
70gh issue create -R cyanheads/mcp-ts-core --template "Bug Report" --web
71```
72
73### CLI (non-interactive)
74
75Structure the `--body` to match the template's form fields:
76
77````bash
78gh issue create -R cyanheads/mcp-ts-core \
79 --title "bug(scope): concise description" \
80 --label "bug" \
81 --assignee "@me" \
82 --body "$(cat <<'ISSUE'
83### mcp-ts-core version
84
850.1.29
86
87### Runtime
88
89Bun
90
91### Runtime version
92
93Bun 1.3.x
94
95### Transport
96
97stdio
98
99### OS
100
101macOS 15.x
102
103### Description
104
105Brief explanation of the bug — what you expected vs what happened.
106
107### Reproduction
108
109```ts
110import { tool, z } from '@cyanheads/mcp-ts-core';
111
112export const broken = tool('broken_example', {
113 description: 'Minimal repro.',
114 input: z.object({ id: z.string().describe('ID') }),
115 output: z.object({
116 name: z.string().describe('Name'),
117 extra: z.string().optional().describe('Optional field'),
118 }),
119 async handler(input, ctx) {
120 return { name: 'test' }; // omitting optional field causes validation error
121 },
122});
123```
124
125### Actual behavior
126
127```
128Error: Output validation failed: ...
129```
130
131### Expected behavior
132
133Omitting an optional output field should pass validation.
134
135### Additional context
136
137Any workarounds, related issues, or observations.
138ISSUE
139)"
140````
141
142### Title conventions
143
144Format: `bug(<scope>): concise description`
145
146| Scope | When |
147|:------|:-----|
148| `tool` | Tool builder, handler, format, annotations |
149| `resource` | Resource builder, handler, list, params |
150| `prompt` | Prompt builder, generate, args |
151| `context` | Context, logger, state, progress, elicit |
152| `config` | AppConfig, parseConfig, env parsing |
153| `errors` | McpError, error factories, typed contracts (`errors[]` / `ctx.fail`), conformance lint, `httpErrorFromResponse`, auto-classification |
154| `auth` | Auth modes, scope checking, JWT/OAuth |
155| `storage` | StorageService, providers |
156| `transport` | stdio/http transport, SSE, session handling |
157| `worker` | createWorkerHandler, Worker runtime |
158| `utils` | Utilities (formatting, parsing, pagination, etc.) |
159| `linter` | Definition linter false positives/negatives |
160| `types` | Type exports, type inference |
161| `services` | LLM, Speech, Graph services |
162| `deps` | Dependency issues, peer dep conflicts |
163
164### Labels
165
166Every issue needs exactly one primary label. Stack secondary labels on top when applicable.
167
168**Primary (required — pick one):**
169
170| Label | When |
171|:------|:-----|
172| `bug` | Something broken |
173| `enhancement` | Feature request or improvement |
174| `documentation` | Documentation is wrong, missing, or misleading |
175
176**Secondary (optional — stack on top of primary):**
177
178| Label | When |
179|:------|:-----|
180| `regression` | Worked before, broken after an update |
181| `performance` | Memory, CPU, latency, or resource usage |
182| `security` | Vulnerability, CVE, or hardening work |
183| `breaking-change` | Fix/feature will break public API; requires a major bump |
184| `surplus-token-idea` | Worth exploring when token budget allows |
185
186Combine labels: `--label "bug" --label "regression"`.
187
188### Attaching logs or stack traces
189
190For long output, write to a file and attach. Note: `--body-file` replaces the entire body — it does not supplement a `--body` flag. For structured bugs with logs, either embed the log content in the `Additional context` section of a normal `--body`, or file the issue first and add the log as a comment:
191
192```bash
193bun run rebuild && bun run start:stdio 2>&1 | head -100 > /tmp/mcp-error.log
194
195# As part of a new issue (the log becomes the entire body — no template fields)
196gh issue create -R cyanheads/mcp-ts-core \
197 --title "bug(transport): stdio crashes on large payload" \
198 --label "bug" \
199 --assignee "@me" \
200 --body-file /tmp/mcp-error.log
201
202# Or as a comment on an existing issue
203gh issue comment <number> -R cyanheads/mcp-ts-core --body-file /tmp/mcp-error.log
204```
205
206## Filing a Feature Request
207
208### Browser (interactive)
209
210```bash
211gh issue create -R cyanheads/mcp-ts-core --template "Feature Request" --web
212```
213
214### CLI (non-interactive)
215
216Template below demonstrates the richer structure. Omit sections you don't need — simple requests don't require Flow / Design / Dependencies blocks.
217
218````bash
219gh issue create -R cyanheads/mcp-ts-core \
220 --title "feat(scope): concise description" \
221 --label "enhancement" \
222 --assignee "@me" \
223 --body "$(cat <<'ISSUE'
224Concrete statement of what's currently missing or broken in the framework. Name the specific builder, utility, context method, or config field. Two or three sentences — the reader should know the gap before the end of the paragraph.
225
226Related: #N
227
228## Proposal
229
230What you want the framework to do, in one paragraph. Link external libraries on first mention: [lib name](https://github.com/owner/repo). Include a short justification — what this gives us that we don't have today.
231
232### Proposed API
233
234```ts
235import { withRetry } from '@cyanheads/mcp-ts-core/utils';
236
237const result = await withRetry(() => fetchExternal(url), {
238 maxAttempts: 3,
239 backoff: 'exponential',
240});
241```
242
243### Flow (optional)
244
245Ordered steps — e.g. `trigger → resolve → fetch → degrade`. Useful when the change spans multiple phases or fallbacks.
246
247### Design / Tradeoffs (optional)
248
249Philosophy: **one-line principle in bold.**
250
251| Option | Strengths | Weaknesses |
252|:---|:---|:---|
253| A | ... | ... |
254| B | ... | ... |
255
256### Scope
257
258- Files or modules touched
259- New exports, env vars, or config keys
260- Tier (Tier 1 core / Tier 2 standard / Tier 3 optional peer dep)
261
262### Out of scope
263
264- What we're deliberately not doing
265- Adjacent work that belongs in a separate issue
266
267### Dependencies (optional)
268
269- Depends on: owner/repo#N
270
271### Alternatives considered
272
273What you tried or evaluated instead, and why it didn't fit.
274ISSUE
275)"
276````
277
278## Following Up
279
280```bash
281# Check issue status (with comment thread)
282gh issue view <number> -R cyanheads/mcp-ts-core --comments
283
284# Add context or respond to maintainer questions
285gh issue comment <number> -R cyanheads/mcp-ts-core --body "Additional context..."
286
287# List your open issues
288gh issue list -R cyanheads/mcp-ts-core --author @me
289```
290
291## Checklist
292
293- [ ] Confirmed bug is in `@cyanheads/mcp-ts-core`, not server code
294- [ ] Running latest (or documented) framework version
295- [ ] Searched existing issues — no duplicate found
296- [ ] If documentation or contract enhancement: confirmed `src/`, `docs/`, `skills/`, and public exports don't already cover the surface
297- [ ] All secrets, credentials, and tokens redacted
298- [ ] Primary label assigned (`bug` / `enhancement` / `documentation`)
299- [ ] If bug: version, runtime, repro code, actual vs expected behavior included
300- [ ] If feature: Proposal and Scope sections present; Out of scope defined