0Pricing
Claude Architect · Lesson

Tools, Resources & Prompts

The three primitives an MCP server can expose.

Tools, Resources & Prompts is a free Claude Architect lesson on CoddyKit — lesson 1 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Claude Architect learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Three Primitives, One Server

The Model Context Protocol (MCP) lets an external server expose capabilities to Claude through a standard interface. A single server can offer exactly three kinds of primitives:

  • Tools — actions the model can invoke (do something, often with side effects)
  • Resources — read-only data and context the model can pull in (schemas, catalogs, docs)
  • Prompts — reusable templates that shape how a task is asked

Knowing which primitive fits a capability is a core architect skill: misclassifying an action as a resource (or vice-versa) leads to brittle, confusing integrations.

Tools — Actions With Effects

Tools are actions. They are the primitive the model calls to make something happen: query a live database, create a ticket, send a message, process a refund. Tools are the MCP analog of the Agent SDK tools you already define in an API request's tools field.

Because tools drive behavior, their descriptions are the primary selection mechanism — not their names. A good tool description states purpose, return values, input formats with examples, and applicability boundaries so the model routes to the right tool.

# An MCP server exposing a Tool (action) — Python style
@mcp.tool()
def lookup_order(order_id: str) -> dict:
    """Fetch a single order by its ID from the orders DB.

    Input: order_id as 'ORD-12345' (string, required).
    Returns: {status, total_cents, items[]}.
    Use only when you already have an exact order ID;
    for fuzzy search use search_orders instead.
    """
    return db.fetch_order(order_id)

Resources — Read-Only Context

Resources are read-only data. They give the model context to reason over rather than an action to perform: a database schema, a product catalog, an API spec, a config file, a reference document.

The mental test: if the model is reading to understand, it is a Resource; if the model is doing to change something, it is a Tool. Exposing a stable schema as a Resource avoids spending a tool call (and a round-trip) just to fetch context the model needs up front.

# An MCP Resource — read-only context the model can load
@mcp.resource("schema://orders")
def orders_schema() -> str:
    """The current orders table schema (read-only).
    Provides column names and types so the model can
    write correct queries without guessing.
    """
    return read_file("db/orders.schema.sql")

Prompts — Reusable Templates

Prompts are templates. An MCP server can publish parameterized, reusable prompt templates — for example a standard "summarize this incident" or "review this PR for security issues" prompt that bakes in the team's preferred structure and criteria.

Prompts are not actions and not data; they are how a task is asked. They let a server ship best-practice instructions (explicit criteria, few-shot examples) so every consumer phrases the request consistently instead of reinventing it.

# An MCP Prompt — a reusable, parameterized template
@mcp.prompt()
def review_pr(diff: str, focus: str = "security") -> str:
    return (
        "Review the following diff. "
        f"Flag a finding only when it clearly violates {focus} "
        "best practice; do not flag style preferences.\n\n"
        f"{diff}"
    )

The Decision: Tool vs Resource vs Prompt

Put the three side by side and the boundaries get sharp:

  • Tool — "Do X." Has effects, may fail transiently, is invoked mid-loop. e.g. process_refund.
  • Resource — "Here is X to read." Stable, idempotent, no side effects. e.g. the orders schema.
  • Prompt — "Ask it like this." A template, not a call. e.g. the PR-review template.

A frequent mistake is wrapping read-only context as a tool. That works, but it costs a tool call and a round-trip; a Resource delivers the same context more cheaply and signals intent clearly.

Configuring an MCP Server: Scope

Where you register a server controls who gets it. Two scopes matter:

  • Project scope.mcp.json at the repo root, committed to version control. Shared with the whole team; everyone who clones the repo gets the same servers.
  • User scope~/.claude.json, personal and NOT shared via VCS. Good for your own credentials or experimental servers.

For an integration the whole team relies on, choose project scope so it lives in VCS and new teammates inherit it automatically.

{
  "mcpServers": {
    "orders": {
      "command": "node",
      "args": ["./servers/orders-mcp.js"],
      "env": {
        "GITHUB_TOKEN": "${GITHUB_TOKEN}"
      }
    }
  }
}

Secrets: Never Commit Tokens

Because project-scope .mcp.json is committed to VCS, you must never hard-code secrets in it. Reference them through environment variables instead — for example ${GITHUB_TOKEN} — so the config is shareable while the actual token stays out of source control.

This is a security guarantee, not a convenience: a committed token is a leaked token. Env-var indirection keeps the project config portable and the credential private to each machine.

{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": { "GITHUB_TOKEN": "${GITHUB_TOKEN}" }
    }
  }
}

Prefer Community Servers

For standard integrations — GitHub, Postgres, Slack, filesystem — prefer a well-maintained community MCP server over building a custom one. You inherit battle-tested tool descriptions, error handling, and updates for free.

Reserve a custom server for genuinely proprietary systems where no community option exists. This mirrors a broader architect principle: don't rebuild standard plumbing; spend your effort on what is actually unique to your domain.

Structured Errors From Tools

When an MCP tool fails, a generic message like "Operation failed" leaves the model blind — it cannot tell whether to retry, escalate, or try an alternative. Always return structured errors so the model can route intelligently.

A good MCP error carries: isError: true, an errorCategory (transient / validation / business / permission), an isRetryable flag, a human message, the attempted_query, and any partial_results. The category and retryable flag are what turn a dead end into an intelligent recovery.

{
  "isError": true,
  "errorCategory": "transient",
  "isRetryable": true,
  "message": "DB connection timed out after 5s",
  "attempted_query": "SELECT * FROM orders WHERE id='ORD-1'",
  "partial_results": []
}

Tool Hygiene Carries Into MCP

Everything you know about good tool design applies to MCP tools too:

  • Descriptions, not names, drive selection — write purpose, returns, input formats, edge cases, and boundaries.
  • Scope tools to the role. About 4-5 tools per agent is optimal; once you approach 18+, selection reliability degrades.
  • Avoid overlap. Two tools with ambiguous, similar descriptions cause misrouting.

An MCP server that dumps 20 vaguely-described tools on an agent is an anti-pattern, no matter how capable each tool is.

Putting It Together

Picture an orders MCP server for a support agent. A clean design uses all three primitives deliberately:

  • Resource schema://orders — so the agent understands the data model up front, no tool call needed.
  • Tools lookup_order, process_refund — the actions, each with a sharp description and structured errors.
  • Prompt refund_review — a template encoding the team's refund-justification criteria.

Register it in project-scope .mcp.json, pull secrets from env vars, and keep the tool count lean. That is an architect-grade MCP integration.

Quick Check

Test your grasp of the three MCP primitives and how to expose them.

Recap: Tools, Resources & Prompts

Key takeaways for the exam and for real builds:

  • An MCP server exposes three primitives: Tools (actions), Resources (read-only data/context), Prompts (templates).
  • Decide by intent: doing → Tool, reading to understand → Resource, how to ask → Prompt.
  • Scope: project .mcp.json (shared in VCS) vs user ~/.claude.json (personal).
  • Secrets go through env vars like ${GITHUB_TOKEN} — never commit tokens.
  • Prefer community servers for standard integrations; keep tools to ~4-5 with sharp descriptions.
  • Return structured errors (isError, errorCategory, isRetryable, attempted_query, partial_results) so the model can recover intelligently.

Frequently asked questions

Is the “Tools, Resources & Prompts” lesson free?

Yes — the full text of “Tools, Resources & Prompts” is free to read here on the web, and the Claude Architect course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Claude Architect course, upgrade to CoddyKit PRO.

What will I learn in “Tools, Resources & Prompts”?

The three primitives an MCP server can expose. You practise Claude Architect with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Claude Architect?

No prior experience is required. Claude Architect on CoddyKit is structured for beginners through advanced learners; this is — lesson 1 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Tools, Resources & Prompts” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Claude Architect lesson?

Yes. Every Claude Architect lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Tools, Resources & Prompts
  2. Project vs User Scope
  3. Secrets with Environment Variables
  4. Community vs Custom Servers
← Back to Claude Architect