Semaphor
MCP

MCP Overview

Connect Claude, Codex, Cursor and your own agents to Semaphor analytics using the Model Context Protocol.

Semaphor runs a Model Context Protocol server that lets agents discover and query your analytics. Agents ground answers in your semantic model, run governed queries under the caller's permissions, read your dashboards, and, with write access, make changes you preview first.

Connect

Add Semaphor to your AI client

Most clients need only the server URL. Add it, log in with your Semaphor account, and ask a question. The agent works across every project you belong to, with your role and permissions.

MCP server URL
https://semaphor.cloud/api/mcp

On a self-hosted install, use your Semaphor URL followed by /api/mcp.

Install the Semaphor plugin, which adds the server and an analytics skill:

claude plugin marketplace add semaphor-analytics/agent-plugin
claude plugin install semaphor@semaphor-analytics

Then run /mcp in a session, choose semaphor, and log in in your browser. Full steps

Install the Semaphor plugin and log in:

codex plugin marketplace add semaphor-analytics/agent-plugin
codex plugin add semaphor@semaphor-analytics
codex mcp login semaphor

Full steps

Open Semaphor in the Claude directory, connect it, and sign in with your Semaphor account.

Or add it yourself: open Settings, then Connectors, click Add custom connector, name it Semaphor, paste the server URL, and sign in. Full steps

Open Settings, then Apps, then Advanced, and turn on Developer mode. Click Create app, paste the server URL, and sign in with your Semaphor account. Full steps

Add the server to Cursor, then complete the Semaphor login in your browser when it connects:

~/.cursor/mcp.json
{
  "mcpServers": {
    "semaphor": {
      "url": "https://semaphor.cloud/api/mcp"
    }
  }
}

Full steps

For automation or an agent inside your own product, mint an MCP project token on your server and send it as a header instead of logging in:

.mcp.json
{
  "mcpServers": {
    "semaphor": {
      "type": "http",
      "url": "https://semaphor.cloud/api/mcp",
      "headers": { "Authorization": "Bearer ${SEMAPHOR_MCP_TOKEN}" }
    }
  }
}

Connect with a Token shows how to mint one.

Then ask: What data can I analyze in Semaphor?

Building an agent? Build an Agent is one page with everything it needs, and /llms-full.txt holds all of these pages as one Markdown document to hand to Claude or any other agent. Every page also has Copy Markdown.

How it works

One endpoint, one caller profile, one analytics spine

Every request to https://semaphor.cloud/api/mcp carries a credential. The server verifies it, builds a caller profile (who you are, which projects you can reach, your scopes, and whether you get SQL), and registers only the tools that profile may use. Tool calls then run through the same governed path as your dashboards. On a self-hosted install, use your Semaphor URL followed by /api/mcp.

MCP clientClaude, ChatGPT, Codex,Cursor, your backendVerify credentialOAuth login orMCP project tokenCaller profilemodeinteractive · headless · embeddedreachyour projects · one projectscopesmcp:read · mcp:writesqlon · offTool list for this callertool families filtered by role,scopes and SQL accessStrict argumentsan unknown name failsand says which oneGroundingdomains, datasets,fields, relationshipsGoverned querycompiled with yoursecurity policiesStructured resultJSON, or an errorwith a stable codebearertools/callpins the project, gates SQL arguments and changes
The caller profile is built once per request from the verified credential. The tool list, the project a session is pinned to, and whether SQL and changes are allowed all come from the profile, never from how the caller logged in.

From the caller's side

Who's calling decides what they see

There are three ways in. Pick one to see how it logs in, what it can do, and what a failure looks like.

Interactive

You connect your AI client and log in with your Semaphor account.

  1. Add https://semaphor.cloud/api/mcp to Claude, ChatGPT, Codex or Cursor, or install the Semaphor plugin.
  2. Your client opens the Semaphor login.
  3. Approve read access, and write access if the agent should make changes.
  4. Ask a question. With one project, the agent doesn’t need to ask which.
Reach
Every project you belong to
Tools
20 with write · 19 read only · 13 as a viewer
SQL
Author role or higher
Changes
Dashboards, generated dashboards and relationships; applying needs write

Tool families

Discovery (available)Analyze (available)Matrix (available)Dashboards (available)SQL (available)Changes (available)Project list (available)

Several agents can share one login. When it expires, your client asks you to log in again.

CallerCredentialToolsWhat's different
Org admin in an AI client, writeOAuth login20Everything, including the change tools
Org admin in an AI client, read onlyOAuth login19Can propose changes, not apply them
Org viewer in an AI clientOAuth login13No SQL, physical tables or change tools
Org admin automation, writeMCP project token19No project list; pinned to one project
Org admin automation, read onlyMCP project token18No project list; can propose, not apply
End user, SQL onMCP project token17Read, analyze, SQL and physical discovery under their policies
End user, SQL offMCP project token12Semantic model only
End user with the Power User role, writeMCP project token19Also changes the dashboards they can edit

Hiding a tool is for clarity, not the security control: the server still authorizes every call. SQL-shaped arguments inside shared tools (a physical source in semaphor_matrix, for example) return capability_required for callers without SQL. See Tools Reference.

Tools

What agents can do

Discover the datasemaphor_get_analysis_context

List projects, semantic domains, datasets, fields and relationships. Callers with SQL access can also browse connections, schemas and tables.

Ask governed questionssemaphor_analyze · semaphor_matrix

Run analytics over the semantic model, or SQL with semaphor_query_sql_advanced when a question needs it. Two people can get different numbers for the same question.

Work from your dashboardssemaphor_list_dashboards

List dashboards, see who can actually open them, and read a dashboard's cards, filters and saved queries.

Make changes, with a previewsemaphor_propose_change

Add, change and remove dashboard cards and filters, add sheets, show cards as tabs, write text cards, build a new dashboard, or improve a semantic model: synonyms, descriptions, calculations and relationships. Every change is previewed first; saving it needs write access.

Reads

Every answer is grounded, then governed

An agent answering a question starts with semaphor_get_analysis_context, finds the exact domain, dataset and fields, and runs semaphor_analyze. Nothing is guessed, and every query runs under the caller's security policies. See Discover and Query.

A questionin plain wordsanalysis_contextrecommends the pathGround the fieldsdomains, datasets, schemasemaphor_analyzegoverned by your policiesThe answerrows and what appliedabout a dashboard card: fromCard runs the card as your users see itno semantic model, and SQL access:tables, then semaphor_query_sql_advanceda wrong field fails andnames the valid onesanswered, partial or failed;filters applied and skipped
The agent never guesses a name: every domain, dataset and field comes from discovery, and a wrong one fails with the valid choices. Each answer says whether it was answered in full, and which filters and date windows it applied or skipped. Two people can get different numbers for the same question, because each sees only their own data.

Writes

Every change is a preview, then an apply

semaphor_propose_change saves nothing and returns one sentence per change, with the new numbers. semaphor_apply_change applies exactly that preview by its proposalId. New capabilities arrive as new changes, never new tools.

Read the outlinesheets, cards, filterspropose_changesentences, preview, riskThe user confirmsreads the sentencesapply_changeexactly as previewedAppliednew IDs in createdFailednothing writtenretry: same resultsaves nothing; expires in 30 mincan view, not edit: saveAs: "copy"needs mcp:writesomeone saved the dashboard first: proposal_stale, read the outline again
Proposing saves nothing and needs no write access; applying needs mcp:write and the user's yes. A proposal expires after 30 minutes. If the person can view the dashboard but not edit it, the agent proposes with saveAs: "copy" and the change is saved as their private copy.

Change kinds

  • Dashboard changes: card.add, card.update, card.remove, the filter.* changes, sheet.add, sheet.update, layout.tabs, layout.untab and layout.arrange, on a dashboard you can edit, or as your own private copy. Organization authors and end users with the Power User role.
  • A new dashboard: create in place of dashboardId, with the changes that fill it, saved private to you. Anyone who can create dashboards in the project.
  • A semantic model's own changes: domain.update, dataset.update, field.update, metric.update, calculation.add and relationship.update add synonyms, example questions and instructions, change descriptions, labels and formats, add calculations and change definitions. See Improve a Semantic Model.
  • relationship.add: adds a relationship between two datasets. Every query on the domain can use it, so it needs the Author role or higher in the project's organization, logged in or with a token, as every semantic model change does.

Permission is not approval

The server enforces permission: write scope, an Author role, the credential rule for each kind, and project access. Approval is the client's job: the apply tool is marked destructive, so clients that honor annotations ask you before running it. For automation tokens, minting write scope is the approval.

Developer experience

What building against it looks like

Connect an agent with a token

Mint a token on your server:

POST /api/v1/token
{
  "projectId": "p_...",
  "projectSecret": "...",
  "orgUserId": "...",
  "mcp": { "scopes": ["mcp:read"], "sql": true },
  "tokenExpiry": 3600
}

Connect any client that takes a header:

.mcp.json
{
  "mcpServers": {
    "semaphor": {
      "type": "http",
      "url": "https://semaphor.cloud/api/mcp",
      "headers": { "Authorization": "Bearer ${SEMAPHOR_MCP_TOKEN}" }
    }
  }
}

What to expect

  • semaphor_get_access_context answers "why is this tool missing": mode, credential, scopes and whether SQL is on.
  • Results are JSON by default and arrive as structured content, checked against each tool's output schema.
  • Errors carry a stable code your code can branch on.
  • A misspelled argument fails with its name instead of being silently dropped.

Error codes worth knowing

write_scope_requiredLog in with write, or mint with mcp:write
capability_requiredThe argument needs SQL; use the semantic form
missing_measureAnalyze needs a measure; __count counts rows
tool_timeoutThe call ran too long; ask a narrower question
proposal_staleThe target changed; propose again
apply_outcome_unknownCheck the target before proposing again

Next

Get started