> For the complete documentation index, see [llms.txt](https://docs.rockhopper.co/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.rockhopper.co/it-setup/mcp-server.md).

# MCP Server (AI Integration)

**Audit, collaborate, version, and approve your spreadsheet work — directly from Claude.** Trace every cell edit back to its author and run formal approval workflows without opening the file. The Rockhopper MCP server makes Rockhopper a native part of your AI workflow — an AI-native analyst that keeps every edit attributed, every review approved, and every workbook SOC 2-grade trustworthy.

Once connected, your AI tools — Cursor, Claude Desktop, Claude Code, VS Code, Claude.ai on the web, and ChatGPT — can talk to your Rockhopper workspace using the [Model Context Protocol](https://modelcontextprotocol.io). All access is scoped to what your Rockhopper account is allowed to see.

### Example prompts

Once the MCP server is connected, you can ask Claude things like:

* **Audit cell-level history:** *"Who last changed C12 in the P\&L Model, and what was it before?"*
* **Review uncommitted changes:** *"Show me every unattributed change in the Q3 budget this week and who made them."*
* **Comment and collaborate inline:** *"Add a comment on Sheet1!B5 asking the analyst why this assumption shifted 10%."*
* **Run formal approval workflows:** *"Create a review request for the latest version of the Q3 forecast."*
* **Approve, cancel, or chase reviews:** *"List my pending review requests, then approve the one for the budget model."*
* **Version, snapshot, or roll back:** *"Create a new version called 'pre-board-edit', then discard uncommitted changes on the Q3 forecast."*

Rockhopper offers two ways to connect, and you can mix and match:

| Deployment          | Who it's for                                                   | Transport               | Install                               |
| ------------------- | -------------------------------------------------------------- | ----------------------- | ------------------------------------- |
| **Local (npm)**     | IDE-based tools (Cursor, Claude Desktop, Claude Code, VS Code) | stdio                   | `npx @rockhopper-co/mcp-server`       |
| **Remote (hosted)** | Web clients that only support remote MCP (Claude.ai, ChatGPT)  | Streamable HTTP + OAuth | Paste `https://mcp.rockhopper.co/mcp` |

{% hint style="info" %}
The remote gateway is gated by a feature flag during GA rollout. If your workspace doesn't see the remote option yet, use the local install — the tools are identical.
{% endhint %}

{% hint style="success" %}
Prefer to test from a UI before wiring up an AI client? See [MCP — Postman Workspace](/it-setup/mcp-postman-workspace.md) for a click-through guide that exercises every tool, resource, and prompt — or jump straight in:

[![Run In Postman](https://run.pstmn.io/button.png)](https://god.gw.postman.com/run-collection/54299481-0b80e147-9f26-4fe5-8a87-a5dcc4a993bc?action=collection%2Ffork\&source=rip_markdown\&collection-url=entityId%3D54299481-0b80e147-9f26-4fe5-8a87-a5dcc4a993bc%26entityType%3Dcollection%26workspaceId%3Dfd36303d-a194-4e6e-978a-3b159249ec65)
{% endhint %}

## Prerequisites

* An active Rockhopper account with access to at least one workspace.
* Node.js 20+ on the machine running the AI client (only for the local install).
* Permission from your IT admin to install the MCP client you plan to use.

## Step 1 — Create a Personal Access Token (PAT)

A PAT is the credential your AI client uses to authenticate to Rockhopper. PATs are tied to **you**, inherit your workspace permissions, and never grant access beyond what you can already see in the Rockhopper app.

1. Sign in at [app.rockhopper.co](https://app.rockhopper.co).
2. Click your avatar (top right) → **Access Tokens**.
3. Click **Create token**.
4. Fill in:
   * **Name** — something memorable (e.g. `Cursor on MacBook`, `Claude Desktop`).
   * **Scope** — `read-only` lets the AI list files, read changes, and read comments. `read-write` additionally lets it post comments and open review requests. Start with `read-only` unless you have a reason to grant writes.
   * **Expires in** — 30 / 60 / 90 / 180 / 365 days. Shorter is safer.
5. Click **Create**. The full token (`rh_pat_…`) is shown **once**. Copy it immediately — Rockhopper stores only a hash; you can't recover it later.

{% hint style="warning" %}
Treat PATs like passwords. Don't paste them into chat messages, commit them to Git, or share them over email. If a PAT leaks, revoke it from the same page — the effect is instant.
{% endhint %}

## Step 2 (Option A) — Local install with `npx`

This path runs `@rockhopper-co/mcp-server` on your own machine and talks to Rockhopper over stdio. It's the simplest setup and what we recommend for IDE-based tools.

### Cursor

Open **Cursor Settings → MCP → Add new MCP server** and paste:

```json
{
  "mcpServers": {
    "rockhopper": {
      "command": "npx",
      "args": ["-y", "@rockhopper-co/mcp-server"],
      "env": {
        "ROCKHOPPER_TOKEN": "rh_pat_your_token_here"
      }
    }
  }
}
```

Save, then in a new chat confirm the **rockhopper** server appears in the MCP picker.

### Claude Desktop

Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):

```json
{
  "mcpServers": {
    "rockhopper": {
      "command": "npx",
      "args": ["-y", "@rockhopper-co/mcp-server"],
      "env": {
        "ROCKHOPPER_TOKEN": "rh_pat_your_token_here"
      }
    }
  }
}
```

Fully quit and relaunch Claude Desktop. You should see the Rockhopper tools in the tool picker.

### Claude Code

```bash
claude mcp add rockhopper \
  --env ROCKHOPPER_TOKEN=rh_pat_your_token_here \
  -- npx -y @rockhopper-co/mcp-server
```

Claude Code will pick up the server on the next session.

### VS Code (GitHub Copilot Chat / Continue / other MCP-aware extensions)

Create or edit `.vscode/mcp.json` in the workspace:

```json
{
  "servers": {
    "rockhopper": {
      "command": "npx",
      "args": ["-y", "@rockhopper-co/mcp-server"],
      "env": {
        "ROCKHOPPER_TOKEN": "rh_pat_your_token_here"
      }
    }
  }
}
```

### Self-hosted Rockhopper

If your company runs Rockhopper at a custom domain, override the API URL:

```json
{
  "env": {
    "ROCKHOPPER_TOKEN": "rh_pat_your_token_here",
    "ROCKHOPPER_API_URL": "https://rockhopper.your-company.com"
  }
}
```

## Step 2 (Option B) — Remote install (Claude.ai, ChatGPT)

Web-based AI tools can't run `npx`, so they connect to our hosted gateway at `mcp.rockhopper.co` over HTTP with OAuth. You won't paste a PAT — you'll log in through your normal Rockhopper identity provider.

### Claude.ai

1. In Claude.ai click **Settings → Connectors → Add custom connector**.
2. Enter:
   * **Name**: `Rockhopper`
   * **URL**: `https://mcp.rockhopper.co/mcp`
3. Click **Connect**. A Rockhopper sign-in window opens — complete your normal SSO.
4. Approve the `read-only` (or `read-write`) scope. Claude.ai will show Rockhopper tools in the tool picker for every chat.

### ChatGPT

1. In ChatGPT open **Settings → Connectors → Add → Custom MCP**.
2. URL: `https://mcp.rockhopper.co/mcp`.
3. Complete the OAuth sign-in and approve the scope.

{% hint style="info" %}
The gateway mints a **short-lived** PAT (default 30 minutes) for each session and rotates it automatically. You can revoke active sessions at any time from the Access Tokens page — look for entries prefixed `gateway:`.
{% endhint %}

## OAuth 2.0 — building your own MCP client

If you're integrating an MCP client that isn't Claude.ai or ChatGPT, you can speak directly to the gateway's OAuth 2.0 surface. Rockhopper implements the [MCP authorization spec](https://modelcontextprotocol.io/specification/server/authorization/), which combines **Dynamic Client Registration** ([RFC 7591](https://www.rfc-editor.org/rfc/rfc7591)) with **Authorization Code + PKCE** ([RFC 7636](https://www.rfc-editor.org/rfc/rfc7636)).

### Endpoints

Discovery (RFC 8414):

```
GET https://mcp.rockhopper.co/.well-known/oauth-authorization-server
GET https://mcp.rockhopper.co/.well-known/mcp-protected-resource
```

Both unauthenticated; returns the canonical endpoint URLs for the rest of the flow.

### 1. Register a client (DCR)

```bash
curl -X POST https://mcp.rockhopper.co/register \
  -H "Content-Type: application/json" \
  -d '{
    "redirect_uris": ["https://your-app.example.com/oauth/callback"]
  }'
```

Response (HTTP 201):

```json
{
  "client_id": "<opaque>",
  "redirect_uris": ["https://your-app.example.com/oauth/callback"],
  "token_endpoint_auth_method": "none",
  "grant_types": ["authorization_code"],
  "response_types": ["code"]
}
```

The gateway issues **public clients only** (no `client_secret`) — PKCE is the integrity guarantee. Store the `client_id`; you'll need it for every authorize + token call.

### 2. Authorization request

Generate a PKCE `code_verifier` (43-128 chars, unreserved) and its `code_challenge` (`base64url(sha256(code_verifier))`). Direct the user's browser to:

```
GET https://mcp.rockhopper.co/authorize
    ?client_id=<client_id>
    &redirect_uri=https://your-app.example.com/oauth/callback
    &state=<random>
    &code_challenge=<S256-challenge>
    &code_challenge_method=S256
```

The gateway redirects the user to Rockhopper's web login at `app.rockhopper.co/login`. After SSO completes, the gateway redirects back to your `redirect_uri` with `?code=<short-lived>&state=<your-state>`.

### 3. Exchange code for access token

```bash
curl -X POST https://mcp.rockhopper.co/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code" \
  -d "code=<code-from-callback>" \
  -d "client_id=<client_id>" \
  -d "code_verifier=<your-code-verifier>"
```

Response:

```json
{
  "access_token": "<opaque>",
  "token_type": "Bearer",
  "expires_in": 1800
}
```

`expires_in` reflects the underlying short-lived PAT's TTL (default 1800 seconds = 30 minutes).

### 4. Call MCP tools

```
POST https://mcp.rockhopper.co/mcp
Authorization: Bearer <access_token>
Content-Type: application/json
Accept: application/json, text/event-stream

{ "jsonrpc": "2.0", "method": "tools/list", "id": "1" }
```

### Token lifecycle

* **Tokens expire after \~30 minutes** (configurable server-side via `SESSION_PAT_TTL_MINUTES`).
* **No refresh tokens yet** — when a token expires, repeat the authorize → token flow. Refresh-token support is on the roadmap; until then, prompt the user to re-login.
* **No revocation endpoint yet** — the user can revoke active sessions from the Access Tokens page at `app.rockhopper.co` (look for `gateway:` entries) and the corresponding access tokens stop working immediately.

### Debugging the OAuth flow from Postman

The public Rockhopper MCP Postman workspace (see [MCP — Postman Workspace](/it-setup/mcp-postman-workspace.md)) doesn't include an OAuth-grant variant by default — the Bearer/PAT variant is the customer-facing path. For OAuth debugging:

1. Add a new MCP Request to your forked collection with `Authorization: OAuth 2.0` instead of Bearer Token
2. In the OAuth config: Grant Type **Authorization Code (with PKCE)**, Callback URL **Postman's default** (`https://oauth.pstmn.io/v1/callback`), Auth URL `https://mcp.rockhopper.co/authorize`, Token URL `https://mcp.rockhopper.co/token`
3. Get your `client_id` from a one-time `POST /register` (curl above) and paste it. Leave `Client Secret` blank.
4. Click **Get New Access Token** in Postman — opens the auth flow in your default browser.

If you're debugging issues with the OAuth flow itself (not your client), the gateway logs at `/ecs/{env}-mcp-gateway` in CloudWatch carry every `oauth.*` event.

## Step 3 — Verify the connection

Ask your AI assistant:

> "Using Rockhopper, list my enrolled files and tell me which one changed most recently."

If the connection works, you'll see it call `list_files`, then `get_file_versions` or `get_unattributed_changes`, and summarize the result. If it fails, see **Troubleshooting** below.

## What the AI can do

The server exposes three surfaces. Everything respects your existing workspace permissions — the AI cannot see files or workspaces you can't see.

### Tools (actions)

| Tool                       | Scope          | What it does                                                           |
| -------------------------- | -------------- | ---------------------------------------------------------------------- |
| `list_files`               | read-only      | List enrolled files in your workspace (optional search filter)         |
| `search_files`             | read-only      | Search enrolled files by name                                          |
| `get_file_versions`        | read-only      | List committed versions of a file (semver, author, timestamp)          |
| `get_file_comments`        | read-only      | List comment threads on a file (with replies, resolution state)        |
| `get_reviews`              | read-only      | List review requests for a specific version, or for the latest version |
| `get_cell_history`         | read-only      | Get how a single cell changed across versions                          |
| `get_unattributed_changes` | read-only      | List pending live-sheet edits not yet committed                        |
| `add_comment`              | **read-write** | Post a comment scoped to a file version                                |
| `reply_to_comment`         | **read-write** | Reply to an existing comment thread                                    |
| `resolve_comment`          | **read-write** | Mark a comment thread resolved (author-only)                           |
| `create_review_request`    | **read-write** | Open a review request and assign reviewers                             |
| `approve_review`           | **read-write** | Approve a review request (assignee-only)                               |
| `cancel_review`            | **read-write** | Cancel a pending review request (requester-only)                       |
| `create_version`           | **read-write** | Snapshot the live state as a new committed version                     |
| `discard_changes`          | **read-write** | Throw away pending live-sheet edits (return to last committed version) |
| `rename_file`              | **read-write** | Rename an enrolled file's display name                                 |

### Resources (read-only URIs your AI can fetch)

Standard MCP resources include file catalogs, version history, comment threads, and review dashboards. Your client will show them in its resource picker.

### Prompts (pre-authored workflows)

| Prompt                   | What it does                                                                                                     |
| ------------------------ | ---------------------------------------------------------------------------------------------------------------- |
| `file-overview`          | Pulls versions, comments, reviews, and pending changes for one file, then asks the AI to write a status report   |
| `summarize-file-changes` | Surfaces the last five versions and twenty unattributed edits, then summarizes what changed and who made changes |
| `pending-reviews`        | Lists every reviewer status on the latest version and asks the AI to flag what needs attention                   |
| `unresolved-comments`    | Filters to open comment threads only and asks the AI to prioritize follow-ups                                    |

## Data governance

* PATs authenticate as **you** and inherit your permissions exactly. Revoking or downgrading your Rockhopper role propagates instantly.
* Read-only PATs cannot modify any data.
* Remote-gateway sessions use per-session short-lived PATs minted server-side; long-lived tokens never leave Rockhopper's infrastructure.
* All MCP traffic (local and remote) is logged with tool name, user id, and latency. Request/response bodies are **not** persisted.
* Comment contents are passed through unmodified. MCP's "untrusted content" guidance applies — your AI should treat comment text as user input, not instructions.

See [Security → Data Governance](/security-and-compliance/data-governance.md) for the full story.

## Troubleshooting

**"Invalid token" or 401 on every call.** The token may be expired or revoked. Create a new one from the Access Tokens page and update your client config.

**AI says "I don't have access to Rockhopper tools."** Fully quit and relaunch the client (Claude Desktop especially caches MCP state). In Cursor, toggle the server off/on in Settings.

**Rate-limited ("Too many requests").** PATs are throttled to 120 requests / minute by default. Ask the AI to batch queries or wait a minute.

**Self-hosted domain not working.** Confirm `ROCKHOPPER_API_URL` points to the same hostname you use in the browser, **without** a trailing slash.

**Remote gateway sign-in loops.** Clear cookies for `mcp.rockhopper.co` and try again. If your IdP blocks third-party cookies, open the gateway URL in a fresh browser window first to complete SSO, then retry from Claude.ai / ChatGPT.

**Need to revoke everything at once.** On the Access Tokens page click **Revoke** on every row; both long-lived and gateway-issued tokens disappear immediately.

## Getting help

Email <support@rockhopper.co> with:

1. The client you're using (Cursor / Claude Desktop / Claude.ai / etc.).
2. The token name (never the token value) and scope.
3. The AI's error message or transcript of the failing turn.
