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

# Connecting a client

> One URL, two ways to sign in, and the configuration for each client.

```text theme={null}
https://app.doers.sh/mcp
```

Two ways to authenticate:

* **OAuth.** The client opens your browser, you approve on the Doers consent screen, and the client
  keeps its own access. Nothing to copy, and you can disconnect it from the app. This is the only
  option for web connectors such as claude.ai and ChatGPT.
* **A personal token.** A `pc_…` token from **Settings > API & MCP**, sent in an `Authorization`
  header. For clients without a browser, scripts and CI.

<Note>
  Use this exact address with OAuth. The authorization server issues tokens for
  `https://app.doers.sh/mcp`. A client configured with another address names that address when it
  asks for a token, as the specification requires, and is refused with `invalid_target`. With a
  personal token, `https://api.doers.sh/mcp` works as well.

  The MCP server's address will be aligned with the API host, `api.doers.sh`. Until then, `https://app.doers.sh/mcp` is the address that works for every client.
</Note>

<Tabs>
  <Tab title="Claude Code">
    ```bash theme={null}
    claude mcp add --transport http doers https://app.doers.sh/mcp
    ```

    Then, in Claude Code, run `/mcp`, choose **doers** and let it open your browser. Sign in if needed
    and approve: Claude Code stores its access on its own.

    Add `--scope user` to make it available in every project. Check with `claude mcp list`.

    With a token instead:

    ```bash theme={null}
    claude mcp add --transport http doers https://app.doers.sh/mcp \
      --header "Authorization: Bearer pc_…"
    ```
  </Tab>

  <Tab title="claude.ai and Claude Desktop">
    In **Settings > Connectors**, add a custom connector with the URL:

    ```text theme={null}
    https://app.doers.sh/mcp
    ```

    Claude finds the authorization server, registers itself and sends you to the consent screen. There
    is no token to paste. The connector is then available in Claude Desktop too.
  </Tab>

  <Tab title="ChatGPT">
    Add a custom connector (an app, in ChatGPT's settings) with the same URL and OAuth authentication.
    ChatGPT registers itself and sends you to the consent screen.
  </Tab>

  <Tab title="Cursor">
    In `~/.cursor/mcp.json`:

    ```json theme={null}
    {
      "mcpServers": {
        "doers": { "url": "https://app.doers.sh/mcp" }
      }
    }
    ```

    Cursor starts the OAuth sign-in on first use. To use a token instead, add
    `"headers": { "Authorization": "Bearer pc_…" }` next to `url`.
  </Tab>

  <Tab title="VS Code">
    In `.vscode/mcp.json`:

    ```json theme={null}
    {
      "servers": {
        "doers": { "type": "http", "url": "https://app.doers.sh/mcp" }
      }
    }
    ```

    VS Code starts the OAuth sign-in on first use. To use a token instead, add
    `"headers": { "Authorization": "Bearer pc_…" }`.
  </Tab>

  <Tab title="Any client (JSON)">
    Most clients read a configuration of this shape. The server speaks Streamable HTTP and answers
    with plain JSON, never a stream:

    ```json theme={null}
    {
      "mcpServers": {
        "doers": {
          "type": "http",
          "url": "https://app.doers.sh/mcp",
          "headers": { "Authorization": "Bearer pc_…" }
        }
      }
    }
    ```

    Leave `headers` out if the client supports OAuth. A client that only speaks stdio can go through
    the `mcp-remote` bridge, which handles OAuth too:

    ```json theme={null}
    {
      "mcpServers": {
        "doers": { "command": "npx", "args": ["-y", "mcp-remote", "https://app.doers.sh/mcp"] }
      }
    }
    ```
  </Tab>
</Tabs>

## What the sign-in does

1. The client calls the server without a token and gets a `401` whose `WWW-Authenticate` header
   points at `/.well-known/oauth-protected-resource`.
2. It reads that document, then `/.well-known/oauth-authorization-server`.
3. It registers itself with `POST /oauth/register`. There is nothing to set up beforehand.
4. It opens your browser on the consent screen, with PKCE.
5. You approve. It exchanges the code for an access token (1 hour) and a refresh token (60 days,
   replaced at every use).

The application then appears in **Settings > API & MCP > Connected apps**. Disconnecting it there
cuts its access at once.

## Check by hand

```bash theme={null}
# Discovery, no token needed
curl -s https://app.doers.sh/.well-known/oauth-protected-resource

# The tool list, with a token
curl -X POST https://app.doers.sh/mcp \
  -H "Authorization: Bearer $DOERS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "MCP-Protocol-Version: 2025-11-25" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
```

To explore interactively, run `npx @modelcontextprotocol/inspector`, choose **Streamable HTTP** and
enter the URL: the Inspector handles OAuth.
