leehack/mcp_dart/mcp-dart-server
Claude Code and agent skill by leehack/mcp_dart
- community
Checking that the SKILL.md file is still in the repository.
Use when building or extending a Model Context Protocol (MCP) server in Dart with mcp_dart: structuring the project, creating an McpServer, adding tools, resources, resource templates or prompts, returning tool results and errors, reporting progress, running over stdio, or testing the server.
Install
npx vskill@latest install leehack/mcp_dart/mcp-dart-serverSKILL.md
Building an MCP server with mcp_dart
McpServer exposes tools, resources and prompts to MCP clients. By default it speaks MCP 2026-07-28 and falls back to initialization-era versions (MCP 2025-11-25 and earlier) for legacy clients. Import everything from package:mcp_dart/mcp_dart.dart.
Project structure
Keep MCP wiring thin and separate from the application's logic. This is the layout that mcp_dart create generates; use it for hand-written servers too:
- If
lib/mcp/tools/base_tool.dartalready exists, the project came from
mcp_dart create. Follow it: add a BaseTool subclass and list it in createAllTools(), and use BaseResource/BasePrompt the same way. Do not add inline registerTool calls beside that pattern.
- To start a new standalone server,
dart pub global activate mcp_dart_cli
then mcp_dart create my_server (the CLI needs Dart 3.12; the generated project adds args and logging and targets Dart 3.4). Adding a server to an existing package needs only dart pub add mcp_dart.
- Tool classes are adapters: parse arguments, call a domain service, map
domain failures to CallToolResult(isError: true). Keep business rules, I/O and state in lib/src/ so they are testable without MCP.
- Build services once in
bin/server.dartand pass them to
createMcpServer. Never create state inside a tool call or inside a Streamable HTTP serverFactory, which runs per request or session.
- Read configuration and secrets at startup (arguments, environment) and pass
them in. Never log secrets or read them inside handlers.
Guidelines
- Create the server with
McpServer(Implementation(name:, version:)). The
register* methods advertise the tools, resources and prompts capabilities automatically; pass McpServerOptions(capabilities: ...) only for extra flags such as listChanged or subscribe, and advertise only what the server actually implements.
- Keep the default
McpProtocol.stableprofile. Use
McpServerOptions(protocol: McpProtocol.legacy) or McpProtocol.require2026 only when a deployment must pin one protocol era.
- Register everything before
connect. OneMcpServerinstance owns one
transport; build a fresh instance per transport from createMcpServer.
- Describe tool inputs with
JsonSchema.object(properties: ..., required: ...).
The SDK validates arguments before the callback runs, so the callback may cast declared fields (args['a'] as num). Still validate business rules.
- Tool callbacks take
(Map<String, dynamic> args, RequestHandlerExtra extra)
and return CallToolResult. Return CallToolResult(isError: true, ...) for expected domain failures (not found, bad input, upstream API errors) so the model can recover. Throw McpError(ErrorCode.x.value, message) only for protocol-level failures.
- For typed output, declare
outputSchemaand return
CallToolResult.fromStructuredContent({...}); it also fills content with the serialized JSON for clients that ignore structured content.
- Set
ToolAnnotations(readOnlyHint: true),destructiveHint,
idempotentHint or openWorldHint honestly; they are hints, not access control.
- Long-running tools call
extra.sendProgress(done, total: n, message: ...)
(a no-op when the client sent no progress token) and check extra.signal.aborted to stop promptly after cancellation.
- Resources:
registerResource(name, uri, (description:, mimeType:), callback)
for fixed URIs; registerResourceTemplate(name, ResourceTemplateRegistration('scheme://{var}', listCallback: null), ...) for URI families. Return contents whose uri is the concrete requested URI. For an unknown URI, throw McpError with invalidParams for MCP 2026-07-28 requests and resourceNotFound for legacy ones.
- Prompts:
registerPrompt(name, argsSchema: {...}, callback: ...). The
prompt callback's args and extra are nullable.
- A callback that must ask the client for more input mid-call (MCP 2026-07-28
InputRequiredResult) needs the registerStateless* counterpart. Use the plain register* methods otherwise.
- Stdio servers must write only MCP frames to stdout. Send application logs
to stderr, never print. Tune SDK-internal logs with setMcpLogHandler or silenceMcpLogs.
- Each incoming stdio message is limited to 10 MiB by default; raise it with
StdioServerTransport(maxIncomingMessageBytes: ...) only when needed, and keep it finite.
- Test through a real client over an in-process
IOStreamTransportpair with
fake or in-memory services. Check a running server by hand with mcp_dart inspect (the CLI's mcp_dart skills install adds a debugging workflow skill for its inspect and trace commands).
Examples
A complete server in the layout above. Each block is one file, named by its first line; my_server is the package name.
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 95 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/mcp-dart-server/SKILL.md
Popularity
- 7-day trend score
- 5
Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/leehack/mcp_dart/mcp-dart-server)