sensorhubDevelopers
Open SensorhubGet an API key
Browse documentation

Connect with MCP

Give an AI assistant read access to Sensorhub through the Model Context Protocol. The assistant sees only what your account can see.

Authentication

There are two ways to authenticate:

  • OAuth (Claude.ai, Claude Desktop, ChatGPT). Add Sensorhub as a connector, sign in, and pick one project or all projects to share. No key is needed.
  • API key (Claude Code, Cursor, scripts). Create a key in the MCP section of a project, or an all-projects key on the workspace MCP page in Sensorhub, and send Authorization: Bearer sk_sh_....

A project key or single-project connection covers one project. An all-projects key or connection is workspace-wide: it reaches every project in the workspace, including new ones, and only members with access to every project can create one. API access is not available on Trial or Basic plans. A key follows the current access of the person who created it: if their access to a project is removed, so is the key's.

Some collections and reports need Perception enabled on the project. They are marked Requires Perception in this reference.

The older /api/v1/products/... endpoints are deprecated and stop working on 10 April 2027. Use /api/v1/query and the named reads instead.

Set up your client

Claude Code

Create an API key in the MCP section of a project (or an all-projects key in Workspace → MCP), then run:

bash
claude mcp add --transport http sensorhub https://app.sensorhub.ai/mcp \
  --header "Authorization: Bearer sk_sh_YOUR_KEY"

Claude Desktop

  1. Go to Settings > Connectors
  2. Click "Add custom connector"
  3. Name: Sensorhub
  4. URL: https://app.sensorhub.ai/mcp
  5. Click "Add"

You'll be prompted to sign in, choose the project to connect, and authorize access. The connection uses OAuth, so no API key is needed. If we update the tools later, refresh the list (your permissions are kept): Customize > Connectors > Sensorhub > three-dot menu > Refresh tools list.

Claude.ai

  1. Open Settings > Connectors
  2. Click "Add custom connector"
  3. Name: Sensorhub
  4. URL: https://app.sensorhub.ai/mcp
  5. Sign in, choose the project and authorize access

The connection uses OAuth, so no API key is needed.

ChatGPT

  1. Turn on Developer mode in ChatGPT settings. It is usually under Apps & Connectors > Advanced settings; OpenAI moves this toggle between releases. On Business, Enterprise and Edu plans a workspace admin has to allow it.
  2. Create a new connector (shown as Create or Create MCP App once Developer mode is on)
  3. Name: Sensorhub
  4. MCP server URL: https://app.sensorhub.ai/mcp
  5. Authentication: OAuth
  6. Sign in with Sensorhub when prompted and choose the project

Developer mode is required because Sensorhub offers its own read tools (discover, describe, query, read) rather than ChatGPT's search and fetch pair. The connection uses OAuth, so no API key is needed.

Cursor

  1. Create an API key in the MCP section of a project (or an all-projects key in Workspace → MCP)
  2. Add this server to your Cursor MCP configuration (mcp.json):
json
{
  "mcpServers": {
    "sensorhub": {
      "url": "https://app.sensorhub.ai/mcp",
      "headers": {
        "Authorization": "Bearer sk_sh_YOUR_KEY"
      }
    }
  }
}

Other clients that support remote MCP servers use the same URL and Authorization header.

cURL

Check that a key works by sending an MCP initialize request:

bash
curl -X POST https://app.sensorhub.ai/mcp \
  -H "Authorization: Bearer sk_sh_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"test","version":"1.0.0"}},"id":1}'

Tools

The server exposes a small, fixed set of tools. Assistants find what they need with discover and describe instead of loading every schema up front.

Typical tool sequence
discover({ "search": "workspaces" })
describe({ "name": "workspaces" })
query({"sql":"SELECT id, name, plan FROM workspaces ORDER BY id ASC LIMIT 25"})

discover

Search authorized capabilities by words in names, descriptions and readable field names. Any matching word qualifies; more word matches rank first. No match returns the authorized catalog with a note. Returns compact summaries in pages; limit is clamped to 50. Describe a name to load its schema.

ParameterTypeDescription
searchstring
max length 200
offsetinteger
min 0 · max 100000 · default 0
skillOffsetinteger
min 0 · max 100000 · default 0
limitinteger
min 1 · max 9007199254740991 · default 20

describe

Get a capability schema/examples, skill, errors, or the SQL dialect. Supply name, or up to 10 names to get {results:[...]} in request order where each unavailable name has its own {name, error}; kind=dialect needs no name. Hidden definitions remain unavailable.

ParameterTypeDescription
namestring
max length 100
namesstring[]
max 10 items
kind"capability" | "skill" | "errors" | "dialect"
default "capability"

query

Run a bounded SELECT against one collection. Bind values as $1, $2, etc., for example {"sql":"SELECT id FROM records WHERE id = $1 LIMIT 10","params":["value"]}. Describe it for supported filters, ranked search, aggregates and GIS operations. Use cursor=null to begin supported keyset pagination and pass meta.nextCursor to continue. Set preflight=true to validate access and adapter support without reading rows; estimate=false skips the optional app estimate. format=columns (default) returns {columns, rows: value[][], meta}; rows returns row objects; toon returns TOON text. queries runs up to 5 entries in order and returns {results:[...]} with a per-entry {error} on failure. No writes, joins or arbitrary functions.

ParameterTypeDescription
sqlstringOne SELECT. Bind values with $1, $2, etc.; for example WHERE id = $1 with params=["value"].
max length 4096
preflightboolean
estimateboolean
cursorstring | null
paramsstring | number | boolean | null[]Values for $1, $2, etc. in SQL order; for example ["value"]. Question-mark and named placeholders are unsupported.
max 100 items
queriesobject[]
max 5 items
format"columns" | "rows" | "toon"
default "columns"

read

Execute an authorized named computed read. Call describe for its input schema; collection filters belong in query.

ParameterTypeDescription
name requiredstring
max length 100
inputobject
default {}

Writing good queries

  • Ask for only the fields you need and add a LIMIT.
  • Filter on indexed fields for large collections; the field reference marks them.
  • Use a report from Reports and reads when you need the exact numbers shown in the app.
  • Errors explain how to fix the query, including suggested field names.