Repository navigation
v0.8.0 — Scaffolds you can test
A scaffolded MCP server used to start with a greet tool that returned a string, and nothing to verify it. That is a poor thing for a scaffolder to teach: a tool description is a contract with a caller that cannot read your code, so an unverified contract is the default failure. Generated projects now start with a realistic example, a passing test suite, an AGENTS.md, and the tool-design skill.
Note: this changes what newly scaffolded projects look like. Existing generated projects are unaffected — they pin their own dependencies.
A worked example worth copying
The greet tool is gone. In its place is a small notes server designed against the tool-design principles, chosen so its contract has something to verify:
list_notes(tag?, limit=20) -> page + matched/returned/truncated + hint
get_note(id) -> the note, or an actionable isError
create_note(title, body, tags?) -> the note including its new id
notes://{id} -> ResourceTemplate, list implemented
summarize-notes -> prompt over a tag
It demonstrates four things a toy example cannot:
- Truncation is signalled, not silently applied. A capped list reports
matched: 30, returned: 5, truncated: trueplus a hint on how to narrow it. A tool that quietly caps results lies to the agent calling it. - An unknown filter is distinguishable from an empty result. Both return no rows; conflating them makes an agent report "you have none" when the truth is "you misspelled it".
- Failures return
isErrorwith a next move, not thrown exceptions or bare codes. - Results chain.
create_notereturns the id, so the agent can read it back without a lookup.
Tool names carry their noun but no server namespace — list_notes, not notes_list. Most MCP clients prepend the server name, so a hardcoded prefix would surface as my-server_notes_list.
Tests that run green immediately
SDK projects ship a working suite — no config to add:
src/notes-store.test.ts— the data layer on its own, no transport.src/server.test.ts— a real MCP client over an in-memory transport, asserting on the payload a tool actually returns.
Nine tests, deliberately. The suite is a template people copy, so each one pins something a tool's description promises and nothing else checks. None exercise the example's own data structures.
FastMCP projects keep their existing example and ship without tests for now.
Structure
server.ts is now a composition root; definitions live beside it:
src/
server.ts # creates the McpServer, registers the primitives
tools.ts # registerTools(server)
prompts.ts # registerPrompts(server)
resources.ts # registerResources(server)
notes-store.ts # data layer, no MCP imports
index.ts # transport wiring
Keeping the data layer free of MCP imports is what makes it testable without a server — and its state must stay at module scope, because createMcpHandler runs the server factory once per request.
AGENTS.md in every project
Written for whoever changes the project, as distinct from the README. It carries the traps that are invisible until they bite: state discarded between requests on HTTP, stdout belonging to the protocol on stdio, and OAuthError-not-Error when OAuth is enabled. Plus how to write a good tool, and how to organize tools as they grow — flat files, then src/tools/, then feature folders.
It stays example-agnostic, so it remains accurate after you delete the notes example.
The tool-design skill, bundled
Projects get Agentailor's tool-design skill at .agents/skills/tool-design/.
It is bundled with the CLI, not fetched — scaffolding needs no network and stays instant, and a given CLI version always emits a known version of the skill. It does age; pull a newer copy when you want one:
npx skills update -p -y.agents/ rather than .claude/, following the same move to tool-agnostic locations that AGENTS.md made. Pass --no-skills to skip it.
Dependency refresh
Templates move to TypeScript 7 (the Go-native compiler) and dotenv 18, both verified by generating and building every variant. Also @modelcontextprotocol/inspector 2.7, hono 4.13, zod 4.6, jose 6.2.12, fastmcp 4.20, @types/node 26.6.
update-template-deps now tags major bumps [MAJOR] and repeats them in a summary, so a compiler rewrite can't land unannounced.
Repo housekeeping
CLAUDE.md→AGENTS.md, the cross-agent convention.vitest.config.tsscopes the test run, so local scratch projects undergenerated/no longer leak into it.
New CLI option
| Option | Default | Description |
|---|---|---|
--no-skills |
false |
Skip adding the tool-design skill |
Upgrading
npx @agentailor/create-mcp-server@0.8.0Full changelog: v0.7.1...v0.8.0