# Token clients

Setup for apps that connect with a personal API token. Create the token first: see
[Connect with an API token](https://franchisesee.com/docs/ai/api-tokens.md#create-a-token) for permissions, lifetimes and keeping
it safe.

In every example below, replace `YOUR_API_TOKEN` with your token and connect whichever servers you
need: `https://app.franchisesee.com/mcp/reporting` (read-only reporting) and
`https://app.franchisesee.com/mcp/admin` (managing locations and users, HQ only).

## GitHub Copilot

Copilot connects to FranchiseSEE directly over HTTP, with no bridge to install. This works in VS
Code, Visual Studio, JetBrains IDEs, Xcode, the Copilot CLI and the Copilot coding agent.

> [!NOTE]
> On Copilot Business or Enterprise, your organization's Copilot administrator must first turn on
> the **MCP servers in Copilot** policy. If FranchiseSEE doesn't appear, that policy is the most
> likely reason.

### VS Code (Copilot agent mode)

Add the servers to `.vscode/mcp.json` in your workspace, or to your user MCP configuration. The
`inputs` entry makes VS Code ask for your token once and store it securely, so the token never
appears in the file:

```json
{
  "servers": {
    "franchisesee-reporting": {
      "type": "http",
      "url": "https://app.franchisesee.com/mcp/reporting",
      "headers": {
        "Authorization": "Bearer ${input:franchisesee-token}"
      }
    },
    "franchisesee-admin": {
      "type": "http",
      "url": "https://app.franchisesee.com/mcp/admin",
      "headers": {
        "Authorization": "Bearer ${input:franchisesee-token}"
      }
    }
  },
  "inputs": [
    {
      "id": "franchisesee-token",
      "type": "promptString",
      "description": "FranchiseSEE API token",
      "password": true
    }
  ]
}
```

Start the servers from the MCP view, and the FranchiseSEE tools appear in Copilot's agent mode. The
reporting server's [guided prompts](https://franchisesee.com/docs/ai/example-prompts.md#guided-prompts) appear as slash commands,
such as `/mcp.franchisesee-reporting.analyze-performance`.

Visual Studio, JetBrains IDEs, Xcode and the Copilot CLI take the same entries (`type: "http"`, the
URL and the `Authorization` header) in their own MCP configuration files.

### Copilot coding agent (github.com)

A repository administrator adds the server under the repository's **Settings**, in
**Code, planning, and automation**, then **Copilot**, then **MCP servers**:

```json
{
  "mcpServers": {
    "franchisesee-reporting": {
      "type": "http",
      "url": "https://app.franchisesee.com/mcp/reporting",
      "headers": {
        "Authorization": "Bearer $COPILOT_MCP_FRANCHISESEE_TOKEN"
      },
      "tools": ["*"]
    }
  }
}
```

Store the token as an environment secret named `COPILOT_MCP_FRANCHISESEE_TOKEN` in the repository's
`copilot` environment. Secrets that start with `COPILOT_MCP_` reach only MCP servers. The `tools`
list is required: `["*"]` allows every tool, or list tool names to allow fewer.

- **Use a read-only token, and only the reporting server.** Anyone who can assign work to the
  coding agent acts with that token. Don't give the coding agent the admin server.
- **Firewall.** The coding agent runs behind an outbound firewall. If it can't connect, add
  `app.franchisesee.com` to the agent's allowlist in the repository's Copilot settings.

The coding agent uses tools only; the guided prompts aren't available there.

## Claude Code with a token

Sign-in is simpler for the reporting server (see [Developer tools](https://franchisesee.com/docs/ai/developer-tools.md#claude-code)).
For the admin server, pass the token as a header:

```bash
claude mcp add --transport http franchisesee-admin https://app.franchisesee.com/mcp/admin \
  --header "Authorization: Bearer YOUR_API_TOKEN"
```

## Claude Desktop with mcp-remote

Claude Desktop connects by signing in (see [Claude](https://franchisesee.com/docs/ai/claude.md)). To use a token instead, for
example to reach the admin server, bridge the server with
[`mcp-remote`](https://www.npmjs.com/package/mcp-remote). This needs Node.js; `npx` downloads the
bridge on first use.

Edit Claude Desktop's configuration file:

- **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`

```json
{
  "mcpServers": {
    "franchisesee-admin": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "https://app.franchisesee.com/mcp/admin",
        "--header",
        "Authorization: Bearer YOUR_API_TOKEN"
      ],
      "env": {
        "PATH": "PASTE_YOUR_FULL_PATH_HERE"
      }
    }
  }
}
```

### Setting `env.PATH`

This is the step that trips people up. Claude Desktop doesn't start from your terminal, so it
doesn't inherit your shell's `PATH`. The bridge needs `PATH` to find two things, and both must be
there:

1. **`npx` and `node`**: the folder Node.js was installed into.
2. **System tools**: `sh` on macOS and Linux, the system folders on Windows. `npx` runs them, and
   without them the server disconnects at once. On macOS and Linux the error is
   `npm error spawn sh ENOENT`. A `PATH` holding only the Node folder is the usual cause.

The simplest value that has both is your terminal's own `PATH`. Leave `command` as plain `"npx"`;
Claude Desktop finds it through the `PATH` you give it.

**macOS and Linux.** Run this in Terminal, copy the whole line it prints, and paste it as the
`env.PATH` value:

```sh
echo "$(dirname "$(command -v npx)"):$PATH"
```

The value is a list separated by colons. Folders with spaces in them, such as
`Application Support`, need no quoting.

**Windows.** Run this in Command Prompt (`cmd.exe`), not PowerShell, and paste the result:

```bat
echo %PATH%
```

The value is a list separated by semicolons. In the JSON file, backslashes must be doubled
(`C:\\Program Files\\nodejs`); if Claude Desktop reports a JSON error, that's the likely cause.

Save the file and restart Claude Desktop. FranchiseSEE appears among its connected servers.

## Other MCP clients

Any client that supports the **Streamable HTTP** transport can connect directly by sending the
token with each request:

```text
POST https://app.franchisesee.com/mcp/reporting
Authorization: Bearer YOUR_API_TOKEN
```

## Something wrong?

See [Troubleshooting: API tokens](https://franchisesee.com/docs/ai/troubleshooting.md#api-tokens).
