Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.emergence.ai/llms.txt

Use this file to discover all available pages before exploring further.

MCP Server

CRAFT handles the “what” — governed, accurate data retrieval from your enterprise systems — so your AI tools and agents can focus on the “why”: validating hypotheses, identifying root causes, running what-if scenarios, and surfacing anomalies. Use resolve_term so your agent knows what “active customer” means in your warehouse before generating SQL; use execute_query to validate results; use generate_plotly_chart to surface patterns instantly. Connect Claude Code, Cursor, Goose, or a purpose-built agent to https://craft.emergence.ai/mcp and CRAFT becomes a governed data layer for any reasoning workflow. Two connection patterns: (a) interactive — IDE clients query CRAFT while you code; (b) programmatic — embed CRAFT as a tool server in an agent pipeline for hypothesis testing, root cause analysis, anomaly detection, or what-if modeling.

Server details

PropertyValue
Endpointhttps://craft.emergence.ai/mcp
TransportStreamable HTTP (MCP 2025-11-25 spec; SSE-compat path available)
AuthOAuth 2.0 PKCE (authorization code + S256, via Keycloak)
HealthGET https://craft.emergence.ai/health{"status": "ok"}

Verify the endpoint (no auth needed)

Before setting up OAuth, confirm the server is reachable with the no-auth hello_world tool:
curl -s -X POST https://craft.emergence.ai/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"hello_world","arguments":{}}}' \
| jq .
Expected response:
{"jsonrpc": "2.0", "id": 1, "result": {"content": [{"type": "text", "text": "Hello from CRAFT MCP server"}]}}
If this succeeds, network connectivity and DNS are confirmed. If you prefer a CLI tool:
npx @mcpjam/cli server doctor --url https://craft.emergence.ai/mcp

Authentication

Interactive clients (OAuth)

Supported IDE clients use the MCP OAuth 2.0 PKCE authorization flow. On first connection, the client opens a browser window to craft.emergence.ai, where you sign in with your Google or Microsoft account. The access token is stored and refreshed by the client automatically — no manual token handling required.

X-Project-ID header

All tools except hello_world require an X-Project-ID header scoping the request to your CRAFT project. Find your project ID in the CRAFT console under Settings → Project → ID. X-Project-ID selects a project scope but does not grant access — project membership is enforced server-side against your JWT’s claims. Passing an arbitrary project ID returns an authorization error if you are not a member.

Token requirements for headless callers

Programmatic callers (agents, pipelines) must obtain an access token before calling tools:
RequirementValue
Issuer (iss)https://craft.emergence.ai/keycloak/realms/emergence
Required scopesopenid profile email
Grant typeAuthorization code (interactive) or Client credentials (service account)
Token TTL~5 minutes; refresh token manages rotation for interactive clients
For service accounts and CI pipelines, see Service Accounts and Authentication.

Connect your AI client

Add the CRAFT MCP server from the CLI:
claude mcp add --transport http craft https://craft.emergence.ai/mcp \
  --header "X-Project-ID: <your-project-id>"
Or add it to .mcp.json in your project root (or ~/.claude.json for user-scope):
{
  "mcpServers": {
    "craft": {
      "type": "http",
      "url": "https://craft.emergence.ai/mcp",
      "headers": {
        "X-Project-ID": "<your-project-id>"
      }
    }
  }
}
The OAuth browser flow triggers automatically on first tool call. Token refresh is handled by Claude Code.
Find your project ID in the CRAFT console under Settings → Project → ID.
Add to .cursor/mcp.json in your project (or ~/.cursor/mcp.json globally):
{
  "mcpServers": {
    "craft": {
      "type": "http",
      "url": "https://craft.emergence.ai/mcp",
      "headers": {
        "X-Project-ID": "${env:CRAFT_PROJECT_ID}"
      }
    }
  }
}
Set CRAFT_PROJECT_ID as a shell environment variable — Cursor expands ${env:VAR} at runtime. The OAuth browser window opens on first use.
Create .vscode/mcp.json in your project:
{
  "inputs": [
    {
      "type": "promptString",
      "id": "craft-project-id",
      "description": "Your CRAFT project ID"
    }
  ],
  "servers": {
    "craft": {
      "type": "http",
      "url": "https://craft.emergence.ai/mcp",
      "headers": {
        "X-Project-ID": "${input:craft-project-id}"
      }
    }
  }
}
VS Code prompts for the project ID once and stores it securely. OAuth handles the access token automatically.
If tool calls fail silently, headers may not be forwarded — a known issue in some VS Code versions (#264095). Workaround: replace the type/url block with mcp-remote:
{
  "servers": {
    "craft": {
      "command": "npx",
      "args": [
        "mcp-remote@latest",
        "https://craft.emergence.ai/mcp",
        "--header",
        "X-Project-ID: <your-project-id>"
      ]
    }
  }
}
Note: mcp-remote handles the OAuth flow locally rather than delegating it to the server.
Add to ~/.config/goose/config.yaml:
extensions:
  craft:
    name: craft
    type: http
    url: https://craft.emergence.ai/mcp
    enabled: true
    headers:
      X-Project-ID: "${CRAFT_PROJECT_ID}"
Set CRAFT_PROJECT_ID in your environment. Alternatively, run goose configure, select Remote Extension (Streamable HTTP), and the interactive wizard will prompt you for the URL and any custom headers. OAuth triggers on first connection.

Interactive charts — MCP Apps extension

generate_plotly_chart currently returns raw Plotly JSON (plotly_json). Inline interactive chart rendering via the io.modelcontextprotocol/ui MCP Apps extension is in development — no additional configuration is needed when it ships; supported clients will render charts inline automatically.
The MCP Apps extension (io.modelcontextprotocol/ui) lets a tool return a ui:// resource containing HTML/JS. The host fetches it and renders it in a sandboxed iframe alongside the chat — users interact with the chart without switching tabs, with bidirectional data flow back to the server. Clients recommended for interactive Plotly charts, sourced from the official client matrix (verified 2026-05-19):
ClientMCP AppsNotes
GooseDesktop app; renders iframes inline
VS Code CopilotBrowser-rendered panel
CursorDesktop IDE; renders iframes inline
PostmanRenders in Postman canvas; good for dev/testing
MCPJamInspector UI; best for debugging chart output
Claude Code (CLI)Terminal — no browser context; receives raw plotly_json
Claude Code users receive the raw plotly_json response. Render it locally with plotly.io.show(fig) in Python or Plotly.newPlot(...) in JavaScript.

Developer tools

Use these tools to test and debug CRAFT’s MCP server during development, especially the MCP Apps / Plotly rendering path.
MCPJam is a dedicated MCP inspector — web app (no install), desktop app, or CLI. It supports the MCP Apps extension and will render Plotly charts inline as they ship.Web app or desktop: Add a server with URL https://craft.emergence.ai/mcp, enable OAuth, and set X-Project-ID in the headers field:
{
  "name": "craft",
  "type": "http",
  "url": "https://craft.emergence.ai/mcp",
  "headers": { "X-Project-ID": "<your-project-id>" },
  "useOAuth": true
}
CLI: Run a health check and OAuth flow validation:
npx @mcpjam/cli server doctor \
  --url https://craft.emergence.ai/mcp \
  --header "X-Project-ID: <your-project-id>"
MCPJam provides full JSON-RPC trace visibility and guided OAuth conformance checks (DCR, PKCE, CIMD) — useful for validating the MCP server before shipping tool changes.
Postman can act as an MCP host (client), connecting to external MCP servers — distinct from Postman’s own MCP server for managing Postman resources.Go to Settings → MCP Hosts → Add and configure:
  • URL: https://craft.emergence.ai/mcp
  • Auth: OAuth (recommended) or access token
  • Headers: X-Project-ID: <your-project-id>
Postman supports the MCP Apps extension — Plotly charts appear inline in the Postman canvas. Once you have a working configuration, use Postman’s Export MCP config button to generate a ready-to-paste config for Claude Code, Cursor, or VS Code.

Calling CRAFT from an external agent

Any MCP-compatible agent framework can use CRAFT as a tool server, bringing governed data access to any reasoning pipeline.
Requires pydantic-ai-slim[fastmcp] and fastmcp:
from fastmcp import Client
from fastmcp.client.transports import StreamableHttpTransport
from pydantic_ai import Agent
from pydantic_ai.toolsets.fastmcp import FastMCPToolset

transport = StreamableHttpTransport(
    url="https://craft.emergence.ai/mcp",
    headers={
        "Authorization": "Bearer <token>",
        "X-Project-ID": "<your-project-id>",
    },
)
toolset = FastMCPToolset(Client(transport))
agent = Agent("anthropic:claude-sonnet-4-6", toolsets=[toolset])

async def main():
    result = await agent.run(
        "What databases are available? Generate SQL to count active customers."
    )
    print(result.output)
MCPServerHTTP is deprecated — use FastMCPToolset with StreamableHttpTransport.
Headless callers need a programmatic access token. Obtain one via a Keycloak service account (client credentials grant). See Service Accounts for setup.

Available tools

Catalog tools

Always available — provide governed access to your project’s data catalog.
ToolRequired parametersReturns
hello_worldServer greeting; confirms connectivity (no auth required)
list_databasesresource_uri — data connection UUIDDatabase metadata list
get_schemaresource_uri, fqn — 2 segments = database, 3 = schema, 4 = tableFull entity schema including columns and types
search_schemaquery — Elasticsearch-style text queryMatching metadata entries across the project

Talk2Data tools

Available when the deployment includes the Data Insights solution. See Data Connections to connect your data sources.
ToolRequired parametersReturns
generate_sqlquestion (natural language), database (connection UUID), schema (object with schema_name)sql, explanation, assumptions
execute_querysql (SELECT statements only), databasecolumns, rows, row_count, truncated
resolve_termterm — business term (e.g., “ARR”, “churn rate”)definition, related_columns, sql_pattern
generate_plotly_chartdata (tabular), chart_type (bar, line, scatter, pie, …)Plotly JSON figure spec (plotly_json)
sample_dataresource_uri, table_fqndatabase.schema.tablecolumns, rows (up to 100 rows preview)
execute_query only accepts SELECT statements — DDL, DML, and admin functions are rejected. generate_sql delegates to the Text2SQL A2A agent; the first call in a session may take 3–8 s (cold start), subsequent calls ~1–2 s.

Per-project allowlist and governance

CRAFT enforces a per-project tool allowlist — each project defines which tools each agent identity may call. This is the key difference between the CRAFT MCP gateway and a raw FastMCP server. Configure allowlists in Platform → Authorization (RBAC model) and Platform → Agents (agent identity → allowlist mapping). Denied calls return a structured error:
{
  "ok": false,
  "error": {
    "code": "tool_not_allowed",
    "message": "Tool 'generate_sql' is not in the allowlist for this agent identity"
  }
}
Every tool call — allowed or denied — writes an audit event to the governance event log. Each event records:
  • Timestamp, agent identity, tool name, project ID
  • Input parameters (PII-scrubbed per governance policy)
  • Result status (allowed / denied / error)
Query audit events via Audit Log. Tool calls are tracked separately from LLM completions and do not flow through the LiteLLM gateway. See LLM Gateway for the complementary table.

Errors and limits

ConditionHTTPMCP error codeRemediation
Missing Authorization header401missing_authorizationComplete the OAuth flow; verify token is fresh
Missing X-Project-ID header400missing_projectAdd X-Project-ID header with your project UUID
Tool not in allowlist403tool_not_allowedAsk project admin to add tool to allowlist
Non-SELECT SQL in execute_query422validation_errorOnly SELECT statements are permitted
Text2SQL agent unavailable503upstream_unavailableRetry; generate_sql depends on the Talk2Data A2A agent
Query row limit hit200Response includes "truncated": true; reduce max_rows
Limits:
  • execute_query: up to 5,000 rows (max_rows parameter; default 500); truncated: true when capped
  • sample_data: up to 100 rows (limit parameter; default 10)
  • generate_sql: first call may take 3–8 s (Text2SQL agent cold-start); subsequent calls ~1–2 s

Next steps

LLM Gateway

The complementary gateway for LLM completions — model allowlist, rate limits, and cost attribution.

Data Connections

Connect your data sources to enable Talk2Data tools.

Release Notes

Track new tools, breaking changes, and platform updates.