> ## Documentation Index
> Fetch the complete documentation index at: https://docs.plane.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Set up Plane MCP

> Connect an MCP client like Claude or ChatGPT to your Plane workspace using the Model Context Protocol, then ask it questions about your data.

This guide walks you through connecting an MCP client to your Plane workspace so
you can ask it questions about workers, payroll, and payments in plain English.
By the end, you will have a client connected over OAuth and reading live data
from your workspace.

## What is MCP?

The **Model Context Protocol (MCP)** is an open standard that lets an
application call external tools in a consistent way. An app that connects to MCP
servers is called an **MCP client**. Most AI assistants, such as Claude and
ChatGPT, act as the MCP client here.

Plane provides an **MCP server** that exposes a set of tools for your workspace,
so your MCP client can look up your data on your behalf instead of you clicking
through screens.

You do not install anything. Plane's MCP server is remote: you point your MCP
client at one URL and sign in.

## What is a connector?

A **connector** is how an MCP client registers an MCP server. Different clients
name it differently. Claude calls it a connector, and ChatGPT calls it an app.
Either way the setup is the same: you add Plane as a custom connector by
entering its URL, the client handles sign-in, and then it discovers the tools
Plane exposes.

<Note>
  The Plane MCP surface is **read-only** today. Use it to list and read records
  such as workers, payrolls, and payments.
</Note>

## Prerequisites

* A Plane account with admin or manager access to the workspace
* An MCP client that supports remote HTTP MCP servers, such as Claude or ChatGPT
* OAuth support in your client, or a [Plane API key](/product/workspace#api-access)
  for the manual fallback

<Warning>
  Keep API keys and access tokens secret. Do not paste credentials into public
  repositories, shared chat logs, client-side code, or anywhere people outside
  your organization can read them.
</Warning>

## Endpoint

Point your MCP client at:

```text theme={null}
https://api.plane.com/mcp
```

Most clients handle the rest automatically: they discover Plane's authorization
server and prompt you to sign in with your Plane credentials. You usually only
need to provide the `/mcp` URL.

## Connect your client

OAuth is the recommended way to connect. You add Plane as a connector, sign in
through the browser, and the client receives a short-lived access token scoped
to your Plane permissions. Pick your client below.

<Tabs>
  <Tab title="Claude">
    <Steps>
      <Step title="Open connectors">
        In Claude, click **Customize**, then **Connectors**.
      </Step>

      <Step title="Add a custom connector">
        Click the **+** button and choose **Add custom connector** (not **Browse
        connectors**). When prompted, enter a name such as `Plane` and set the
        remote MCP server URL to `https://api.plane.com/mcp`.
      </Step>

      <Step title="Sign in to Plane">
        Complete the Plane sign-in flow in the browser when Claude prompts you.
      </Step>

      <Step title="Use Plane in a chat">
        Start a new conversation, make sure the Plane connector is enabled, and
        try `List the first 10 workers in Plane`.

        <Check>
          Claude calls `workers_list` and returns the result.
        </Check>
      </Step>
    </Steps>

    If your Claude Desktop build cannot complete the OAuth flow, use the
    [manual API key fallback](#manual-api-key-fallback) below.
  </Tab>

  <Tab title="ChatGPT">
    Set this up in ChatGPT on the web (`chatgpt.com`). The desktop apps may not
    offer custom MCP setup.

    <Steps>
      <Step title="Enable developer mode">
        Go to **Settings > Apps > Advanced settings** and turn on **Developer
        mode**. ChatGPT flags this as elevated risk because it allows custom,
        unverified connectors; it may also be restricted by your workspace
        admin.
      </Step>

      <Step title="Create the app">
        Back on **Settings > Apps**, click **Create app**. In the **New App**
        dialog, enter a name such as `Plane`, set **Connection** to **Server
        URL**, and enter `https://api.plane.com/mcp`. Set **Authentication** to
        **OAuth**.
      </Step>

      <Step title="Confirm and connect">
        Check **I understand and want to continue**, click **Create**, and
        complete the Plane sign-in flow when prompted.
      </Step>

      <Step title="Use Plane in a chat">
        Start a new conversation, make sure the Plane app is enabled, and try
        `List the first 10 workers in Plane`.

        <Check>
          ChatGPT calls `workers_list` and returns the result.
        </Check>
      </Step>
    </Steps>
  </Tab>
</Tabs>

<Note>
  Connect over OAuth only when you want the client to work with live workspace
  data. To experiment safely, use a sandbox API key with the manual fallback.
</Note>

## Try it

Once connected, start with prompts that read data:

* `List the workers we paid in May.`
* `How much did we pay [contractor name] this year?`
* `Show me the most recent payroll and what it totaled.`
* `Which payments are still pending?`
* `Pull a list of contractors hired in the last 90 days.`

## What you can do today

Tool names follow `{resource}_{action}`, for example `workers_list` or
`payments_get`. List tools accept pagination arguments: `limit`, `cursor`,
`starting_after`, and `ending_before`.

<Accordion title="All available tools">
  | Resource                   | Tools                                                               |
  | -------------------------- | ------------------------------------------------------------------- |
  | Benefit elections          | `benefit_elections_get`, `benefit_elections_list`                   |
  | Benefit enrollments        | `benefit_enrollments_get`, `benefit_enrollments_list`               |
  | Benefit events             | `benefit_events_get`, `benefit_events_list`                         |
  | Benefit plans              | `benefit_plans_get`, `benefit_plans_list`                           |
  | Benefit programs           | `benefit_programs_get`, `benefit_programs_list`                     |
  | Charges                    | `charges_get`, `charges_list`                                       |
  | Classifications            | `classifications_get`, `classifications_list`                       |
  | Compensations              | `compensations_get`, `compensations_list`                           |
  | Employments                | `employments_get`, `employments_list`                               |
  | Events                     | `events_get`, `events_list`                                         |
  | Labor taxes                | `labor_taxes_get`, `labor_taxes_list`                               |
  | Leave balance transactions | `leave_balance_transactions_get`, `leave_balance_transactions_list` |
  | Leave balances             | `leave_balances_get`, `leave_balances_list`                         |
  | Leave entitlements         | `leave_entitlements_get`, `leave_entitlements_list`                 |
  | Leave policies             | `leave_policies_get`, `leave_policies_list`                         |
  | Leave requests             | `leave_requests_get`, `leave_requests_list`                         |
  | Leaves                     | `leaves_get`, `leaves_list`                                         |
  | Locations                  | `locations_get`, `locations_list`                                   |
  | Offers                     | `offers_get`, `offers_list`                                         |
  | Payment requests           | `payment_requests_get`, `payment_requests_list`                     |
  | Payments                   | `payments_get`, `payments_list`                                     |
  | Payroll                    | `payrolls_get`, `payrolls_list`                                     |
  | Positions                  | `positions_get`, `positions_list`                                   |
  | Refunds                    | `refunds_get`, `refunds_list`                                       |
  | Reportings                 | `reportings_get`, `reportings_list`                                 |
  | Roles                      | `roles_get`, `roles_list`                                           |
  | Sandboxes                  | `sandboxes_get`, `sandboxes_list`                                   |
  | Time entries               | `time_entries_get`, `time_entries_list`                             |
  | Worker addresses           | `worker_addresses_get`, `worker_addresses_list`                     |
  | Worker beneficiaries       | `worker_beneficiaries_get`, `worker_beneficiaries_list`             |
  | Worker dependents          | `worker_dependents_get`, `worker_dependents_list`                   |
  | Workers                    | `workers_get`, `workers_list`                                       |
  | Workforce calculations     | `workforce_calculations_get`                                        |
  | Workforce plans            | `workforce_plans_get`, `workforce_plans_list`                       |
</Accordion>

## Manual API key fallback

Use an API key only when your client cannot complete OAuth, only supports static
headers, or you are testing the endpoint directly.

Create live API keys from **Developers > API keys** in Plane; see
[API access](/product/workspace#api-access). For test keys, create a sandbox
first and generate a key from inside it; see
[Your first API call](/guides/first-api-call#create-a-sandbox). Send the key as
a bearer token:

```http theme={null}
Authorization: Bearer YOUR_API_KEY
```

### Claude Desktop config

On macOS, Claude Desktop stores local MCP configuration at
`~/Library/Application Support/Claude/claude_desktop_config.json`. Open Claude
Desktop, go to **Settings > Developer**, and click **Edit Config**. Add Plane as
an HTTP MCP server:

```json theme={null}
{
  "mcpServers": {
    "plane": {
      "type": "http",
      "url": "https://api.plane.com/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_API_KEY"
      }
    }
  }
}
```

If the file already contains other servers, add the `plane` entry inside the
existing `mcpServers` object rather than replacing the file. Fully quit and
restart Claude Desktop to load the change.

## Advanced: test the endpoint with curl

You can verify the endpoint without a full MCP client by sending a JSON-RPC
request with an API key. List the available tools:

<RequestExample>
  ```bash List tools theme={null}
  curl https://api.plane.com/mcp \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "jsonrpc": "2.0",
      "id": 1,
      "method": "tools/list",
      "params": {}
    }'
  ```
</RequestExample>

Then call a read-only tool:

<RequestExample>
  ```bash Call workers_list theme={null}
  curl https://api.plane.com/mcp \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "jsonrpc": "2.0",
      "id": 2,
      "method": "tools/call",
      "params": {
        "name": "workers_list",
        "arguments": { "limit": 10 }
      }
    }'
  ```
</RequestExample>

<ResponseExample>
  ```json Success theme={null}
  {
    "jsonrpc": "2.0",
    "id": 2,
    "result": {
      "content": [
        {
          "type": "text",
          "text": "{\n  \"data\": []\n}"
        }
      ]
    }
  }
  ```
</ResponseExample>

MCP wraps the Plane result in a `content` text block, so the `text` field holds
the JSON returned by the underlying operation. Treat cursors as opaque: if the
response includes a `cursor`, pass it back unchanged as the `cursor` argument to
fetch the next page. When `cursor` is absent, you have reached the end of the
list.

## Troubleshooting

<AccordionGroup>
  <Accordion title="The OAuth flow doesn't start">
    Confirm your client supports remote HTTP MCP servers with OAuth. Some clients
    only support local stdio servers or static API-key headers. If yours cannot
    complete OAuth, use the [manual API key fallback](#manual-api-key-fallback).
  </Accordion>

  <Accordion title="Tools don't appear in my client">
    Restart the client after adding the connector. If tools still don't show,
    confirm the OAuth flow completed and that your account has access to the
    workspace.
  </Accordion>

  <Accordion title="Tool calls return empty results">
    Empty `data` arrays are normal in new or empty workspaces. Confirm your
    credential has access to the workspace you expect. If you are using an API
    key, verify it is from the right workspace (sandbox keys start with
    `sk_test_`, live keys with `sk_live_`).
  </Accordion>

  <Accordion title="I get permission errors on some tools">
    MCP tools inherit the permissions of the credential the client sends. If a
    tool fails a permission check, the underlying user or API key does not have
    access to that resource. Review the credential's role in
    [Members and roles](/product/members-and-roles).
  </Accordion>

  <Accordion title="I want to test without touching live data">
    Use a sandbox API key with the manual fallback. Create a sandbox from
    **Developers > Sandboxes**, generate a key inside it (prefix `sk_test_`),
    and configure your client with that key. See
    [Your first API call](/guides/first-api-call#create-a-sandbox).
  </Accordion>
</AccordionGroup>

## Next steps

<CardGroup cols={2}>
  <Card title="Using Plane Agent" icon="robot" href="/product/agent">
    Ask Plane Agent questions about your workspace directly inside Plane.
  </Card>

  <Card title="Your first API call" icon="rocket" href="/guides/first-api-call">
    Make a direct API call without MCP, using cURL, Node.js, or Python.
  </Card>

  <Card title="Authentication" icon="key" href="/reference/authentication">
    Review API-key authentication for the manual fallback.
  </Card>

  <Card title="API reference" icon="book" href="/reference/introduction">
    Browse every endpoint and object the API exposes.
  </Card>
</CardGroup>
