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; npx fetches 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.js directly.

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

VariableDefaultNotes
PLAINWORK_API_KEYRequired. Must start with pw_agent_.
PLAINWORK_API_URLhttps://api.plainwork.xyz/v1Point at a self-hosted API (keep the /v1 suffix).
MCP_TRANSPORTstdioSet to http for the remote transport.
MCP_HTTP_PORT9090HTTP transport port.
LOG_LEVELwarnsilent | error | warn | info | debug.

Missing or malformed env vars cause the process to exit with a clear message.