Coding Agents MCP
Connect Claude Code, Codex, Cursor, or any MCP client to Plaine so a coding agent can message you when it needs a decision and continue once you reply.
First-release Plaine MCP uses local stdio. The MCP process runs on your machine with an agent API key, so future E2EE support can keep private keys outside Plaine.
Hosted HTTP MCP is not the recommended setup. It runs on Plaine’s servers and cannot decrypt private E2EE conversations without Plaine seeing plaintext or key material.
Why Plaine cares about project labels
Plaine creates separate conversations so one coding session does not bleed into another. For coding agents, the natural boundary is usually the local project folder plus the machine running the agent.
Local stdio MCP can read cwd and hostname, so it can derive a stable label like laptop:plane-messaging automatically. That lets Plaine open one conversation per project without asking you to paste conversation ids.
Recommended setup: local stdio
Use local stdio when you want one install to create separate Plaine conversations per local project folder. The Python package has no runtime dependencies and keeps the local process lighter.
Create a pull-mode agent in Plaine first. Open local runtime setup. Local stdio uses that agent’s API key as PLAINE_API_KEY.
If other Plaine users will talk to this agent, finish the agent’s Encryption setup before inviting them. Owner-self setup conversations work immediately; peer conversations require the agent public key.
For Claude Code:
claude mcp add plaine uvx plaine mcp \
--env PLAINE_API_KEY=plane_xxx \
--env PLAINE_API_BASE=https://plaine.chat
For Codex:
[mcp_servers.plaine]
command = "uvx"
args = ["plaine", "mcp"]
env = { PLAINE_API_KEY = "plane_xxx", PLAINE_API_BASE = "https://plaine.chat" }
Generic MCP JSON:
{
"mcpServers": {
"plaine": {
"command": "uvx",
"args": ["plaine", "mcp"],
"env": {
"PLAINE_API_KEY": "plane_xxx",
"PLAINE_API_BASE": "https://plaine.chat"
}
}
}
}
The Node package remains available:
claude mcp add plaine npx @plaine/mcp \
--env PLAINE_API_KEY=plane_xxx \
--env PLAINE_API_BASE=https://plaine.chat
Local stdio auto-labels each conversation from ${hostname}:${basename(cwd)} on first run. Override with PLAINE_CONVERSATION_LABEL=my-label if you want a stable name of your own, or PLAINE_CONVERSATION_ID=conv_xxx to pin to a specific existing conversation.
If two local MCP sessions boot in the same folder, the second one detects the first via a pidfile (${TMPDIR}/plaine-mcp-*.pid) and suffixes its label with its own pid so the two sessions get separate conversations.
Tools
message_user(text)— send a message to you, no wait.poll_messages(since?)— check for user messages after a cursor, no blocking.wait_for_message(timeout_s?, since?)— block until you reply or the timeout hits.send_and_wait(text, timeout_s?)— send a message, then block for the next reply after that message.describe_message_capabilities()— report the local runtime’s transport, encryption, and message-shape support.
Use send_and_wait when your agent is asking a direct question. It uses the sent message id as the cursor, so older unread messages are not treated as the answer. If your MCP client does not support that tool yet, pass the messageId returned by message_user as since when calling wait_for_message.
Current local stdio packages are plaintext-only for owner-self setup conversations. If a conversation is client-side-e2ee-v1, they refuse until local device-key unwrap, decrypt, and encrypt support lands.
Local stdio registers an agent-runtime device through POST /api/agent/devices on first use. The API key identifies the agent; the private runtime key stays on the local machine. By default, Python MCP uses the OS secure storage backend exposed by keyring. Set PLAINE_AGENT_DEVICE_KEY_FILE only when you intentionally want to store the generated runtime private key in a local file.
Tool approvals arrive through the same polling tools as text replies. If your coding agent sends an approval-requested tool part through Plaine’s API, wait until poll_messages or wait_for_message returns a user message containing data-tool-approval with the matching toolCallId, then resume or skip the tool from that recorded decision.
Config summary: local stdio
| Env var | Required | Default |
|---|---|---|
PLAINE_API_KEY | yes | — |
PLAINE_CONVERSATION_ID | no | auto-provisioned from label |
PLAINE_CONVERSATION_LABEL | no | ${hostname}:${basename(cwd)} |
PLAINE_API_BASE | no | https://plaine.chat |
PLAINE_ON_TIMEOUT | no | stop |
PLAINE_AGENT_DEVICE_KEY_FILE | no | OS secure storage |
Troubleshooting
- Hosted HTTP MCP returns a privacy error — use local stdio MCP. Hosted HTTP MCP runs on Plaine servers and cannot decrypt private E2EE conversations.
- Peers cannot start or accept conversations with this agent — finish the agent’s Encryption setup. Peer conversations require the agent public key; owner-self setup conversations do not.
PLAINE_API_KEY is required— the local stdio package needs an API key minted from the agent’s manage page.plaine inbox failed: 401— the API key is wrong, revoked, or scoped to a different agent.- Manage page shows “Last poll — polling may have stopped” — your local stdio MCP process is not polling. Check your MCP client logs.