🦨 MCP SDK Developer Guide: Code Like It’s 10,000 B.C.


🦴 What Is MCP SDK?

You are a primitive developer. The world is cold. You must survive.

MCP SDK is your flint and fire β€” a Dart package that lets you build AI-powered servers using:

  • Tools – Actions the AI can perform (like hitting things with a big rock)
  • Prompts – Phrases the AI repeats (tribal chants, but for output)
  • Resources – Data and files the AI can read (cave drawings)

You’re not writing software. You’re building the first digital tribe. And MCP is the torch.


πŸ”¨ Why Expose Tools, Prompts, and Resources?

Tools – "AI, go do thing."

  • Think: API endpoints, but with more grunting.
  • You give the AI a function it can call, like:
    • Checking if a Dart package exists
    • Querying a database
    • Running some logic
    • Controlling a thing that beeps

Example: You build FireLookup β€” a tool that looks into the smoke and checks pub.dev for signs of a Dart package.


Prompts – "AI, talk like this."

  • Think: pre-written speech scrolls, but passed around the fire.
  • You give the AI a tone or task:
    • Be a code reviewer
    • Answer customer support
    • Start a story
    • Fill in structured info

Example: Use CodeCritic, a prompt that reviews your code like a cranky cave elder who hates tabs.


Resources – "AI, go read wall."

  • Think: shared files, but they’re sacred cave scribbles.
  • AI can inspect:
    • Source code
    • Docs
    • Images or audio
    • Database schemas

Example: Expose your project files so the AI can make suggestions or just stare in horror at your main.dart.


πŸ› οΈ How MCP SDK Helps You Not Die

You don’t need to handcraft JSON spells or chant schemas into the void.
Just:

  1. Annotate Dart classes with @McpTool, @McpPrompt
  2. Implement execute() – the action or response
  3. Run code gen with build_runner (like automated mammoth hunting)
  4. Register with your server – add it to the tribal knowledge

The SDK will:

  • Serialize data (grunts β†’ symbols)
  • Generate schemas (ritual circles)
  • Register handlers (tribal assignments)
  • Dispatch calls (yell and stuff happens)

πŸ”₯ FireLookup: When You Need to Know if the Package is Real

@McpTool(
  name: 'check_pub_package',
  description: 'Peers into pub.dev to check if a Dart package exists and its latest version.',
)
@JsonSerializable()
class CheckPubPackageArgs {
  @McpToolArg(description: 'Package name', required: true)
  final String packageName;

  const CheckPubPackageArgs({required this.packageName});

  factory CheckPubPackageArgs.fromJson(Map<String, dynamic> json) =>
      _$CheckPubPackageArgsFromJson(json);

  Map<String, dynamic> toJson() => _$CheckPubPackageArgsToJson(this);

  // This is the part where we poke the fire and hope it talks back.
  FutureOr<CallToolResult> execute() async {
    final info = await fetchPubPackageInfo(packageName);
    if (info == null) {
      return CallToolResult(content: [
        TextContent(text: 'πŸ”₯ No fire. "$packageName" not found on pub.dev.')
      ], isError: true);
    }
    return CallToolResult(content: [
      TextContent(text: 'πŸ”₯ Fire shows "$packageName". Latest version: \${info.version}')
    ]);
  }
}

Register it:

server.registerCheckPubPackageTool(); // You may grunt here if necessary.

πŸ§“ CodeCritic: The Village Elder Who Judges All Code

@McpPrompt(
  name: 'code_review_spell',
  description: 'An old village coder reviews your code.',
)
@JsonSerializable()
class CodeReviewSpellArgs {
  @McpPromptArg(description: 'Code snippet', required: true)
  final String code;

  const CodeReviewSpellArgs({required this.code});

  factory CodeReviewSpellArgs.fromJson(Map<String, dynamic> json) =>
      _$CodeReviewSpellArgsFromJson(json);

  Map<String, dynamic> toJson() => _$CodeReviewSpellArgsToJson(this);

  FutureOr<GetPromptResult> execute() {
    return GetPromptResult(messages: [
      PromptMessage(
        role: PromptMessageRole.user,
        content: TextContent(
          text: 'πŸ§“ CodeCritic speaks:\n"This code:\n\$code\n...it weak. Needs more strength. Use less fire, more logic."',
        ),
      )
    ]);
  }
}

Register the wisdom:

server.registerCodeReviewSpellPrompt();

🩡 Resources: Let AI Read the Cave Wall

  • Implement a resource provider
  • Share file URIs like file:///path/to/fossil.dart
  • AI can:
    • List files
    • Read them
    • Subscribe to changes (magic smoke updates)

Use Case: AI can now peek at your source code, and maybe suggest a better wheel.


🏑 Setup: Tell the Tribe What You Can Do

final serverCapabilities = ServerCapabilities(
  tools: ServerCapabilitiesTools(listChanged: true),
  prompts: ServerCapabilitiesPrompts(listChanged: true),
  resources: ServerCapabilitiesResources(listChanged: true, subscribe: true),
);

You now have a fire pit. You now have knowledge.
You are ready to build.


🐾 Summary: For the Hunter Who Reads No Scrolls

  • MCP SDK turns Dart code into AI-callable things
  • FireLookup is your package-checking tool
  • CodeCritic is your reusable grump prompt
  • Resources are your files, for AI to scan like ancient runes
  • Minimal setup: Annotate β†’ Implement β†’ Generate β†’ Register β†’ Profit? Probably not.

Now go, cave coder. Bang rocks together until your server hums. Then teach the AI to do it better.

Libraries

builder
mcp_sdk
Support for the Model Context Protocol (MCP) SDK, including client and server implementations.