ASK KNOX
beta
LESSON 399

The Three Primitives in Depth — Tools, Resources, Prompts

Tools do work, resources are data, prompts shape conversations — but the decision tree for which to use is more nuanced than it sounds, and most production servers get it wrong.

8 min read·Building Production MCP Servers

Why the Distinction Matters

The mcp-for-beginners track introduced the three primitives: tools do work, resources are data, prompts shape conversations. The distinction sounded clean. In practice, most developers either make everything a Tool (because it is the most familiar pattern) or make everything a Resource (because it seems safer than write operations). Both approaches are wrong.

Making everything a Tool adds call overhead to every piece of static content your server exposes. Making everything a Resource means you cannot execute logic, run queries, or take actions. The primitives exist for a reason — and the decision rule for which to use is precise enough to follow as a checklist.

All Three Primitives, Fully Explained

The primitive table above is worth studying with your own server in mind. For each surface you are planning to expose, ask the three questions in order. The answer usually resolves quickly.

The anti-pattern at the bottom of each primitive is the real lesson. Tools built for static data accumulate call overhead. Resources built for dynamic data cannot serve current state. Prompts used for content that belongs in CLAUDE.md waste MCP overhead for content that should be always-loaded.

The Decision Tree

A decision tree makes the choice mechanical. You do not need to reason from first principles every time.

The tree has three nodes. Most surfaces in Knox's production servers resolve at node one — they are Tools. Semantic Memory Layer has 12 tools and zero resources or prompts. The agent dispatch bridge is pure tools. The mcp-bridge is pure tools. The knowledge-OS pattern is almost always Tools because knowledge retrieval and storage are inherently dynamic — different query, different result.

The beginner MCP track covered a simple file-serving example that used Resources. That is appropriate for the beginner track. Production knowledge-OS servers are tools.

Why Semantic Memory Layer is 100% Tools

Semantic Memory Layer exposes 12 tools and no resources or prompts. This is a deliberate design decision, not an oversight.

Every piece of data Semantic Memory Layer serves is dynamic:

  • memory_query(query) returns different results for every query string
  • memory_recall(id) could return different content if the memory was updated
  • memory_status() returns current chunk count which changes as memories are added
  • memory_namespaces() returns the current set of namespaces which can change
  • memory_events() returns the current event log which grows continuously

None of these are addressable, stable documents. None of them belong on the Resource surface. The design decision to make them all Tools is correct.

The only case where Knox considered a Resource was the server's own configuration — config://settings. He kept it as a Tool (memory_status) because the configuration changes meaningfully (chunk count, last_indexed_at) and callers need the current value, not a cached snapshot.

Schema Design for Each Primitive

The schema design differs by primitive. Tools have JSON Schema input validation and return typed output. Resources have a URI template and return text or blob content. Prompts have named arguments and return a message sequence.

For Tools — which you will spend 90% of your time on — the schema defines the contract. The description field is what the model reads to decide when to call the tool. The input schema constrains what values the model can pass. The output shape is what the callers depend on.

A weak tool description: "Search the database". The model cannot decide when to call this.

A strong tool description: "Semantic search across all indexed memories. Call at session start with the project name to surface architecture context, known failure modes, and recent corrections. Returns results sorted by relevance." The model knows exactly when to call this and what it provides.

The description field is not documentation for humans. It is an instruction to the model. Write it as an instruction, not a description.

Prompts in Production: Rarely Used, But Powerful

Knox's production servers do not use Prompts. This is common — most production MCP servers are 90% Tools and 10% Resources. Prompts are useful when you have reusable conversation templates that need to be shared across installations and injected on demand.

The best use case: a team server that exposes company-specific code review standards as a Prompt. Every developer on the team has the same MCP server registered in their ~/.claude.json. When someone wants the review standards injected, they request the Prompt by name. The content comes from the central server, not from each developer's CLAUDE.md.

This is the power of Prompts: centralized, versioned, on-demand injection. If your use case does not benefit from centralization and on-demand loading, the content probably belongs in CLAUDE.md instead.

What's Next

The next lesson goes deep on tool surface design — how to structure inputs, define stable output contracts, and perform the consumer-contract check that prevents silent breakage when callers depend on your tool's output shape.