API + MCP reference

MCP server

terminal.house ships a Model Context Protocol server so agents — Claude Desktop, Cursor, Windsurf, VS Code Copilot, or your own LangGraph / Mastra / GPT custom-tool — can call our REST surface as first-class tools instead of generating raw HTTP.

Operator tier and up. MCP is included on Operator, Team, and Custom. Starter is REST- only — upgrade at terminal.house/api-keys if you're on Starter and want MCP.

Overview

The server lives at https://mcp.terminal.house/mcp and speaks the standard streamable-HTTP transport. Auth is the same bearer API key you use for REST — no separate key, no separate dashboard.

We expose 10 tools covering every read-mostly REST endpoint plus the watchlist lifecycle. Tools that touch parcels consume lead-views against the same monthly quota as REST; tools that touch watchlists and metadata are free. See Rate limits & quotas.

Quick test once configured — ask your agent:

prompt
// In Claude / Cursor / Windsurf with terminal.house MCP wired:> Use list_leads with recipe "oos_long_tenure_high_signal" and limit 5. // The agent calls the tool. Returns:{  "results": [    {      "folio":   "30-3122-008-0440",      "address": "4567 NW 22nd Av, Miami FL 33125",      "score":   0.78,      "signals_fired": ["out_of_state_owner", "tenure_years_long",                       "no_homestead", "code_violation"],      "observed_at": "2026-05-28T10:14:00Z"    }    // ...4 more  ],  "cursor": "eyJv...A3",  "total":  340}

Setup · Claude Desktop

Claude Desktop's MCP config file lives at ~/Library/Application Support/Claude/claude_desktop_config.json on macOS or %APPDATA%\Claude\claude_desktop_config.json on Windows. Claude Desktop only speaks the stdio transport natively, so we proxy our streamable-HTTP endpoint through mcp-remote.

claude_desktop_config.json
{  "mcpServers": {    "terminal.house": {      "command": "npx",      "args": [        "-y",        "mcp-remote",        "https://mcp.terminal.house/mcp",        "--header",        "Authorization: Bearer ${TERMINAL_HOUSE_API_KEY}"      ],      "env": {        "TERMINAL_HOUSE_API_KEY": "th_live_...your-key..."      }    }  }}

Restart Claude Desktop. The terminal.house tools appear under the wrench icon in the chat input.

Setup · Cursor

Cursor's MCP config lives at ~/.cursor/mcp.json. Cursor speaks streamable-HTTP natively, so no proxy needed.

~/.cursor/mcp.json
{  "mcpServers": {    "terminal.house": {      "url": "https://mcp.terminal.house/mcp",      "headers": {        "Authorization": "Bearer ${TERMINAL_HOUSE_API_KEY}"      },      "env": {        "TERMINAL_HOUSE_API_KEY": "th_live_...your-key..."      }    }  }}
One-click install (coming soon). The cursor://anysphere.cursor-deeplink/mcp/install deep-link will land an "Install in Cursor" button on the just-issued-key reveal modal — tracking that in our changelog.

Setup · Windsurf

Windsurf's MCP config lives at ~/.codeium/windsurf/mcp_config.json. Same streamable-HTTP transport as Cursor.

~/.codeium/windsurf/mcp_config.json
{  "mcpServers": {    "terminal.house": {      "serverUrl": "https://mcp.terminal.house/mcp",      "headers": {        "Authorization": "Bearer ${TERMINAL_HOUSE_API_KEY}"      }    }  }}

Setup · VS Code Copilot

VS Code 1.99+ supports MCP servers natively through GitHub Copilot Chat. Add the server to your workspace at .vscode/mcp.json or globally via Command Palette → MCP: Add Server.

.vscode/mcp.json
{  "servers": {    "terminal.house": {      "type": "http",      "url": "https://mcp.terminal.house/mcp",      "headers": {        "Authorization": "Bearer ${env:TERMINAL_HOUSE_API_KEY}"      }    }  }}

VS Code resolves ${env:TERMINAL_HOUSE_API_KEY} from your shell environment, so set the key in your shell rc or in the workspace's .env (don't commit it).

Other clients

Any MCP-compliant client speaking streamable-HTTP works. Common combos:

  • LangGraph — use langchain-mcp-adapters to mount the server as a tool group.
  • Mastra — use @mastra/mcp to wire the server into your agent's tool registry.
  • GPT custom tools / Assistants API — proxy via mcp-remote or call the REST surface directly with the same Bearer key.
  • Custom MCP client — follow the MCP transport spec. Endpoint: POST https://mcp.terminal.house/mcp; Bearer auth in the Authorization header on every request.

API key persistence

We strongly recommend env-var indirection in client configs — every example above uses ${TERMINAL_HOUSE_API_KEY} rather than inlining the secret. This keeps the config file safe to commit, and rotates cleanly when you swap the env var. See Authentication · MCP-side auth.

Tool reference

Every tool's parameter shape is published in the MCP server's tools/list response — your client renders it natively (e.g. Claude Desktop shows it under the wrench icon; Cursor in the MCP panel). The summaries below cover the surface; deep-detail lives in the REST analogue at REST API · v1.

list_leads1 lead-view per parcel in results
list_leads(recipe?, filter?, limit?, cursor?, min_score?, since?, include?[])

Return scored, signal-rich parcels matching a saved recipe slug or an inline filter DSL. Sorted by composite score descending. Paged via opaque cursor.

get_lead1 lead-view (free if same parcel already viewed this UTC day)
get_lead(folio: str)

Full detail for one parcel by folio — owner, valuation, every signal evidence, sales history, signals, score.

batch_get_leads1 lead-view per folio (calendar-day-UTC idempotent)
batch_get_leads(folios: list[str])

Bulk-fetch up to 100 folios in one call. Useful for re-hydrating a saved pipeline.

list_watchlistsFree
list_watchlists()

List every watchlist visible to the active tenant. Includes recipe slug, last-fired timestamp, webhook count.

get_watchlistFree
get_watchlist(watchlist_id: str)

Read one watchlist by id. Returns the full recipe DSL + delivery config + match-history summary.

create_watchlistFree
create_watchlist(name, recipe, ...delivery)

Save a recipe as a watchlist so new matches trigger webhooks. Optional delivery config (webhook endpoint(s), notification cadence).

update_watchlistFree
update_watchlist(watchlist_id, ...fields)

Patch a watchlist's recipe, name, or delivery config. Partial updates supported.

delete_watchlistFree
delete_watchlist(watchlist_id)

Hard-delete a watchlist + every linked webhook. Match history retained for 90 days for audit.

run_watchlist1 lead-view per match in results
run_watchlist(watchlist_id, ...overrides)

Re-execute a watchlist's recipe against the latest ingestion snapshot. Returns matches without waiting for the next scheduled run.

poll_new_matches1 lead-view per new match
poll_new_matches(watchlist_id, since_cursor?)

Return only the matches that have arrived since the last poll. The watchlist's next-poll cursor advances on success — call this in a loop for a near-real-time feed without webhooks.