Installation
Install @plainwork/mcp via NPM (stdio) or self-host the HTTP remote transport.
Last updated
Installation
Two install paths, both shipped today:
- Via NPM (stdio) — the default for local hosts: Claude Desktop, Claude
Code, Cursor. No install step;
npxfetches the package on demand. - Self-hosted HTTP (remote) — one shared server process that multiple
agents or orchestrators can connect to over HTTP + SSE. Ship it in Docker
or run the built
dist/index.jsdirectly.
Pick one. Both speak the same MCP over the same tool set; only the transport differs.
Before you install
You need a Plainwork agent API key. See
Authentication for the walk-through. The short
version: Settings → Agents → New agent, copy the pw_agent_… token
(shown once).
Node 22 or newer is required (the package declares "engines": { "node": ">=22" }).
Via NPM (stdio)
This is the 95% case. npx pulls the latest published version of
@plainwork/mcp on each launch, so you never need to manage local installs.
Smoke-test it outside any host first:
PLAINWORK_API_KEY=pw_agent_... \
npx -y @plainwork/mcp
The process should start, log nothing, and wait for JSON-RPC on stdin. Hit
Ctrl+C to stop.
Pinning a version
Bare @plainwork/mcp always gets the latest. In production hosts, pin:
npx -y @plainwork/mcp@0.1.0
Offline behaviour
npx --yes caches packages under ~/.npm/_npx/. First run with no network
fails; subsequent runs work offline as long as the cache is intact. If you
need guaranteed offline behaviour, install globally:
npm install -g @plainwork/mcp
plainwork-mcp # now on PATH
Then point hosts at the plainwork-mcp binary instead of npx.
Wiring into a host
See the per-host guides:
Self-hosted HTTP (remote)
Use this when you want one shared MCP process instead of spawning an
npx-backed stdio child per host — for example, an n8n workflow or a
browser-based orchestrator that speaks HTTP + SSE.
There are two supported ways to run the HTTP transport.
Option A — Docker
The package ships with a ready-to-build Dockerfile at apps/mcp/Dockerfile
in the monorepo. It builds the server, exposes port 9090, and sets
MCP_TRANSPORT=http.
# From the repo root:
docker build -f apps/mcp/Dockerfile -t plainwork-mcp .
docker run --rm -p 9090:9090 \
-e PLAINWORK_API_KEY=pw_agent_... \
plainwork-mcp
Check it's up:
curl -i http://localhost:9090/mcp
# The server answers GET /mcp with an SSE stream. You should see HTTP/1.1 200
# and a `Content-Type: text/event-stream` header.
Option B — Build locally and run with Node
From a clone of the monorepo:
pnpm --filter @plainwork/mcp build
PLAINWORK_API_KEY=pw_agent_... \
MCP_TRANSPORT=http \
node apps/mcp/dist/index.js
# or pass --http explicitly:
# node apps/mcp/dist/index.js --http
Port and host
The HTTP server binds to 0.0.0.0:9090 by default. Override the port with
MCP_HTTP_PORT:
MCP_HTTP_PORT=8080 MCP_TRANSPORT=http node apps/mcp/dist/index.js
Sessions
The HTTP transport is session-aware. The first request receives an
mcp-session-id header; include that header on every subsequent request to
stay on the same session. See Transports for
endpoint details and Custom HTTP client
for a raw-curl example.
What is not included
Today the HTTP transport binds one agent API key to the whole process at
startup — every request from every client uses that key. A hosted,
multi-tenant endpoint where each request authenticates with its own
Authorization: Bearer token is not shipped yet. Until it is, self-host per
agent or per tenant.
Environment variables
| Variable | Default | Notes |
|---|---|---|
PLAINWORK_API_KEY | — | Required. Must start with pw_agent_. |
PLAINWORK_API_URL | https://api.plainwork.xyz/v1 | Point at a self-hosted API (keep the /v1 suffix). |
MCP_TRANSPORT | stdio | Set to http for the remote transport. |
MCP_HTTP_PORT | 9090 | HTTP transport port. |
LOG_LEVEL | warn | silent | error | warn | info | debug. |
Missing or malformed env vars cause the process to exit with a clear message.