# Connect a client

Every client needs the server's URL:

```text
https://tryjustdocs.com/mcp
```

Give it exactly like that: no trailing slash, and not `www.`. The server's [resource metadata](https://tryjustdocs.com/docs/mcp/oauth) names this URL, and clients refuse to sign in when the URL you gave differs from it.

Then the client authenticates in one of two ways:

- **Sign in with OAuth.** The client opens a JustDocs page, where you choose a workspace (your personal one, or a team you own or administer) and what the app may do. No key is copied anywhere. Claude, ChatGPT, Muse and Claude Code work this way. See [Sign in with OAuth](https://tryjustdocs.com/docs/mcp/oauth).
- **An agent key**, sent as `Authorization: Bearer <agent key>`. Make it on the workspace's **API & agents** page; on Teams & Platform, choose **For: An AI agent**. The server refuses other keys with `403`. Every client can use one.

Either way the client acts as an agent key: everything it asks to send waits for an owner or admin to approve. Below, a key is in an environment variable named `JUSTDOCS_AGENT_KEY`. Keep it out of files you commit.

## Claude (claude.ai and Claude Desktop)

1. Open **Settings → Connectors** and choose **Add custom connector**.
2. Name it _JustDocs_ and give the URL `https://tryjustdocs.com/mcp`. Leave the OAuth client ID and secret under **Advanced settings** empty: Claude identifies itself.
3. Choose **Connect**. A JustDocs page opens. Sign in, choose the workspace and limits, and connect.

The page shows Claude as verified on `claude.ai`, returning you to `claude.ai`. Connectors you add on claude.ai also appear in Claude Desktop.

### With an agent key instead

If you'd rather use a key, choose the option without sign-in when you add the connector. Under **Request headers**, add `Authorization` with the value `Bearer jd_live_…`. Type the word `Bearer`, then a space, then the key.

If the dialog only offers a URL and OAuth, run the server through [`mcp-remote`](https://www.npmjs.com/package/mcp-remote) in Claude Desktop's configuration file instead (**Settings → Developer → Edit Config**):

```json
{
  "mcpServers": {
    "justdocs": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://tryjustdocs.com/mcp", "--header", "Authorization:${JUSTDOCS_AUTH}"],
      "env": { "JUSTDOCS_AUTH": "Bearer jd_live_…" }
    }
  }
}
```

There is no space after `Authorization:` in `args`, on purpose. Some systems split arguments at spaces, so the space goes in the environment value instead. Restart Claude Desktop afterwards.

## ChatGPT

ChatGPT connects to MCP servers in **developer mode**. Its menus change from time to time, so the names below may differ slightly.

1. In ChatGPT's settings, open **Apps**, then **Advanced settings**, and turn on **Developer mode**.
2. Create an app (a connector). Name it _JustDocs_, give the URL `https://tryjustdocs.com/mcp`, and choose **OAuth** for authentication. Leave any client ID and secret empty: ChatGPT identifies itself.
3. Connect. A JustDocs page opens. Sign in, choose the workspace and limits, and connect.

The page shows ChatGPT as verified on `chatgpt.com`, returning you to `chatgpt.com`.

## Muse

Add a custom MCP server in Muse with the URL `https://tryjustdocs.com/mcp`, and choose OAuth for authentication. Muse registers itself with JustDocs and opens the JustDocs page, where you sign in and approve it.

An app that registers itself can claim any name, so the page shows Muse as an **unverified app**. Check that **Sends you back to** names Muse's own address before you connect.

## Claude Code

Add the server, then sign in from inside Claude Code:

```bash
claude mcp add --transport http justdocs https://tryjustdocs.com/mcp
```

Run `/mcp`, choose `justdocs`, and choose **Authenticate**. Your browser opens the JustDocs page. The page warns that the sign-in returns to a program on your computer. That program is Claude Code, where you started the sign-in, so you can continue. Once you connect, `/mcp` shows `justdocs` as connected with its tools.

### With an agent key instead

```bash
claude mcp add --transport http justdocs https://tryjustdocs.com/mcp \
  --header "Authorization: Bearer $JUSTDOCS_AGENT_KEY"
```

To share the setup with a project without sharing the key, commit a `.mcp.json` that reads the key from each person's environment:

```json
{
  "mcpServers": {
    "justdocs": {
      "type": "http",
      "url": "https://tryjustdocs.com/mcp",
      "headers": { "Authorization": "Bearer ${JUSTDOCS_AGENT_KEY}" }
    }
  }
}
```

Leave out `headers` to have each person sign in with OAuth instead.

## Cursor

Add the server to `~/.cursor/mcp.json` for every project, or to `.cursor/mcp.json` for one:

```json
{
  "mcpServers": {
    "justdocs": {
      "url": "https://tryjustdocs.com/mcp",
      "headers": { "Authorization": "Bearer ${env:JUSTDOCS_AGENT_KEY}" }
    }
  }
}
```

Cursor reads `${env:…}` from the environment it was started in. Restart it after you change the file.

## VS Code

Add `.vscode/mcp.json`. VS Code asks for the key the first time and stores it securely:

```json
{
  "inputs": [
    { "type": "promptString", "id": "justdocs-key", "description": "JustDocs agent key", "password": true }
  ],
  "servers": {
    "justdocs": {
      "type": "http",
      "url": "https://tryjustdocs.com/mcp",
      "headers": { "Authorization": "Bearer ${input:justdocs-key}" }
    }
  }
}
```

The top-level key is `servers`, not `mcpServers`.

A client that can sign in to MCP servers with OAuth can leave out the header and sign in instead. JustDocs returns sign-ins only to an `https` address or to a program on your own computer, never to a custom app scheme such as `myapp://`. A client that needs one of those has to use a key.

## Connector platforms

Some platforms let you register a remote MCP server for their users. If the platform supports OAuth for MCP servers, choose it and give the URL `https://tryjustdocs.com/mcp`. The platform identifies or registers itself, and each of its users signs in and approves it on the JustDocs page. Each person's connection is their own agent key.

Otherwise, choose authentication with an API key, and have the platform send the agent key as `Authorization: Bearer <key>`. If the platform asks for a header name and a value separately, the name is `Authorization` and the value is `Bearer ` followed by the key. Each workspace makes its own agent key, so the platform must keep each user's key separate.

## Any other client

The server speaks [Streamable HTTP](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#streamable-http) without sessions. Every JSON-RPC message is a `POST` to `/mcp`, and replies come back as JSON, not as a stream. `GET` and `DELETE` return `405`. Send `Accept: application/json, text/event-stream`, as the transport requires.

Send an agent key, or an access token from [signing in](https://tryjustdocs.com/docs/mcp/oauth), as the bearer token:

```bash
curl https://tryjustdocs.com/mcp \
  -H "Authorization: Bearer $JUSTDOCS_AGENT_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
```

With the official TypeScript SDK:

```ts
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";

const client = new Client({ name: "my-agent", version: "1.0.0" });
await client.connect(new StreamableHTTPClientTransport(new URL("https://tryjustdocs.com/mcp"), {
  requestInit: { headers: { Authorization: `Bearer ${process.env.JUSTDOCS_AGENT_KEY}` } },
}));
const { tools } = await client.listTools();
```

The SDK can also sign in with OAuth: give the transport an `authProvider` instead of the header, and it follows the server's `401` to sign in. See [Sign in with OAuth](https://tryjustdocs.com/docs/mcp/oauth) for what JustDocs expects.

With the official Python SDK:

```python
import asyncio, os
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client

async def main():
    headers = {"Authorization": f"Bearer {os.environ['JUSTDOCS_AGENT_KEY']}"}
    async with streamablehttp_client("https://tryjustdocs.com/mcp", headers=headers) as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()
            tools = await session.list_tools()
            print([tool.name for tool in tools.tools])

asyncio.run(main())
```

## Check the connection

Ask the agent to _"list our JustDocs templates"_. If it can't, see [Troubleshooting](https://tryjustdocs.com/docs/mcp/troubleshooting). If the list is empty, the key may be in another workspace from the one with your templates: the agent can check with `get_workspace` (see [Workspaces](https://tryjustdocs.com/docs/mcp/troubleshooting#workspaces)). The key's **last used** time on the API & agents page tells you whether the requests are reaching JustDocs. An app that signed in is listed there as a **Connected app**.
