# Connect an MCP client

Trov is a remote MCP server at https://trov.dev/mcp. Setup to copy for Claude Code, Claude Desktop, Cursor, VS Code, Codex, Windsurf and any other client.

## How connecting works

- **One address:** `https://trov.dev/mcp`, a remote MCP server over Streamable HTTP. Nothing runs on your machine.
- **Browser sign-in (OAuth).** A request with no token is answered `401` with a `WWW-Authenticate` header pointing at Trov's OAuth metadata (`/.well-known/oauth-protected-resource`, RFC 9728). A client that supports MCP's OAuth registers itself (RFC 7591), opens Trov in your browser, and gets a token after you click **Allow**. OAuth 2.1 with PKCE; access tokens last an hour and refresh on their own. Trov accepts `https` redirect addresses and `http` on a loopback host (`localhost`, `127.0.0.1`), which is what native clients use.
- **Which organization.** One connection covers all your organizations. On the Allow page you choose how it picks one: **follow the repository** you are working in (every call passes `repo`, and acts in the organization that has that repository connected), or **manual** (it acts in the organization you choose, among the ones you tick; `switch_org` changes it). Change it later in Settings › MCP access.
- **It acts as you.** It sees what you see and writes as you, within what an agent may do ([Concepts](https://trov.dev/docs/concepts)). Revoke it any time in Settings › MCP access › Connected apps.
- **A pasted token** (`trov_mcp_…`, or an older `canopy_mcp_…`) also works, sent as `Authorization: Bearer <token>`; it acts in the one organization it was made for. Settings no longer creates tokens, and a token you already have keeps working. For a client that cannot sign in through a browser (CI, a headless agent), a signed-in person can still mint one with `POST /api/o/<your-org>/mcp-tokens`; the token is shown once. The examples below read it from `$TROV_MCP_TOKEN`.

## Claude Code

**With the plugin (recommended).** It adds the MCP server and the skills (`trov`, `load-context`, `record-session`, `my-work`, `tickets`, `handoff`, `prompts`, `artifacts`, `read-plan`, `update-plan`). In Claude Code:

```text
/plugin marketplace add AndresL230/trov
/plugin install trov@trov
```

Then run `/mcp`, choose **trov**, then **Authenticate**, and click **Allow** in the browser. Update it later with `/plugin marketplace update trov`.

**Without the plugin.** Add the server for every project (`--scope user`), then `/mcp` › trov › Authenticate as above:

```bash
claude mcp add --transport http --scope user trov https://trov.dev/mcp
```

With a token instead of the browser sign-in:

```bash
claude mcp add --transport http --scope user trov https://trov.dev/mcp --header "Authorization: Bearer $TROV_MCP_TOKEN"
```

Use one or the other, not both, or your agent sees every tool twice (`claude mcp remove trov` drops the manual one).

## Claude Desktop and claude.ai

Trov is a **custom connector** there. There is no plugin, and no field for a token: custom connectors sign in through the browser only.

1. Open Settings › Connectors, choose **Add custom connector**, name it Trov and enter `https://trov.dev/mcp`.
2. Choose **Connect**. Trov's sign-in opens in the browser.
3. On the Allow page, **manual** is already chosen, because a chat is in no repository to follow. Tick the organizations the connection may use, pick the one it starts in, and click **Allow**.
4. In a chat, ask “call `get_connection`”. It answers who you are and which organization you are in.

On a Team or Enterprise plan, an owner adds the connector for the organization and each member connects it. The connection shows up in Trov under Settings › MCP access › Connected apps, like any other.

## In a chat, with no repository

A chat (claude.ai on the web, Claude Desktop, or any client outside a code checkout) gets all of Trov's tools, but it has no repository, no shell and none of the Claude Code plugin's skills. Nothing orients or records by itself: you ask.

**Things to ask in a first chat:**

- “What’s on my plate in Trov?” Your open tickets and assigned issues, and your recent pull requests (`get_my_work`).
- “What does Trov say about the billing flow?” A search of the docs, decisions and feed (`query`), then the doc itself (`get_doc`).
- “File a ticket for this and assign it to me.” Tickets are written at once; after that the agent can change only the tickets assigned to you.
- “Propose this as a change to the onboarding doc.” It is staged, and waits in **Triage › Review** until a person promotes it.
- “Save this as a prompt”, or “make this an artifact”. A prompt is staged until a person publishes it.
- “Leave a handoff for my next coding session.” It says where the task stands; your agent in the repository lists it when it starts.

**What is different with no repository:**

- **Which organization.** A manual connection acts in its current organization. Say “switch to <organization>” (`switch_org`, which changes it for every chat on that connection), or change it in Settings › MCP access. A connection set to follow the repository reads and writes nothing in a chat unless a call names the repository: switch it to manual in Settings › MCP access.
- **Nothing reads `git`.** A handoff written in a chat carries no repository, branch or files. An agent that claims a handoff asking for code changes cannot make them: it tells you what is asked and does the parts that need no repository.
- **Recording.** “Record this chat” stages the decisions and doc changes made in it. The agent cannot see what shipped, so give it the pull request or commit to record shipped work.
- **Files.** With no shell there is nothing to upload or download with, so an image, PDF or file artifact travels inside the call, up to 1 MB. A larger one can be linked, but not opened or uploaded. A picture you attach to the chat usually cannot be passed on to Trov. Text artifacts (HTML, Markdown, SVG, Mermaid) are sent as text.

**Tell the agent once.** In a claude.ai Project, put this in the project's instructions, so every chat in it follows the same rules:

```markdown
## Trov: the team's memory

This team keeps its docs, decisions, roadmap, tickets and a feed of what shipped in Trov, through the Trov connector (https://trov.dev/mcp). This chat is in no code repository.

- **Say where you are.** At the start of a chat, call `get_connection` and tell the person which organization you are in. When they name another one, pass `org` on that call, or use `switch_org` and say that it changes the organization for every chat on this connection.
- **Orient before you answer.** Before changing an area the team already knows, search Trov with `query` (a short, specific `q`; narrow with `types` and `section`) and read the top results; open a doc with `get_doc`. Always do this before proposing a doc change, and pass the doc's `current_version` as `base_version`.
- **Trust only `live`.** Every result is flagged `live`, `staged_pending`, `unpromoted` or `draft`. Only `live` is settled; never present the others as fact.
- **Never invent a repository.** Leave `repo`, branch and files out unless the person names them; when a call needs a repository, ask which one they mean.
- **At the start of a chat,** also call `list_handoffs` and `get_my_work`, and tell the person what is waiting. Claim a handoff only after they pick it. You cannot change code here: say what the handoff asks, and do the parts that need no repository.
- **Stage, never confirm.** Doc changes, decisions and feed entries you write are proposals that a person promotes in the Trov web app; you cannot promote, ratify, reject or publish. Do not resolve a ticket or complete a sprint unless the person asks.
- **Tickets: your lane only.** You may file tickets (`create_ticket`, after `list_people` to pick assignees). Every other ticket write needs the ticket to be assigned to the person you work for.
- **Record only when asked.** Send ONE `record_session` batch with what was decided or written in this chat, and doc changes written against the version you read. You cannot read `git` here: record shipped work only from a pull request or commit the person gives you, never from memory.
- **Files travel inside the call.** An image, PDF or file artifact of up to 1 MB goes as `content_base64` (`upload_asset`, `artifact_update`) and comes back with `include_file` (`artifact_get`). For a larger one, give the person its link.
```

## Cursor

In `.cursor/mcp.json` (this project) or `~/.cursor/mcp.json` (every project):

```json
{
  "mcpServers": {
    "trov": {
      "url": "https://trov.dev/mcp"
    }
  }
}
```

Cursor opens the browser sign-in when the server needs it. Its recent versions sign in through a loopback address, which Trov accepts; an older build that registers a `cursor://` address is refused at sign-in (Trov takes only https and loopback redirects), so update Cursor, or use a token:

```json
{
  "mcpServers": {
    "trov": {
      "url": "https://trov.dev/mcp",
      "headers": {
        "Authorization": "Bearer ${env:TROV_MCP_TOKEN}"
      }
    }
  }
}
```

## VS Code

In `.vscode/mcp.json` (this workspace), or with **MCP: Open User Configuration** (every workspace):

```json
{
  "servers": {
    "trov": {
      "type": "http",
      "url": "https://trov.dev/mcp"
    }
  }
}
```

VS Code registers itself with Trov and opens the browser sign-in on first use. With a token, VS Code asks for it once and keeps it in its secret storage:

```json
{
  "inputs": [
    {
      "type": "promptString",
      "id": "trov-token",
      "description": "Trov MCP token",
      "password": true
    }
  ],
  "servers": {
    "trov": {
      "type": "http",
      "url": "https://trov.dev/mcp",
      "headers": {
        "Authorization": "Bearer ${input:trov-token}"
      }
    }
  }
}
```

## OpenAI Codex CLI

Add the server; Codex sees that Trov signs in with OAuth and opens the browser:

```bash
codex mcp add trov --url https://trov.dev/mcp
codex mcp login trov   # sign in again later, if needed
```

Or in `~/.codex/config.toml`:

```toml
[mcp_servers.trov]
url = "https://trov.dev/mcp"
```

With a token, read from the environment (Codex does not take the token itself in the file):

```toml
[mcp_servers.trov]
url = "https://trov.dev/mcp"
bearer_token_env_var = "TROV_MCP_TOKEN"
```

## Windsurf

In `~/.codeium/windsurf/mcp_config.json`, a remote server is `serverUrl`:

```json
{
  "mcpServers": {
    "trov": {
      "serverUrl": "https://trov.dev/mcp"
    }
  }
}
```

If your Windsurf version does not open a browser sign-in for remote servers, send a token:

```json
{
  "mcpServers": {
    "trov": {
      "serverUrl": "https://trov.dev/mcp",
      "headers": {
        "Authorization": "Bearer ${env:TROV_MCP_TOKEN}"
      }
    }
  }
}
```

## Any other MCP client

Trov works with any client that speaks MCP over Streamable HTTP and either follows MCP's OAuth flow (it discovers everything from the `401`) or can send a header. Most clients read this shape; it is the Claude Code plugin's own `.mcp.json`:

```json
{
  "mcpServers": {
    "trov": {
      "type": "http",
      "url": "https://trov.dev/mcp"
    }
  }
}
```

and, with a token, add the header:

```json
{
  "mcpServers": {
    "trov": {
      "type": "http",
      "url": "https://trov.dev/mcp",
      "headers": {
        "Authorization": "Bearer <your trov_mcp_ token>"
      }
    }
  }
}
```

A client that only runs local (stdio) servers can reach a remote one through a bridge such as `mcp-remote` (`npx mcp-remote https://trov.dev/mcp`).

## Check the connection

Ask your agent to call `get_connection`. It answers who you are, the connection's mode, and which organization a call would act in; `organization: null` means a call would read and write nothing, and `unresolved` says why. Every failed call carries a `hint` saying what to do next ([MCP tools](https://trov.dev/docs/mcp-tools) › Errors).

## Tell your agent how to use Trov

The Claude Code plugin's skills already follow this loop. For any other agent that works in a repository, or to make it explicit, add this to your project's `AGENTS.md` or `CLAUDE.md` (for a chat, use the one under In a chat, with no repository):

```markdown
## Trov: the team's memory

This team keeps its docs, decisions, roadmap, tickets and a feed of what shipped in Trov, through the `trov` MCP server (https://trov.dev/mcp).

- **Orient before you work.** Before changing an area the team already knows, search Trov with `query` (a short, specific `q`; narrow with `types` and `section`) and read the top results; open a doc with `get_doc`. Always do this before proposing a doc change, and pass the doc's `current_version` as `base_version`.
- **Trust only `live`.** Every result is flagged `live`, `staged_pending`, `unpromoted` or `draft`. Only `live` is settled; never present the others as fact.
- **Say which repository.** Pass `repo` (owner/name, from `git remote get-url origin`) on every Trov call. Unsure where you are? Call `get_connection` and tell the person which organization you are in.
- **At the start of a session,** call `list_handoffs` and `get_my_work`, and tell the person what is waiting. Claim a handoff only after they pick it.
- **Stage, never confirm.** Doc changes, decisions and feed entries you write are proposals that a person promotes in the Trov web app; you cannot promote, ratify, reject or publish. Do not resolve a ticket or complete a sprint unless the person asks.
- **Tickets: your lane only.** You may file tickets (`create_ticket`, after `list_people` to pick assignees). Every other ticket write needs the ticket to be assigned to the person you work for.
- **Record at the end, only when asked.** When the person says “record this session”, send ONE `record_session` batch: what actually shipped, copied from `git` and `gh` output (never from memory), and doc changes written against the version you read.
```

---

This page: https://trov.dev/docs/connect · All docs for language models: https://trov.dev/llms.txt
