MCP vs REST.
Honest comparison.

Neither one wins universally. Three real scenarios — each shown in the approach that actually fits.

Live demos below use real endpoints on this site.

Scenario 1

Direct Query — REST Wins

When you know what you want, REST is faster and simpler.

REST Direct query
✓ Best choice here

Request

GET /api/portfolio?skill=python&type=featured&limit=3

You knew the query. You got the data. No AI needed, no overhead.

MCP Tool definition
Works — but overkill

Equivalent MCP tool

{
  "name": "search_portfolio",
  "description": "Search Ryan's portfolio projects",
  "inputSchema": {
    "type": "object",
    "properties": {
      "skill": { "type": "string" },
      "type": {
        "enum": ["featured", "exploration", "all"]
      },
      "limit": { "type": "number" }
    }
  }
}

This works too — but you're adding an AI reasoning layer to a deterministic query. Extra latency, extra cost, same result.

Scenario 2

Exploratory Query — MCP Wins

When the AI needs to reason across sources, MCP removes the routing logic you'd otherwise write yourself.

REST Intent router
You wrote the reasoning

What you'd have to build

# You write the routing logic
def handle_query(query):
  q = query.lower()

  if "built" in q and "available" in q:
    # Composite intent — call two endpoints
    projects = get_projects()
    avail = get_availability()
    return summarize(projects, avail)

  elif "what" in q and "built" in q:
    return get_projects()

  elif "available" in q:
    return get_availability()

  elif "rust" in q:
    return get_projects(skill="rust")

  # Every new question type needs new code here
  else:
    return fallback_search(query)

Every new question type is new code. You own the reasoning logic forever.

MCP Tool-calling handler
✓ Best choice here

Tool definitions — the AI handles routing

[
  {
    "name": "search_projects",
    "description": "Search Ryan's work by skill, type, or topic"
  },
  {
    "name": "get_availability",
    "description": "Return Ryan's consulting availability and engagement process"
  }
]
// AI decides which tools to call, in what order

Try the live handler — this uses the real /api/ask endpoint on this site:

You describe what each tool does. The AI figures out which to call and how to compose the answer.

Scenario 3

Adding a New Capability — MCP Scales Better

As your system grows, MCP stays manageable. REST routing compounds.

REST Adding blog search
4 files, ~60 lines

Files you need to touch

1

src/utils/intent-classifier.ts

Add "blog_search" intent detection — ~15 lines of keyword matching

2

src/pages/api/ask.ts

Add another else if branch for blog queries — ~10 lines

3

src/utils/prompt-templates.ts

New prompt template for blog context — ~20 lines

4

tests/ask.test.ts

New test cases for the new branch — ~15 lines

Each new capability touches multiple layers. The classifier, the router, the prompts, the tests. It compounds.

MCP Adding blog search
1 file, ~15 lines

What you add

// Add one tool to your tool registry
{
  "name": "search_blog",
  "description": "Search Ryan's writing and insights by topic",
  "inputSchema": {
    "type": "object",
    "properties": {
      "topic": { "type": "string" },
      "limit": { "type": "number", "default": 5 }
    }
  }
}
// The AI discovers this tool automatically.
// No classifier update. No routing change.
// No prompt template. The description IS the prompt.

Same new capability. Very different maintenance cost. At 3 tools this difference is minor. At 15 tools, the REST router is a full-time job.