for agents & developers

The video pricing & matching engine, for agents.

When someone asks their AI assistant to price or find a videographer, this is the engine that answers — calibrated on thousands of real delivered productions, structured priced request out. Below is a real session, not a sketch of one: every frame is stdout from node apps/com/app/mcp.js, captured 2026-07-25 and re-checked against the live server by the test suite.

the handshake

videographer.com v1.1.0

JSON-RPC 2.0 over stdio, protocol 2024-11-05. Four methods are implemented — initialize, ping, tools/list, tools/call — and anything else answers -32601. There are no resources and no prompts.

sent
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2024-11-05",
    "capabilities": {},
    "clientInfo": {
      "name": "demo",
      "version": "1.0.0"
    }
  }
}
received
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "2024-11-05",
    "capabilities": {
      "tools": {}
    },
    "serverInfo": {
      "name": "videographer.com",
      "version": "1.1.0"
    }
  }
}
tools/list

12 tools, and where the line is drawn

Three price shoots in-process with no account at all. The other nine act for one videographer — their calendar, their leads, their listing — and need a credential that names that account.

sent
{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/list"
}
received

12 tool descriptors, 6.5 KB of JSON. Condensed to names and arguments:

ToolArguments (bold = required)
price_video_shoot freedescription
video_cost_by_market freeshoot_type, city
list_video_markets freenone
find_second_shooter credentialdate, city, shoot_type
set_my_availability credentialdates, status, discoverable
request_second_shooter credentialvideographer_id, date, shoot_type, note
respond_to_second_shooter_request credentialrequest_id, action
my_second_shooter_requests credentialnone
my_leads credentialnone
respond_to_lead credentialroute_id, action
my_listing credentialnone
update_my_listing credentialname, bio, website_url, reel, cities, shoot_types, status, discoverable, second_shooter_note, second_shooter_roles, confirm_clear_coverage

One descriptor in full, so you can see what the strings a client actually reads look like:

{
  "name": "find_second_shooter",
  "description": "Find videographers available to work as a second shooter on a date. Acts as the videographer who owns this MCP server's agent credential. Results carry public fields only — name, city, shoot types, reel, note — never an email address; contact is revealed only after a request is accepted. Use the returned id with request_second_shooter.",
  "inputSchema": {
    "type": "object",
    "properties": {
      "date": {
        "type": "string",
        "description": "YYYY-MM-DD. Only days a peer explicitly marked available are returned."
      },
      "city": {
        "type": "string",
        "description": "Defaults to your own first covered city."
      },
      "shoot_type": {
        "type": "string",
        "description": "wedding, corporate-event, brand-film, real-estate, music-video"
      }
    }
  }
}
tools/call

A sentence in, a priced request out

The pricing half runs against the same parser and the same rate sheet as the website, in the MCP process, offline. Same sentence, same numbers a person gets.

sent
{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "price_video_shoot",
    "arguments": {
      "description": "a 5-hour wedding in Austin, two cameras, drone"
    }
  }
}
received
{
  "order": {
    "shootType": "wedding",
    "city": "Austin",
    "cityTier": 3,
    "cityFactor": 1.05,
    "date": null,
    "durationMinutes": 300,
    "deliverableMinutes": null,
    "cameras": 2,
    "addons": [
      "drone"
    ],
    "budget": null,
    "budgetAmount": null
  },
  "estimate": {
    "currency": "USD",
    "range": {
      "low": 1675,
      "high": 3650
    },
    "display": "$1,675 – $3,650",
    "tiers": [
      {
        "key": "essentials",
        "label": "Essentials",
        "tagline": "Raw & lightly-edited footage — your day, captured.",
        "priceLow": 1675,
        "priceHigh": 2275,
        "display": "$1,675 – $2,275",
        "includes": [
          "5h coverage",
          "2 cameras",
          "Full raw footage delivery",
          "Lightly-edited selects",
          "4–8 weeks turnaround"
        ]
      },
      {
        "key": "signature",
        "label": "Signature",
        "tagline": "Fully edited, color-graded film — the full-service middle of the range.",
        "priceLow": 2275,
        "priceHigh": 3250,
        "display": "$2,275 – $3,250",
        "includes": [
          "5h coverage",
          "2 cameras",
          "Raw footage (all coverage)",
          "Documentary edit option",
          "Highlight film (3–6 min)",
          "Color-graded delivery"
        ]
      },
      {
        "key": "cinematic",
        "label": "Cinematic",
        "tagline": "Premium multi-camera cinematic production with every extra.",
        "priceLow": 3250,
        "priceHigh": 3650,
        "display": "$3,250 – $3,650",
        "includes": [
          "5h coverage",
          "2 cameras",
          "Multi-camera cinematic coverage",
          "Raw footage (all coverage)",
          "Documentary edit option",
          "Highlight film (3–6 min)",
          "Color-graded delivery",
          "Cinematic edit & advanced color grade",
          "Aerial / drone"
        ]
      }
    ],
    "recommended": {
      "cameras": 2,
      "crew": 2,
      "coverageHours": 5,
      "deliverables": [
        "Raw footage (all coverage)",
        "Documentary edit option",
        "Highlight film (3–6 min)",
        "Color-graded delivery",
        "Aerial / drone"
      ],
      "turnaround": "4–8 weeks"
    },
    "lineItems": [
      {
        "label": "Wedding coverage + edit (raw → finished)",
        "low": 1150,
        "high": 2725
      },
      {
        "label": "Additional camera (×1)",
        "low": 200,
        "high": 200
      },
      {
        "label": "Aerial / drone",
        "low": 300,
        "high": 700
      }
    ],
    "assumptions": [
      "5h coverage",
      "2 cameras",
      "local market rate (×1.05)",
      "range spans raw footage → fully edited"
    ],
    "budget": null,
    "note": "Estimate only — a real quote depends on the specific shoot, scope, and videographer. Ranges reflect real production pricing."
  },
  "source": "videographer.com — calibrated to real production pricing"
}

Note the envelope: a tool result is a JSON string inside a text content block, so you have to parse content[0].text. That is normal MCP and easy to miss.

the professional half

Acting for a videographer

The other nine tools are thin calls onto routes the website already uses, carrying an agent credential minted on the host. No tool takes an id for the account it acts as — the account is inside the signature.

sent
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "find_second_shooter",
    "arguments": {
      "date": "2026-08-15",
      "city": "Chicago",
      "shoot_type": "wedding"
    }
  }
}
received
{
  "count": 0,
  "date": "2026-08-15",
  "city": "Chicago",
  "shootType": "wedding",
  "results": []
}

That is a real answer, and it is empty. The second-shooter network is opt-in, and on 2026-08-15 in Chicago nobody had marked themselves available — so count is 0. A result never carries an email address either; contact is exchanged only when a request is accepted.

refusals

The two ways you get told no

Neither is a JSON-RPC error, and neither clears on a retry. Both arrive as a successful result your client has to read.

Without a credential

sent
{
  "jsonrpc": "2.0",
  "id": 5,
  "method": "tools/call",
  "params": {
    "name": "find_second_shooter",
    "arguments": {
      "date": "2026-08-15",
      "city": "Chicago",
      "shoot_type": "wedding"
    }
  }
}
received
{
  "jsonrpc": "2.0",
  "id": 5,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Error: No agent credential. Set VIDEOGRAPHER_AGENT_TOKEN in this MCP server's environment — mint one on the videographer.com host with: node app/mcp.js --mint <your account email>"
      }
    ],
    "isError": true
  }
}

Tool errors come back as results with isError: true. The same sentence covers missing, expired, revoked and under-scoped, because those are indistinguishable to you — mint a new one rather than trying another tool.

For a shoot we do not cover

sent
{
  "jsonrpc": "2.0",
  "id": 4,
  "method": "tools/call",
  "params": {
    "name": "price_video_shoot",
    "arguments": {
      "description": "a memorial service for my grandfather in Denver"
    }
  }
}
received
{
  "order": {
    "shootType": null,
    "city": "Denver",
    "cityTier": 3,
    "cityFactor": 1,
    "date": null,
    "durationMinutes": null,
    "deliverableMinutes": null,
    "cameras": null,
    "addons": [],
    "budget": null,
    "budgetAmount": null
  },
  "estimate": null,
  "unsupported": true,
  "message": "We don’t cover that kind of shoot yet, so we won’t guess at a price. The cost guide at /cost may still help you plan."
}

Bereavement, milestones and one-off ceremonies get no price on any surface. This is a deliberate refusal, not a gap: do not reword the description to get around it, and do not fall back to /api/estimate to synthesise a number. A funeral once came back at $900–$1,500 under the tagline “your day, captured”, which is why the gate exists.

connect it

Point a client at it

There is no published package and no hosted transport yet. Clone the repo and give your client an absolute path; the token is only needed for the professional half.

{
  "mcpServers": {
    "videographer": {
      "command": "node",
      "args": ["/absolute/path/to/videographer.com/apps/com/app/mcp.js"],
      "env": { "VIDEOGRAPHER_AGENT_TOKEN": "…" }
    }
  }
}
http api

Or one HTTP call, no MCP

Post a plain-language shoot; get a structured request and a calibrated budget range. No key, no auth, free.

Request
curl -s https://videographer.com/api/quote \
  -H 'content-type: application/json' \
  -d '{"description":"a 5-hour wedding in Austin, two cameras, drone"}'
Response
{
  "order": {
    "shootType": "wedding",
    "city": "Austin",
    "cityTier": 3,
    "cityFactor": 1.05,
    "date": null,
    "durationMinutes": 300,
    "deliverableMinutes": null,
    "cameras": 2,
    "addons": [
      "drone"
    ],
    "budget": null,
    "budgetAmount": null
  },
  "estimate": {
    "currency": "USD",
    "range": {
      "low": 1675,
      "high": 3650
    },
    "display": "$1,675 – $3,650",
    "tiers": [
      {
        "key": "essentials",
        "label": "Essentials",
        "display": "$1,675 – $2,275",
        "includes": [
          "5h coverage",
          "2 cameras",
          "…"
        ]
      },
      {
        "key": "signature",
        "label": "Signature",
        "display": "$2,275 – $3,250",
        "includes": [
          "5h coverage",
          "2 cameras",
          "…"
        ]
      },
      {
        "key": "cinematic",
        "label": "Cinematic",
        "display": "$3,250 – $3,650",
        "includes": [
          "5h coverage",
          "2 cameras",
          "…"
        ]
      }
    ],
    "recommended": {
      "cameras": 2,
      "crew": 2,
      "coverageHours": 5,
      "deliverables": [
        "Raw footage (all coverage)",
        "Documentary edit option",
        "Highlight film (3–6 min)",
        "Color-graded delivery",
        "Aerial / drone"
      ],
      "turnaround": "4–8 weeks"
    },
    "lineItems": [
      {
        "label": "Wedding coverage + edit (raw → finished)",
        "low": 1150,
        "high": 2725
      },
      {
        "label": "Additional camera (×1)",
        "low": 200,
        "high": 200
      },
      {
        "label": "Aerial / drone",
        "low": 300,
        "high": 700
      }
    ],
    "assumptions": [
      "5h coverage",
      "2 cameras",
      "…"
    ],
    "note": "Estimate only — a real quote depends on the specific shoot, scope, and videographer. Ranges reflect real production pricing."
  }
}

Full reference in the API docs, the contract at /openapi.json, and a citable summary at /llms.txt.