Skip to content

AI assistants (MCP setup)

DataQ ships a built-in MCP server so AI assistants — Claude Desktop, Claude.ai, VS Code / GitHub Copilot, Cursor — can answer questions like "what failed today?" or "run the orders suite" against your live DataQ instance, with the same per-suite permissions as the signed-in user.

Endpoint & authentication

The server is mounted on the deployed app at:

https://<your-dataq-host>/mcp/

Keep the trailing slash

/mcp answers with a 307 redirect to /mcp/, and some HTTP clients drop the Authorization header when following redirects — which then surfaces as a confusing 401. Always configure clients with the /mcp/ form.

The endpoint accepts the same credentials as the REST API (ADR 0008 / 0026): an OIDC bearer token (Azure AD or Cognito), or a DataQ API key (dq_live_…). Without a working sign-in configuration the endpoint is not mounted at all — it is never unauthenticated.

Email-OTP deployments: MCP works, with an API key

A deployment running email one-time codes instead of SSO (ADR 0032) has no identity provider to issue bearer tokens, so an API key is the only /mcp credential there — mint one as below and use it exactly the same way. Everything else is identical, including all 50 tools and per-suite permissions. Two rejections are deliberate in that mode: a raw JWT is refused (there is nothing to validate it against), and your sign-in session is never accepted — it is a browser credential and does not authenticate /mcp, whether presented as a bearer or carried as a cookie.

Getting a token

Recommended — a DataQ API key (PAT): mint one via POST /api/v1/me/api-keys (see API keys) and use it as the bearer. It lives up to a year, is revocable per-integration, and runs with exactly your per-suite access — built for always-on MCP configs.

Quick one-off — your web session's OIDC token: sign in to the DataQ web app, open your browser's developer tools → Application → Session Storage → the oidc.user:… entry → copy the access_token value.

OIDC tokens expire after ~1 hour

The pasted browser token is short-lived; when the client starts getting 401s, paste a fresh one and restart the MCP server/connection — or switch to an API key and stop re-pasting.

Never commit a config that carries a token

Keep token-bearing MCP config files out of version control (in the DataQ repo itself, .gitignore already covers .vscode/*).

Client configuration

Claude Desktop / Claude.ai (claude_desktop_config.json) — and GitHub Copilot (mcp.json):

{
  "mcpServers": {
    "dataq": {
      "url": "https://<your-dataq-host>/mcp/",
      "headers": { "Authorization": "Bearer <AZURE_AD_ACCESS_TOKEN>" }
    }
  }
}

VS Code (workspace .vscode/mcp.json, used by Copilot agent mode) uses a servers key — not mcpServers — plus an explicit type:

{
  "servers": {
    "dataq": {
      "type": "http",
      "url": "https://<your-dataq-host>/mcp/",
      "headers": { "Authorization": "Bearer <AZURE_AD_ACCESS_TOKEN>" }
    }
  }
}

Start it via the command palette (Cmd/Ctrl+Shift+P) → MCP: List Serversdataq → Start (or open Copilot Chat in agent mode — configured servers start on demand).

Cursor (~/.cursor/mcp.json) uses the same mcpServers shape as Claude Desktop.

The 50 tools

Each tool is a thin wrapper over the same service layer as the REST API — per-suite authorization (view for a read, edit for a mutation) and failing-sample redaction apply identically. The complete list — every tool, who can call it, and what it does — is the MCP tools reference, generated from the server itself and drift-checked in CI, so it cannot go stale the way an earlier hand-typed pass of this page did.

The tools split three ways, not two:

  • Read-only (27) — reads gated on view where a suite is named; workspace-wide reads such as list_suites and get_health_score need only a signed-in user.
  • Changes state (18) — every one gates on edit access to the affected suite (schedule, binding and incident tools via the suite they target); import_suite additionally requires the member workspace role, since it has no existing suite to gate on.
  • Live probes (5) — profile_column, list_columns, dryrun_check, suggest_column_policy, test_connection persist nothing but open a live datasource connection with stored credentials. They are gated like writes, not reads, because they spend a real credential against a remote system: the first four require edit on the suite whose connection they probe, and test_connection (which has no suite) requires the member workspace role.

Troubleshooting

Symptom Cause / fix
401 on every request Token expired (~1 h) → paste a fresh one. Or the client followed the /mcp/mcp/ redirect and dropped the header → use /mcp/ directly.
307 responses Missing trailing slash — configure /mcp/.
Server absent / connection refused locally The MCP server is unmounted unless the deployment has a working sign-in configuration — SSO (AZURE_*) or email OTP (AUTH_EMAIL_* + an allowlist); fail-closed by design.
401 with an API key on an email-OTP deployment Check you sent the API key, not your session cookie/token: in OTP mode a dq_live_… key is the only credential /mcp accepts.
Tool call returns "not found" for a suite you can see in the UI as someone else MCP calls run as the token's user — suite access is per-user, same as the web app.