# MCP (/docs/api/mcp)

Signal serves a [Model Context Protocol](https://modelcontextprotocol.io) endpoint at
`https://app.signal.metricshive.com/api/mcp`, so an AI client can read your visibility data and manage
prompts without you copying numbers between windows. MCP access is included on every plan.

The app documents the same connection at **Organization Settings → MCP**: the endpoint, snippets for the
common clients, and the tools it offers.

There are two ways to connect. Signing in from the client is the quickest, and the connection then
acts as you, in the workspaces you belong to. An API key is for a client that can't open a browser —
a container, a scheduled job — and is also how you grant a client *less* than your own access.

## Quick Setup [#quick-setup]

[`add-mcp`](https://github.com/neon-solutions/add-mcp) finds the AI clients installed on your machine and
adds Signal to each of them:

```bash
npx add-mcp https://app.signal.metricshive.com/api/mcp --name signal
```

Add `-g` to install it for every project rather than just the current one, and `-y` to skip the
prompt. Each client then asks you to sign in the first time it uses Signal. To set up a single client
by hand, or one `add-mcp` doesn't cover, follow its section below.

## Sign In from the Client [#sign-in-from-the-client]

Give the client the URL and it opens a browser for you to sign in. There is no application to
register first.

### Claude Code [#claude-code]

```bash
claude mcp add --transport http signal https://app.signal.metricshive.com/api/mcp
```

Then run `/mcp` and choose **Authenticate**.

### Claude.ai and Claude Desktop [#claudeai-and-claude-desktop]

Custom connectors are available on every Claude plan; the Free plan is limited to one.

1. Open **Customize → Connectors**, choose **+ Add**, then **Add custom connector**.
2. Name it `Signal`, set the URL to `https://app.signal.metricshive.com/api/mcp`, and choose **Continue**.
3. Review the detected authentication settings, choose **Continue**, and choose **Add**.
4. Sign in to Signal when Claude asks.

On Team and Enterprise plans, an owner adds the connector first under **Organization settings →
Connectors**, choosing **Add**, then **Custom → Web**. Members then find it under **Customize →
Connectors** and choose **Connect**.

### ChatGPT [#chatgpt]

Custom MCP servers are added from ChatGPT on the web, and workspace admins can restrict them.

1. Open [Plugins](https://chatgpt.com/plugins), choose **+**, then **Add custom MCP server**.
2. Name it `Signal`, set the server URL to `https://app.signal.metricshive.com/api/mcp`, and choose **OAuth** for
   authentication.
3. Confirm the warning with **I understand and want to continue**, then choose **Create as a plugin**.
4. Install the plugin and sign in to Signal.

### Codex [#codex]

```bash
codex mcp add signal --url https://app.signal.metricshive.com/api/mcp
codex mcp login signal
```

### Cursor [#cursor]

[Add to Cursor](cursor://anysphere.cursor-deeplink/mcp/install?name=signal&config=eyJ1cmwiOiJodHRwczovL2FwcC5zaWduYWwubWV0cmljc2hpdmUuY29tL2FwaS9tY3AifQ%3D%3D)

Or put it in `~/.cursor/mcp.json`, or `.cursor/mcp.json` for a single project:

```json
{
  "mcpServers": {
    "signal": { "url": "https://app.signal.metricshive.com/api/mcp" }
  }
}
```

Cursor shows the server as needing login; sign in from there. Older Cursor releases send a callback
Signal can't accept, so if signing in fails, use an API key instead.

### VS Code [#vs-code]

[Add to VS Code](vscode:mcp/install?%7B%22name%22%3A%22signal%22%2C%22type%22%3A%22http%22%2C%22url%22%3A%22https%3A%2F%2Fapp.signal.metricshive.com%2Fapi%2Fmcp%22%7D)

Or from a terminal:

```bash
code --add-mcp '{"name":"signal","type":"http","url":"https://app.signal.metricshive.com/api/mcp"}'
```

Or run **MCP: Add Server** from the Command Palette, choose **HTTP**, and enter the URL. Or put it
under `servers` in `mcp.json`:

```json
{
  "servers": {
    "signal": { "type": "http", "url": "https://app.signal.metricshive.com/api/mcp" }
  }
}
```

VS Code asks you to sign in the first time it starts the server.

### Devin Desktop [#devin-desktop]

Devin Desktop, formerly Windsurf, shares its MCP servers with Devin CLI:

```bash
devin mcp add -s user signal https://app.signal.metricshive.com/api/mcp
devin mcp login signal
```

Or put it in `~/.config/devin/mcp_config.json`:

```json
{
  "mcpServers": {
    "signal": { "url": "https://app.signal.metricshive.com/api/mcp" }
  }
}
```

### Antigravity [#antigravity]

Antigravity's IDE and CLI, which replaced Gemini CLI, read `~/.gemini/config/mcp_config.json`:

```json
{
  "mcpServers": {
    "signal": { "serverUrl": "https://app.signal.metricshive.com/api/mcp" }
  }
}
```

To sign in, open **Agent settings → Customizations** and choose **Authenticate** next to Signal. After
signing in, Antigravity shows a code in the browser; paste it back into the settings panel and choose
**Submit**.

### OpenCode [#opencode]

In `opencode.json`, or `~/.config/opencode/opencode.json` for every project:

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "signal": {
      "type": "remote",
      "url": "https://app.signal.metricshive.com/api/mcp",
      "enabled": true
    }
  }
}
```

Then `opencode mcp auth signal`.

### Goose [#goose]

[Add to Goose](goose://extension?url=https%3A%2F%2Fapp.signal.metricshive.com%2Fapi%2Fmcp&type=streamable_http&id=signal&name=Signal&description=Read%20your%20AI%20visibility%20data%20and%20manage%20prompts%20in%20Signal)

Or run `goose configure`, choose **Add Extension → Remote Extension (Streamable HTTP)**, and enter the
URL.

### Other Clients [#other-clients]

Any client that supports remote MCP servers over Streamable HTTP with OAuth can connect: give it
`https://app.signal.metricshive.com/api/mcp` and sign in when it asks. A client that only runs local servers can
reach Signal through [`mcp-remote`](https://www.npmjs.com/package/mcp-remote):

```json
{
  "mcpServers": {
    "signal": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://app.signal.metricshive.com/api/mcp"]
    }
  }
}
```

## Or Use an API Key [#or-use-an-api-key]

Issue one from **Organization Settings → API Keys** — keys belong to the organization, so they are not
found under a brand. Issue it read-only and optionally narrow it to
selected brands.

Send it as a bearer token. ChatGPT only connects by signing in; Claude.ai and Claude Desktop take the
key when you add the connector: choose **No sign in** under **Authentication** and add an
`Authorization: Bearer signal_...` request header. `add-mcp` takes it as a header for every client it configures:

```bash
npx add-mcp https://app.signal.metricshive.com/api/mcp --name signal \
  --header "Authorization: Bearer signal_..."
```

Claude Code:

```bash
claude mcp add --transport http signal https://app.signal.metricshive.com/api/mcp \
  --header "Authorization: Bearer signal_..."
```

Codex, which reads the key from the environment rather than the config file:

```bash
codex mcp add signal --url https://app.signal.metricshive.com/api/mcp \
  --bearer-token-env-var SIGNAL_API_KEY
```

Cursor, in `~/.cursor/mcp.json`:

```json
{
  "mcpServers": {
    "signal": {
      "url": "https://app.signal.metricshive.com/api/mcp",
      "headers": { "Authorization": "Bearer signal_..." }
    }
  }
}
```

VS Code, in `mcp.json`:

```json
{
  "servers": {
    "signal": {
      "type": "http",
      "url": "https://app.signal.metricshive.com/api/mcp",
      "headers": { "Authorization": "Bearer signal_..." }
    }
  }
}
```

Devin Desktop and Devin CLI, in `~/.config/devin/mcp_config.json`:

```json
{
  "mcpServers": {
    "signal": {
      "url": "https://app.signal.metricshive.com/api/mcp",
      "headers": { "Authorization": "Bearer signal_..." }
    }
  }
}
```

Antigravity, in `~/.gemini/config/mcp_config.json`:

```json
{
  "mcpServers": {
    "signal": {
      "serverUrl": "https://app.signal.metricshive.com/api/mcp",
      "headers": { "Authorization": "Bearer signal_..." }
    }
  }
}
```

OpenCode, in `opencode.json`:

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "signal": {
      "type": "remote",
      "url": "https://app.signal.metricshive.com/api/mcp",
      "enabled": true,
      "headers": { "Authorization": "Bearer signal_..." }
    }
  }
}
```

## Try [#try]

> What is the visibility and share of voice for each tagged prompt in Signal for `<brand>`?

> What are some AEO opportunities for my `<brand>`?

> Give me an example run for my `<description>` prompt.

## Scopes [#scopes]

A connection is only offered the tools its scopes allow, so a client is never shown something it
would then be refused:

| Scope | MCP tool |
| --- | --- |
| *(none)* | `whoami`, `list_models` |
| `read` | `list_brands`, `get_brand`, `list_competitors`, `list_prompts`, `list_prompt_tags`, `get_analytics`, `get_prompt_performance`, `get_citations`, `get_query_fanout`, `get_opportunities`, `list_runs`, `get_run`, `get_billing` |
| `write` | `create_prompts`, `update_prompt` |

A read-write key can create and edit prompts over MCP, but no tool deletes data and no tool changes
billing — deleting a prompt isn't available to API keys at all, and billing can only be changed in the app.

A connection you signed in from acts as you and reaches everything you can, so scopes are a property
of a key rather than of the sign-in.
