Project 1: MCP Protocol Explorer

Build a strict MCP server contract with reliable tool schemas, deterministic outputs, and debuggable traces.

Quick Reference

Attribute Value
Difficulty Beginner
Time Estimate Weekend
Main Programming Language TypeScript (Alternatives: Python, Go)
Alternative Programming Languages Python, Go
Coolness Level Level 2
Business Potential Resume Gold
Prerequisites JSON schemas, HTTP fundamentals, idempotency basics
Key Topics MCP tools/resources, metadata quality, error normalization

1. Learning Objectives

By completing this project, you will:

  1. Design five MCP tools with clear intent boundaries.
  2. Build schema constraints that prevent invalid states.
  3. Return deterministic success and failure envelopes.
  4. Trace planner behavior using structured logs.

2. All Theory Needed (Per-Concept Breakdown)

Tool Descriptors as Planner Control Plane

Fundamentals Tool descriptors are runtime routing instructions for the model planner. Your names, descriptions, and schema shapes are what the planner sees before choosing a tool. If descriptors are broad or ambiguous, the wrong tool will be selected under realistic user prompts. In this project, descriptor quality is treated as a first-class artifact. Think of each descriptor as both API contract and intent classifier.

Deep Dive into the concept MCP tool descriptors have two jobs: communicate what a tool does, and constrain how it is called. The first job is semantic. Tool names and descriptions must map to user intent language, not backend implementation jargon. For example, “list_recent_incidents” is better than “query_events_table” because planner intent mapping is user-centric. The second job is syntactic. Input schemas define legal argument shapes, cardinality, and boundaries. If the schema is under-specified, planner-generated arguments drift toward invalid states, producing noisy failures.

A robust descriptor should also encode side-effect expectations. Read-only tools can be called more freely, while mutating tools should include explicit confirmation fields and unambiguous naming. This reduces accidental writes and improves auditability.

Use response envelopes that separate human-readable summaries from structured data. Structured fields allow downstream component rendering and deterministic tests. Narrative summaries help conversational continuity.

Production behavior depends on deterministic error design. Errors should include machine-usable fields: code, retryable, message, trace_id. Without this, troubleshooting becomes guesswork. Descriptor design is therefore a reliability mechanism, not only a developer convenience.

Finally, descriptor design should be versioned. As tool semantics evolve, explicit version notes prevent regressions in planner behavior. Teams that treat descriptors like code (reviewed, tested, versioned) ship more stable apps.

How this fit on projects

  • This is the foundation for every later project.
  • You will reuse this pattern in P03, P05, P06, and P10.

Definitions & key terms

  • Descriptor: tool metadata + schema contract.
  • Planner routing: model decision process to choose tools.
  • Side effect: external state change caused by tool execution.

Mental model diagram

Prompt -> Intent parse -> Descriptor match -> Schema check -> Tool call -> Result envelope

How it works

  1. User asks for outcome.
  2. Planner compares descriptors.
  3. Schema validates candidate args.
  4. Tool executes under policy checks.
  5. Success/error envelope returned.

Minimal concrete example

Tool: create_project
Input: { name: string, owner_id: string, confirm_create: true }
Output: { status: "created", project_id: "prj_1001" }
Error: { code: "DUPLICATE_NAME", retryable: false, trace_id: "trc_9ab" }

Common misconceptions

  • “One generic tool is easier.” -> It hurts planner precision.
  • “Description text is cosmetic.” -> It is a routing signal.

Check-your-understanding questions

  1. Why do broad descriptors increase mutation risk?
  2. Which fields make error envelopes operationally useful?

Check-your-understanding answers

  1. Planner ambiguity causes wrong tool selection.
  2. code, retryable, message, and trace_id.

Real-world applications

  • Incident management assistants
  • CRM record managers

Where you’ll apply it

  • P01 directly, then P03/P05/P10.

References

  • OpenAI Apps SDK reference
  • OpenAI MCP server guide

Key insights Clear descriptors are your strongest reliability primitive.

Summary Descriptor quality determines planner quality.

Homework/Exercises to practice the concept

  1. Rewrite three ambiguous tool descriptions.
  2. Add explicit confirmation fields to two mutating tools.

Solutions to the homework/exercises

  1. Use user-intent verbs and context.
  2. Require confirm_* booleans for writes.

3. Project Specification

3.1 What You Will Build

An MCP server with five tools:

  • list_projects
  • get_project
  • create_project
  • archive_project
  • health_check

Included:

  • Strict schemas
  • Normalized errors
  • Deterministic fixtures

Excluded:

  • Complex auth (handled in P06)
  • Rich UI components (handled in P02/P03)

3.2 Functional Requirements

  1. Every tool validates input schema.
  2. Every tool returns normalized success/error envelopes.
  3. Read-only and mutating tools are clearly separated.
  4. Logs include trace_id, tool_name, duration_ms, status.

3.3 Non-Functional Requirements

  • Performance: p95 tool latency under 300ms for fixture data.
  • Reliability: deterministic output for fixed test fixtures.
  • Usability: error messages include next-step guidance.

3.4 Example Usage / Output

invoke: list_projects { limit: 3 }
result: { items:[...], next_cursor:"cur_2" }

invoke: create_project { name:"Q1 migration", owner_id:"usr_14", confirm_create:true }
result: { status:"created", project_id:"prj_1001" }

3.5 Real World Outcome

$ npm run dev:mcp
[server] listening http://localhost:8001/mcp
[server] ready tools=5

$ mcp-inspector invoke get_project '{"project_id":"prj_1001"}'
status: ok
project.name: Q1 migration
project.owner_id: usr_14

4. Solution Architecture

4.1 High-Level Design

Planner -> MCP tool registry -> schema gate -> domain handler -> result envelope -> trace logger

4.2 Key Components

Component Responsibility Key Decisions
Tool Registry Declares tools and schemas Narrow, intent-driven tools
Validator Enforces input constraints Fail fast before handler
Handler Layer Executes business logic Separate read and write paths
Envelope Builder Normalizes output/errors Deterministic shapes
Trace Logger Correlation and latency tracking Structured JSON logs

4.3 Algorithm Overview

  1. Resolve tool by name.
  2. Validate input.
  3. Execute handler with timeout budget.
  4. Return normalized envelope.
  5. Emit trace log.

5. Implementation Guide

5.1 The Core Question You’re Answering

“Can I build tool contracts that remain predictable under noisy real prompts?”

5.2 Concepts You Must Understand First

  1. JSON schema constraints and enums.
  2. Idempotency for mutation safety.
  3. Normalized error taxonomy.

5.3 Questions to Guide Your Design

  1. Which tools can be retried safely?
  2. Which fields are mandatory for observability?
  3. Which failures should be user-actionable?

5.4 Thinking Exercise

Draw success/failure state diagrams for create_project and archive_project.

5.5 The Interview Questions They’ll Ask

  1. Why separate read and write tools?
  2. What makes a schema production-grade?
  3. How do you debug planner misrouting?
  4. Why are deterministic errors important?
  5. How do you measure tool reliability?

5.6 Hints in Layers

  • Hint 1: Start with read-only tools.
  • Hint 2: Add one mutating tool with explicit confirmation.
  • Hint 3: Normalize all errors before adding more tools.
  • Hint 4: Freeze fixture IDs and timestamps for deterministic tests.

5.7 Books That Will Help

Topic Book Chapter
API contracts “Clean Architecture” Interfaces chapter
Reliability patterns “The Pragmatic Programmer” Automation/testing
Data consistency “Code Complete” Defensive programming sections

5.8 Implementation Phases

  • Phase 1: Tool registration + schema validation.
  • Phase 2: Handler logic + envelope normalization.
  • Phase 3: Trace logging + deterministic test transcripts.

6. Testing Strategy

  • Unit tests: schema acceptance/rejection.
  • Integration tests: tool invocation traces.
  • Edge tests: malformed input, duplicate mutations, timeout simulation.

7. Common Pitfalls & Debugging

Pitfall Symptom Solution
Ambiguous descriptions Wrong tool chosen Rewrite with intent triggers
Incomplete schemas Runtime validation chaos Add strict enums and required fields
Non-normalized errors Hard debugging Use one error envelope format

8. Extensions & Challenges

  • Add bulk update tool with safe batching.
  • Add pagination cursor integrity checks.
  • Add offline fixture replay mode.

9. Real-World Connections

  • Internal DevOps assistants
  • Customer support resolution tooling

10. Resources

  • Apps SDK reference
  • MCP specification
  • OpenAI testing/troubleshooting docs

11. Self-Assessment Checklist

  • I can explain tool descriptor tradeoffs.
  • I can enforce schema invariants.
  • I can normalize success/error envelopes.
  • I can debug tool misrouting with traces.

12. Submission / Completion Criteria

Minimum Viable Completion

  • Five tools implemented with strict schemas.
  • Normalized envelopes for success and failure.
  • Deterministic transcript for one read and one write path.

Full Completion

  • Includes trace logging, edge-case tests, and retry safety checks.