MCP server

IntakeFlow ships a Model Context Protocol server at /api/mcp. Point any MCP client at it and an AI agent can inspect, send, and review client portals using your API key as its credential — the same keys, scopes, and plan limits as the REST API.

Connect a client

Claude Code / Claude Desktop
claude mcp add --transport http intakeflow https://your-domain.com/api/mcp \
  --header "Authorization: Bearer ifl_live_YOUR_KEY"
Cursor (mcp.json)
{
  "mcpServers": {
    "intakeflow": {
      "url": "https://your-domain.com/api/mcp",
      "headers": { "Authorization": "Bearer ifl_live_YOUR_KEY" }
    }
  }
}
Create a dedicated key for your agent. Read-only keys can inspect portals but can't send or review — a good default for assistants you're still trusting.

Transport

Stateless streamable-HTTP: every request is self-contained JSON-RPC 2.0 with the bearer header.initialize, notifications/initialized, ping, tools/list, and tools/call are implemented; no server-side session state, so it works behind load balancers and serverless.

Tools

ToolScopeWhat it does
list_portalsreadPortals with status, completion %, and awaiting-review counts. Optional status filter.
get_portalreadOne portal in full: client, items, every response, rejection notes. No credential values.
send_portalwriteSend a portal to a client (creates the client if needed) and returns the signed link.
review_itemwriteApprove a submitted item or reject it with a note (the client is emailed).
list_templatesreadTemplates with item definitions — the source of template ids.
upsert_clientwriteCreate a client or update by email match.
portal_linkreadA fresh signed URL the client can use to open their portal.
send_reminderwriteEmail the client about outstanding items, bypassing the daily cadence.

Example conversation

With the tools connected, an agent can run a whole review pass on its own:

What the agent does under the hood
User:  "Check Acme's portal and approve the items that look complete."

Agent: list_portals({})            → finds Acme, status awaiting_review
       get_portal({ portal_id })   → reads each submitted answer
       review_item({ response_id: "res_…", action: "approve" })
       review_item({ response_id: "res_…", action: "reject",
                     note: "Screenshot shows the old logo — please re-upload" })

Safety rails

  • Tool calls inherit the key's scopes — read-only keys simply can't mutate.
  • Rejecting without a note is refused; the client needs to know what to fix.
  • Every action respects plan limits and tenancy — an agent can only see its own account.
  • Credential answers are never exposed to the model, only has_credential flags.

Raw JSON-RPC example

POST https://your-domain.com/api/mcp
{ "jsonrpc": "2.0", "id": 1, "method": "tools/call",
  "params": {
    "name": "list_portals",
    "arguments": { "status": "awaiting_review" }
  } }
Response
{ "jsonrpc": "2.0", "id": 1, "result": {
  "content": [ { "type": "text", "text": "{ \"portals\": […]" } ],
  "isError": false } }