§5 · MCP integration

AI-native, not AI-adjacent.

People API ships with an MCP server out of the box. Six tools. One resource. Stdio transport. Any MCP-compatible client gets People API for free — no per-vendor integration work.

For: agent builders and anyone wondering whether to write their own integration.

Why MCP

MCP is the emerging standard interface between AI assistants and external systems. Before MCP, "integrating your product with an AI assistant" meant writing a custom plugin for every assistant — a Claude plugin, a Cursor plugin, a ChatGPT action — each with its own schema, auth, and lifecycle.

MCP collapses that into a protocol. Implement the server once. Any MCP-compatible client discovers your tools and resources automatically. People API's MCP server is the integration — there isn't a Claude-specific or Cursor-specific variant.

The six tools

Each tool is a thin wrapper over a REST endpoint. The shape is deliberate: an agent should be able to read the tool list and understand the protocol without reading the API reference. Params use snake_case because MCP idioms favor it; the underlying REST API uses camelCase.

TOOL
create_intent

Declare what you want. Creates a Tier-1 intent in the registry.

Params
  • category: string·req
  • description: string·req
  • attributes: object
  • budget_min: number
  • budget_max: number
  • currency: stringdefaults to USD
  • urgency: enumbrowsing | planning | ready_to_buy
  • metro: string
  • zip: string
  • tags: string[]
  • autoApproveBelow: numberauto-accept qualifying offers at or below this price
Example call
{
  "category": "plumbing_fixtures",
  "description": "Pink undermount kitchen sink, porcelain, 30\"",
  "budget_min": 200,
  "budget_max": 400,
  "urgency": "ready_to_buy",
  "metro": "NYC",
  "autoApproveBelow": 300
}
TOOL
list_intents

View your intents. Filter by status or category.

Params
  • status: enumactive | fulfilled | expired | cancelled
  • category: string
Example call
{ "status": "active" }
TOOL
view_offers

See offers for an intent, ranked by score.

Params
  • intentId: string·req
Example call
{ "intentId": "int_7f..." }
TOOL
respond_to_offer

Accept, reject, or counter an offer.

Params
  • offerId: string·req
  • action: enum·reqaccept | reject | counter
  • counterMessage: stringrequired when action = counter
Example call
{ "offerId": "off_9a...", "action": "accept" }
TOOL
cancel_intent

Cancel an active intent.

Params
  • intentId: string·req
Example call
{ "intentId": "int_7f..." }
TOOL
browse_registry

Vendor-perspective browse of the public registry. Filter by category, metro, urgency, budget.

Params
  • category: string
  • metro: string
  • urgency: enumbrowsing | planning | ready_to_buy
  • budgetMin: number
  • limit: numberdefaults to 20
Example call
{ "category": "plumbing_fixtures", "metro": "NYC", "urgency": "ready_to_buy" }

The one resource

MCP resources are read-only data the client can fetch. People API exposes one:

MCP resource
# URI
peopleapi://protocol

# Returns
{
  "name": "People API",
  "tagline": "Services got APIs. Now people get them too.",
  "tiers": [
    { "number": 1, "name": "Public",        "access": "none" },
    { "number": 2, "name": "Engaged",       "access": "session_token" },
    { "number": 3, "name": "Transactional", "access": "session_token" }
  ],
  "capabilities": {
    "scoring": true,
    "auto_accept": true,
    "auto_reject": true,
    "sse_events": true
  }
}

The resource is a self-describing manifest. An agent that has never seen People API can read it and understand the privacy model and server capabilities before calling any tool.

Transport

Stdio. The MCP client spawns the server as a subprocess and communicates over standard input/output framed as newline-delimited JSON-RPC. This is the canonical local-MCP transport — it matches how Claude Desktop and Cursor launch servers.

Config snippet

Drop this into ~/Library/Application Support/Claude/claude_desktop_config.json (or the Cursor equivalent) and restart the client. The tools appear automatically.

claude_desktop_config.json
{
  "mcpServers": {
    "peopleapi": {
      "command": "node",
      "args": ["/absolute/path/to/peopleapi/dist/mcp/server.js"]
    }
  }
}

A real agent conversation

The end-to-end pink-sink flow, played through Claude as an MCP client. Tool calls are shown inline; the agent orchestrates all three of create_intent, view_offers, and respond_to_offer without a second prompt.

Agent transcript · pink-sink flowstdio · peopleapi MCP
  1. You

    I need a pink undermount kitchen sink, porcelain, 30 inches, in NYC. Budget $200–400. Auto-approve anything under $300. Go find me offers.

  2. Claude

    I'll publish an intent to the People API registry now, then check for offers in a moment.

  3. Tool call
    create_intent
    {
      "category": "plumbing_fixtures",
      "description": "Pink undermount kitchen sink, porcelain, 30\"",
      "attributes": { "material": "porcelain", "color": "pink", "size_inches": 30, "mount": "undermount" },
      "budget_min": 200, "budget_max": 400,
      "urgency": "ready_to_buy", "metro": "NYC",
      "autoApproveBelow": 300
    }
    Result
    { "intent": { "id": "int_7f3a1b2c", "status": "active" } }
  4. Claude

    Intent published. Let me check what vendors have come back with.

  5. Tool call
    view_offers
    { "intentId": "int_7f3a1b2c" }
    Result
    {
      "offers": [
        { "id": "off_9a2b4c8d", "vendor": "Premium Sink Co", "price": 280, "deliveryDays": 2, "score": 82, "status": "accepted" },
        { "id": "off_3c5d7e9f", "vendor": "Bathrooms Direct", "price": 340, "deliveryDays": 4, "score": 73, "status": "pending" },
        { "id": "off_5e7f9h1j", "vendor": "Budget Plumbing", "price": 150, "deliveryDays": 7, "score": 69, "status": "pending" }
      ]
    }
  6. Claude

    You already have one auto-accepted: Premium Sink Co at $280 in 2 days, score 82. Two more are pending review — Bathrooms Direct at $340 (score 73), and Budget Plumbing at $150 (score 69, a touch below the auto-accept threshold). Should I accept the second offer, counter it, or hold?

  7. You

    Just accept Premium Sink. Reject the others.

  8. Tool call
    respond_to_offer
    { "offerId": "off_3c5d7e9f", "action": "reject" }
    Result
    { "offer": { "status": "rejected" } }
  9. Tool call
    respond_to_offer
    { "offerId": "off_5e7f9h1j", "action": "reject" }
    Result
    { "offer": { "status": "rejected" } }
  10. Claude

    Done. Premium Sink Co remains accepted. You'll get a session token when they confirm the ship date.

MCP server source