Connect Cursor (MCP)¶
Cursor talks to RealtyPad over HTTP MCP on the same API host as the REST API.
Prerequisites¶
- Cursor installed
- RealtyPad account (web login works)
- API reachable from your machine (local:
http://localhost:8000, production: your operator’s HTTPS URL) PUBLIC_BASE_URLset to the public API origin (MCP discovery / token endpoints)WEB_BASE_URLset to the web UI origin (consent page; local defaulthttp://localhost:5173)
Step 1 — Add the MCP server (browser OAuth)¶
Preferred: Cursor discovers OAuth, opens your browser, you sign in and approve the agent. No pasted Bearer token.
- Open Cursor Settings → MCP (or edit MCP config).
- Add a server with the MCP URL only:
Local example (API on port 8000):
{
"mcpServers": {
"RealtyPad": {
"url": "http://localhost:8000/mcp"
}
}
}
Production example:
{
"mcpServers": {
"RealtyPad": {
"url": "https://api.yourdomain.com/mcp"
}
}
}
- Save and reload MCP. Cursor should prompt to authorize → browser opens the web app at
/oauth/consent→ sign in (if needed) → Authorize. - Ask the agent to call
list_deals(limit 3). You should see deals from your tenant only.
If you see “Protected resource … does not match expected”¶
Clear the server’s stored OAuth state in Cursor (remove/re-add the MCP server, or clear auth), then reconnect. The MCP URL should be without a trailing slash:
http://localhost:8000/mcp
If you see “Authorization session ended” / Cursor never gets the URL¶
Cursor’s cloud callback (cursor.com/.../oauth/callback) often fails against a localhost MCP URL. Prefer mcp-remote (local :8787 callback) or fully quit Cursor (Cmd+Q) and reconnect:
{
"mcpServers": {
"RealtyPad": {
"command": "npx",
"args": ["-y", "mcp-remote@latest", "http://localhost:8000/mcp", "8787"]
}
}
}
If the browser never opens¶
Known Cursor issue: discovery succeeds but openExternal never runs. Try in order:
- In Settings → MCP, click Needs authentication (not only Connect).
- Open Output → MCP: RealtyPad, find
Redirect to authorization/ authorize URL, paste it into a browser. - Or use the
mcp-remotestdio proxy above.
Fallback — static agent JWT¶
If you need a long-lived token without the browser flow:
- Sign in to the web app.
- Open Agent → Mint agent JWT.
- Configure MCP with a Bearer header:
{
"mcpServers": {
"RealtyPad": {
"url": "http://localhost:8000/mcp",
"headers": {
"Authorization": "Bearer eyJhbGciOiJIUzI1NiIs..."
}
}
}
}
Troubleshooting¶
| Symptom | What to check |
|---|---|
401 / no authorize prompt |
PUBLIC_BASE_URL must match the URL Cursor uses; MCP_OAUTH_ENABLED must be true |
| Consent opens on API HTML / wrong host | Set WEB_BASE_URL to the web UI (e.g. http://localhost:5173) and restart API |
| Empty deals | Token/consent bound to a different workspace |
| Connection refused | Wrong host/port; production requires HTTPS |
Docker MCP vs remote HTTP¶
Some setups use a Docker MCP bridge (user-HouseMaxxMCP) on the operator’s machine. For a shared hosted API, prefer the remote HTTP URL above so OAuth scopes to your tenant on the server. Local bridges must send a Bearer agent JWT (or use remote URL + browser OAuth).
Revoking access¶
Deny on the consent screen, rotate passwords, or mint a new agent JWT and drop the old one from Cursor config. OAuth refresh tokens are server-side and expire (~90 days).