Pencil MCP Server
Connect an MCP client through hosted OAuth, an API key, or local stdio.
Use Pencil from your MCP client to find tasks, read context, and save work. Hosted MCP does not require Pencil Gateway. Install the gateway only when your client needs a local stdio connection or you want to run Pencil-assigned work on your computer.
Choose a connection
| Your client needs | Use |
|---|---|
| A remote server URL | https://your-pencil-host.example.com/api/mcp with OAuth |
| A remote URL with a static bearer header | The same endpoint with an MCP-enabled Pencil API key |
| A local command, without pairing a task runtime | pencil-gateway mcp --oauth |
| A local command using an existing paired device | pencil-gateway mcp |
Replace the example host with your Pencil instance. See Pencil Gateway for installation and device pairing. Running pencil-gateway start is not required for an MCP client connection.
Hosted remote MCP
Add your Pencil instance's /api/mcp URL to your client's remote-server configuration. Choose OAuth when supported, then sign in, select your workspace, and approve access. Pencil supports discovery, dynamic client registration, PKCE, refresh-token rotation, and revocation.
For clients with static headers, organization admins can create a key in Settings → API Keys with MCP access enabled. Existing REST-only keys do not work for MCP.
POST /api/mcp
Authorization: Bearer pk_live_...
Content-Type: application/json
Read keys grant mcp:read; write keys grant mcp:read mcp:write. API keys are long-lived bearer secrets with optional expiry and do not receive offline_access.
Local stdio with OAuth
After installing the gateway package, run:
pencil-gateway mcp --oauth
The first run opens Pencil for sign-in, workspace selection, and consent. Registration and rotating tokens are stored with user-only permissions in ~/.pencil/mcp-oauth.json. No device pairing is needed.
Configure your stdio client with:
{
"mcpServers": {
"pencil": {
"command": "pencil-gateway",
"args": ["mcp", "--oauth"]
}
}
}
Use --account work for a separate profile and --mc-url https://your-pencil.example.com (or PENCIL_MC_URL) for self-hosted Pencil. Include the same flags in the client's args. If consent port 8787 is busy, choose another with --oauth-callback-port <port>.
OAuth stdio proxies the hosted endpoint and follows its workspace, scope, and tool restrictions. It cannot be combined with --include-dangerous.
Local stdio with device pairing
Complete gateway pairing, then use the config above with "args": ["mcp"]. For a named pairing, use "args": ["mcp", "--account", "work"].
The server reads the selected gateway config, uses its saved Pencil URL and device token, fetches the tool catalog, and forwards calls to Pencil. Workspace and task-access checks still apply server-side.
Task progress and ownership
update_task_status follows the authenticated caller:
| Caller | Task status permissions |
|---|---|
| OAuth human or paired gateway | The authenticated person's Pencil UI permissions, including tasks without an assigned agent. |
| Internal agent context | The invoking workspace agent may transition its assigned tasks or human-owned tasks. On truly unassigned tasks it may set review, blocked, or in_progress; other statuses require an owner. |
| API key | Uses the task's assigned Pencil agent. An API key does not identify an invoking workspace agent; passing an agentId tool argument cannot supply one. |
For unassigned work, use review to request confirmation or blocked to record an obstacle. Progress is attributed to the invoking agent in task history without changing assignment. A refused completion returns TASK_UNASSIGNED_REQUIRES_OWNER, allowed statuses, and remedies such as assign_task or update_task_status(status=review). A caller without an agent identity receives TASK_AGENT_REQUIRED with assignment and OAuth alternatives. Completion still checks checklists and review gates.
assign_task can explicitly claim unassigned work, subject to workspace and assignment-readiness checks. autoPickupDisabled only controls automatic pickup of inbox work; progress reports preserve it and do not claim a task. update_task edits metadata and may promote backlog work into inbox when assigning a sprint. set_task_phase changes phase membership and schedules gate release. Neither metadata tool accepts an arbitrary completion status; use update_task_status for that.
Troubleshooting
| Symptom | What to check |
|---|---|
| No local tools appear | Confirm the gateway executable is on the client's PATH and restart the client. For paired mode, run pencil-gateway doctor with the matching account. |
| Paired mode returns 401 | Follow Gateway troubleshooting. |
| Hosted MCP returns 401 | Reconnect OAuth or verify the API key is current. |
| Hosted MCP returns 403 | Check MCP access and the grant's read/write scopes. |
| Wrong self-hosted instance | Set --mc-url for OAuth, or re-pair the device with the correct URL. |
| A listed tool fails | Check the returned task, workspace, assignment, or permission error. |
Admins can inspect transport, caller, status, and duration in Settings → Integrations → Access Telemetry. Tool arguments and bearer tokens are not recorded.
What to try next
Read MCP tools and permissions to choose the tools your client can use.