{
  "markdown": "# Livespace CRM MCP Server\n\nUnofficial [MCP](https://modelcontextprotocol.io) server for\n[Livespace CRM](https://www.livespace.io). It exposes 11 intent-shaped tools\ninstead of mirroring the raw API and targets the stateless Streamable HTTP\ntransport in MCP spec 2026-07-28.\n\nVersion 0.1.1 is available on\n[npm](https://www.npmjs.com/package/livespace-crm-mcp/v/0.1.1), in the\n[official MCP Registry](https://registry.modelcontextprotocol.io/v0.1/servers/io.github.proAutomator%2Flivespace-crm-mcp/versions/0.1.1),\nand as a [GitHub Release](https://github.com/proAutomator/livespace-crm-mcp/releases/tag/v0.1.1).\n\nThe v1 implementation is complete in this repository. It has six read tools\nand five optional write tools, read-only defaults, bounded API access,\nsanitized errors and an elicitation-first confirmation flow. Use a test\nLivespace account while evaluating it.\n\n## Why this shape?\n\nLivespace's RPC API has about 80 methods, but it does not provide sorting,\naggregation or a direct operation for setting a deal stage. The server groups\nthose lower-level calls into tasks an MCP client can use safely:\n\n- discovery before IDs are used;\n- bounded search, record reads and analysis;\n- batch previews before writes;\n- per-item outcomes and post-write checks;\n- explicit handling of Livespace-specific stage moves and notifications.\n\n## Tools\n\n| Tool | Mode | Purpose and bound |\n|---|---|---|\n| `health` | Read | Checks the server; `checkLivespace: true` also makes one lightweight Livespace API call. |\n| `crm_metadata` | Read | Returns nine dictionary sections, including processes, users, groups, sources, task dictionaries, products and the current user. |\n| `search_crm` | Read | Finds persons, companies or deals. Sorted deal searches use one 200-record sort window and report truncation. |\n| `get_records` | Read | Reads one record kind and up to 25 ids; walls for at most 5 persons, companies or deals. |\n| `get_activity` | Read | Reads one record wall, one bounded CRM feed range or bounded task pages per call. |\n| `analyze` | Read | Runs one named aggregation over bounded windows and reports whether its source window was truncated. |\n| `create_records` | Write | Creates persons, companies, deals or tasks. Up to 10 items per call, with exact-match contact deduplication by default. |\n| `update_records` | Write | Updates persons, companies, deals or tasks. Up to 10 items per call. |\n| `log_activities` | Write | Adds public notes or phone calls. Up to 15 notes or calls per call. |\n| `move_deals_to_stage` | Write | Moves deals by applying the minimal process-step diff. Up to 10 items per call; backward moves need an explicit allowlist. |\n| `notify_user` | Write | Dispatches one in-app notification, limited to 5 per 10 minutes and 1 per recipient per minute. |\n\n`move_deals_to_stage` works by checking and unchecking process steps because\nLivespace has no \"set stage\" call. A deal stands at its furthest checked step.\nA backward move therefore unchecks completed steps and can change the\nhistorical meaning of those checkboxes.\n\n`notify_user` validates the recipient and can add a deep link to a record.\nLivespace provides no notification read-back, so the tool reports a successful\nrequest as dispatched, never as delivered.\n\n## Requirements\n\n- A Livespace plan with API access, currently Automation or higher.\n- One Livespace API key and secret from `Account settings -> API -> Users`.\n  Use a dedicated Livespace API user with only the permissions this MCP needs.\n  Every API operation inherits that user's permissions.\n- Bun 1.3.14 or newer ([bun.sh](https://bun.sh)). The current server uses\n  `Bun.serve` and has no Node.js or Cloudflare Workers adapter.\n\nThe v1 deployment model is single-user: one Livespace credential pair and, if\nenabled, one MCP bearer token protects the server. There is no OAuth or\nmulti-user credential routing.\n\n## Install and run from npm\n\nThe package is distributed through npm's public registry, but Bun is its\nruntime. You do not need Node.js or the npm CLI to run it.\n\nFor a first evaluation, create a private working directory outside a Git\nrepository. Add a `.env` file there with your own Livespace credentials:\n\n```dotenv\nLIVESPACE_SUBDOMAIN=\nLIVESPACE_API_KEY=\nLIVESPACE_API_SECRET=\n```\n\nFill the three empty values, protect the file, then start the published\npackage:\n\n```bash\nchmod 600 .env\nbunx livespace-crm-mcp\n```\n\nThe default endpoint is `http://127.0.0.1:3020/mcp`. Keep the process running\nwhile your MCP client is connected. Start in read-only mode, call `health`,\nthen use `crm_metadata` before any operation that needs a user, process, stage,\ngroup or dictionary ID.\n\n`bunx` downloads the package from npm and caches it locally. To pin this\nsecurity release, run `bunx livespace-crm-mcp@0.1.1`.\n\n## Connect an MCP client\n\nConfigure a client that supports Streamable HTTP with this server URL:\n\n```json\n{\n  \"url\": \"http://127.0.0.1:3020/mcp\"\n}\n```\n\nThe exact configuration field differs between clients. Set `MCP_AUTH_TOKEN`\nand configure the client to send `Authorization: Bearer <your-token>`, even on\nloopback. Authentication is mandatory when write tools are enabled.\n\nThis package exposes Streamable HTTP, not stdio. Some MCP clients can connect\nto the local URL but cannot launch `bunx` for you, so start the command in a\nseparate terminal. Clients that accept only stdio are not supported yet. Each\nHTTP request must contain one JSON-RPC message; top-level batch arrays are\nrejected before dispatch.\n\n## Configuration\n\n| Variable | Purpose |\n|---|---|\n| `LIVESPACE_SUBDOMAIN` | Account subdomain without protocol or `.livespace.io`. |\n| `LIVESPACE_API_KEY` / `LIVESPACE_API_SECRET` | Credentials for one Livespace user. |\n| `MCP_PORT` | Server port. Default: `3020`. |\n| `MCP_BIND_HOST` | Bind address. Default: `127.0.0.1`. |\n| `MCP_AUTH_TOKEN` | Random bearer token of at least 32 bytes. Required for writes and on a non-loopback bind; recommended for every server. |\n| `LIVESPACE_MCP_ENABLE_WRITES` | Set to `true` to expose write tools. Default: `false`. |\n| `LIVESPACE_MCP_READ_ONLY` | Emergency kill-switch. `true` removes and blocks write tools even when enabled above. |\n| `MCP_REQUEST_STATE_KEY` | Independent random secret of at least 32 bytes used to sign write confirmations. Required when writes are enabled. |\n| `MCP_ALLOW_UNBOUND_WRITE_CONFIRMATION` | Unsafe compatibility mode for clients without form elicitation. Default: `false`. |\n| `MCP_ALLOWED_HOSTS` | Host-header allowlist for DNS-rebinding protection. Required on a non-loopback bind. |\n| `MCP_ALLOWED_ORIGIN_HOSTNAMES` | Optional additional browser-origin hostnames. On a non-loopback bind it defaults to `MCP_ALLOWED_HOSTS`. |\n| `MCP_RATE_LIMIT_PER_MINUTE` / `MCP_RATE_LIMIT_BURST` | Per-principal request rate. Defaults: 120 per minute and burst 30. |\n| `MCP_MAX_CONCURRENT_REQUESTS` / `MCP_MAX_QUEUED_REQUESTS` | Admission limits. Defaults: 8 in flight and 16 queued. |\n| `MCP_REQUEST_INGRESS_TIMEOUT_MS` | Absolute limit for admission queueing plus body upload, not tool execution. Default: 10000; maximum: 60000. |\n| `MCP_REQUEST_EXECUTION_TIMEOUT_MS` | Absolute limit for tool execution after upload. Default: 90000; maximum: 300000. |\n\nThe server refuses a non-loopback bind unless `MCP_AUTH_TOKEN` and\n`MCP_ALLOWED_HOSTS` are set. It also refuses to enable writes without both\n`MCP_AUTH_TOKEN` and `MCP_REQUEST_STATE_KEY`. Once `MCP_AUTH_TOKEN` is\nconfigured, every `/mcp` request needs that Bearer token, including on\nloopback. Host and Origin checks run before the MCP handler.\n\nGenerate independent values for `MCP_AUTH_TOKEN` and `MCP_REQUEST_STATE_KEY`\nby running `openssl rand -hex 32` twice. Do not reuse a Livespace credential.\n\nThe Bun process does not terminate TLS. Put a TLS-capable reverse proxy in\nfront of every network-exposed deployment. The server reads credentials from\nenvironment variables, commonly through Bun's `.env` loading; protecting\n`.env` at rest is the operator's responsibility. Never commit it. The smoke\nscript can also read the sandbox credentials from the macOS Keychain.\n\n## Write safety\n\nThe normal flow is elicitation-first:\n\n1. A plain write-tool call or `dryRun: true` builds a plan and writes nothing.\n2. On an elicitation-capable client, the server asks a human to approve the\n   plan. A `confirm: true` argument cannot bypass this prompt.\n3. The confirmation exchange uses a signed `requestState` that is valid for\n   five minutes and consumed after an accepted or declined response. It is\n   bound to the authenticated principal when present, the tool, arguments and\n   preview.\n4. If the relevant records changed before approval, the tool returns\n   `recordsChanged: true`, writes nothing and presents a fresh plan.\n\nWrite execution is disabled by default on clients without form elicitation.\nThose clients can preview, but `confirm: true` is refused. An operator can set\n`MCP_ALLOW_UNBOUND_WRITE_CONFIRMATION=true` for compatibility. In that mode,\n`confirm: true` executes without signed proof that a human saw the preview.\n\nResults distinguish these cases:\n\n- `verification: verified` means the server re-read comparable fields after\n  the write.\n- A successful write can still report `verification: unavailable` when a\n  follow-up read failed, no sent field had an independent comparator or the\n  upstream API exposes no read-back. Inspect that item's error and re-read the\n  record where possible; do not retry the write.\n- `unknown_outcome` means the request may or may not have landed. Never retry\n  it blindly.\n- `not_attempted` means that item was not sent, usually because a time budget\n  expired or an earlier item hit the upstream rate limit. Those unsent items\n  can be submitted later; follow the error hint for the rate-limited item.\n\nNotification success is reported as dispatched, never as delivered. If\ndelivery matters, confirm it by another channel instead of sending a duplicate\nnotification.\n\n## Security and privacy\n\nCRM names, notes, imported e-mails, task text and wall entries are untrusted\ndata. The server never evaluates them as instructions, but the MCP host and\nmodel can still be influenced by their contents. Keep writes disabled unless\nthe client provides a human confirmation flow. Fetch only the records and\ndetail level needed for the task.\n\nTool responses can be retained by the MCP host, model provider or local client\nlogs. Choose a host whose storage, training and retention policy fits the CRM\ndata you process. This server stores no CRM records on disk and sends no\ntelemetry, but it cannot control what the host does after receiving a result.\n\nUse a dedicated Livespace API user rather than an administrator's key. Give it\nthe smallest useful record and write permissions. Evaluate the MCP against a\nseparate test account before connecting it to business data.\n\nFor a reverse proxy, terminate TLS, disable caching and do not log MCP request\nor response bodies. The server sets `Cache-Control: no-store` and\n`Vary: Authorization`, but proxy policy must preserve those protections.\n\n## Incident response\n\nIf a Livespace key, bearer token or confirmation key may be compromised:\n\n1. Stop the MCP server.\n2. Immediately revoke the Livespace API key and issue a replacement for the\n   dedicated API user.\n3. Generate new, independent `MCP_AUTH_TOKEN` and `MCP_REQUEST_STATE_KEY`\n   values.\n4. Restart the server and update the MCP client's Bearer header.\n5. Review Livespace's record and activity history for unexpected writes. Do\n   not retry any operation that previously returned `unknown_outcome`.\n\n## v1 limits\n\n- No delete or merge operations.\n- No tag or custom-field writes in v1. Livespace documents tag changes through\n  `tag_add` and `tag_remove`, and custom fields through `dataset`. Tag writes\n  still need a sandbox probe using those exact keys. Custom-field writes\n  cannot be verified until the sandbox has fields covering the supported\n  types, including answer ids for select fields.\n- Tasks created here cannot be linked to records. Livespace's\n  [`Todo/addTodo` documentation](https://api-docs.livespace.io/#fa921958-129d-480d-b613-6439e88fd516)\n  describes links through `todo.objects`, but our sandbox probe returned\n  success and echoed the submitted link while a fresh read returned\n  `objects: []`. The exact raw probe payload was not retained, so the result\n  is inconclusive. The server omits `objects` from task writes until a\n  controlled probe confirms that the link persists. Existing links returned\n  by Livespace are still exposed as `linkedRecords`.\n- Logged notes and calls cannot be edited or removed.\n- Deal updates cover name and status; stage changes use\n  `move_deals_to_stage`. `create_records` can set budget lines when it creates\n  a deal, but `update_records` does not edit an existing budget because the\n  append-versus-replace behavior has not been verified.\n- `stage_conversion` is a point-in-time estimate because Livespace exposes no\n  stage history.\n- Reads and analyses use bounded windows. Inspect truncation fields before\n  treating a result as complete.\n- Missing values and mixed currencies can make monetary sums `null`; the\n  result names the reason.\n- API ids differ from the ids shown in the Livespace UI. Use IDs returned by\n  `crm_metadata`, `search_crm` or another tool and never guess them.\n\n## Development\n\nTo work from source instead of the published package:\n\n```bash\ngit clone https://github.com/proAutomator/livespace-crm-mcp.git\ncd livespace-crm-mcp\nbun install\ncp .env.example .env\nbun run dev\n```\n\nThe repository commands are:\n\n```bash\nbun test                 # complete offline suite\nbun run test:security    # focused security contract from docs/security.md\nbun run typecheck\nbun run smoke            # live test-account check via .env or macOS Keychain\nbun run dev\n```\n\n`bun run smoke` and `health` with `checkLivespace: true` make real API calls.\nUse only a test Livespace account, never a production CRM.\n\nThe binding threat model and regression map are in\n[docs/security.md](https://github.com/proAutomator/livespace-crm-mcp/blob/main/docs/security.md).\nReport vulnerabilities privately as described in\n[SECURITY.md](https://github.com/proAutomator/livespace-crm-mcp/blob/main/SECURITY.md).\n\n## Disclaimer\n\nCommunity project. Not affiliated with, endorsed by or supported by Livespace\nS.A. \"Livespace\" is a trademark of its owner and is used here only to describe\ncompatibility. Operations through the Livespace API run under your API key and,\nunder Livespace's terms of service, at your responsibility.\n\n## Attribution\n\nThis server follows patterns from Adam Gospodarczyk's (overment) MCP servers,\nespecially\n[iceener/streamable-mcp-server-template](https://github.com/iceener/streamable-mcp-server-template)\n(MIT): a small intent-shaped tool surface, operating instructions, batch-first\nwrites with per-item results and errors with recovery hints. Thanks, Adam.\n\n## Author\n\nBuilt by [Kuba Masztalski](https://kubamasztalski.pl)\n\n- LinkedIn: [linkedin.com/in/kuba-masztalski](https://www.linkedin.com/in/kuba-masztalski/)\n- X: [@proAutomator](https://x.com/proAutomator)\n\nBugs and feature requests:\n[GitHub Issues](https://github.com/proAutomator/livespace-crm-mcp/issues).\nSecurity reports: see [SECURITY.md](SECURITY.md).\n\n## License\n\n[MIT](LICENSE)\n",
  "bytes": 15284,
  "sha": "c3d55d7d972c88428bdb02535c4a7fe35a56162548f18cdec78f7a27efa4a0ec",
  "repo_slug": "proautomator/livespace-crm-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_proautomator_livespace_crm_mcp_2f77685e/readme"
}