Developer Interface
Connect AI agents to your Chalk deployment over the Model Context Protocol.
Chalk hosts a Model Context Protocol (MCP) server so that AI agents (Claude, Cursor, your own LangChain or agent code, or any MCP-compatible client) can interact with your Chalk deployment directly. Through the MCP server an agent can run online queries, execute ChalkSQL, read feature and resolver definitions, search logs and traces, and inspect query errors, all scoped to the permissions of the credentials it presents.
The MCP server is hosted alongside the Chalk API and requires no installation or self-hosting.
The MCP Server is distinct from the MCP Gateway. The MCP Server exposes Chalk itself to agents (run queries, execute ChalkSQL, inspect your deployment). The MCP Gateway sits in front of other MCP servers and governs your agents' access to them.
Most MCP clients accept a remote server URL plus a set of headers. Point your client at
https://api.chalk.ai/v1/mcp/sse using its streamable-HTTP or remote-server configuration. The
snippets below read your credentials from chalk config, so they work as written
once you are logged in. See Authentication for where those credentials come
from, and Endpoint if you are on a dedicated or self-hosted deployment.
The CLI registers the server for you, using the credentials you are already logged in with:
chalk mcp configure-claudeThis adds Chalk in Claude Code’s user scope, so it is available in every project. Pass
--claude-scope local to limit it to the current directory, or --claude-scope project to write
it to .mcp.json for your teammates. Start Claude Code and run /mcp to confirm the connection.
Under the hood this runs claude mcp add,
which you can also call yourself:
claude mcp add --transport http chalk https://api.chalk.ai/v1/mcp/sse \
--header "X-Chalk-Client-Id: $(chalk config --format json | jq -r .clientId.value)" \
--header "X-Chalk-Client-Secret: $(chalk config --format json | jq -r .clientSecret.value)"The CLI writes the Codex configuration for you:
chalk mcp configure-codexThis adds an [mcp_servers.chalk] block to ~/.codex/config.toml, leaving the rest of the file
untouched. Codex has no per-project scope, so the server is available everywhere. Pass
--env-headers to reference environment variables instead of writing your credentials into the
file, and confirm the result with codex mcp list.
Codex’s own codex mcp add command covers stdio servers only, so you can also add Chalk by
editing that file yourself:
[mcp_servers.chalk]
url = "https://api.chalk.ai/v1/mcp/sse"
env_http_headers = { "X-Chalk-Client-Id" = "CHALK_CLIENT_ID", "X-Chalk-Client-Secret" = "CHALK_CLIENT_SECRET" }env_http_headers maps each header to the name of an environment variable Codex reads when it
connects, which keeps the credentials out of the file. Export them first with
eval "$(chalk config --format shell)". To write the values into the file instead, use
http_headers, which takes the header values themselves.
This is the format used by Cursor, Windsurf, and many other clients (mcp.json /
mcpServers):
{
"mcpServers": {
"chalk": {
"url": "https://api.chalk.ai/v1/mcp/sse",
"headers": {
"X-Chalk-Client-Id": "token-392c737aa1e467e42e85ae3e8417a003",
"X-Chalk-Client-Secret": "ts-6307f46a00a68436b0f955b82b7fb30075d"
}
}
}
}For a client that cannot connect to a remote server directly, bridge to it with
mcp-remote:
{
"mcpServers": {
"chalk": {
"command": "npx",
"args": [
"mcp-remote",
"https://api.chalk.ai/v1/mcp/sse",
"--header",
"X-Chalk-Client-Id: ${CHALK_CLIENT_ID}",
"--header",
"X-Chalk-Client-Secret: ${CHALK_CLIENT_SECRET}"
],
"env": {
"CHALK_CLIENT_ID": "token-392c737aa1e467e42e85ae3e8417a003",
"CHALK_CLIENT_SECRET": "ts-6307f46a00a68436b0f955b82b7fb30075d"
}
}
}
}You can confirm your credentials are accepted by issuing an initialize request directly:
curl -sS https://api.chalk.ai/v1/mcp/sse \
-H "X-Chalk-Client-Id: $(chalk config --format json | jq -r .clientId.value)" \
-H "X-Chalk-Client-Secret: $(chalk config --format json | jq -r .clientSecret.value)" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"curl","version":"0"}}}'A 401 with a WWW-Authenticate header means the credentials were missing or rejected.
The server speaks the Streamable HTTP transport (MCP specification 2025-03-26). A single
URL handles both the JSON-RPC POST requests and the Server-Sent Events (SSE) streams that the
transport uses, so most clients only need this one URL.
Configure your client for a streamable-HTTP (or “HTTP”) remote server, not a legacy SSE server. The
/sse suffix in the path is historical: this endpoint speaks the modern Streamable HTTP transport,
not the deprecated HTTP+SSE transport.
If you are on a dedicated or self-hosted Chalk deployment, replace api.chalk.ai with your own
API server host. You can find it in the apiServer field of chalk config --format json.
The MCP server authenticates with the same service credentials used everywhere else in Chalk.
Generate or look up a service token in the Settings → Service Tokens tab of the Chalk
dashboard, then retrieve the values from the CLI with chalk config:
chalk configName Value Description
client_id token-392c737aa1e467e42e85ae3e8417a003 default token
client_secret ts-6307f46a00a68436b0f955b82b7fb30075d default token
environment btfxgaqqxbt7z ...
api_server https://api.chalk.ai ...
To pull the values out programmatically, use a machine-readable format:
# JSON object with clientId / clientSecret / apiServer fields
chalk config --format json
# Shell export statements: CHALK_CLIENT_ID / CHALK_CLIENT_SECRET / ...
chalk config --format shellProvide your client_id and client_secret as HTTP headers on every request:
| Header | Value |
|---|---|
X-Chalk-Client-Id | Your service token’s client_id |
X-Chalk-Client-Secret | Your service token’s client_secret |
The server exchanges these for a short-lived access token internally, so you do not need to run the OAuth client-credentials flow yourself.
The server also accepts a standard Authorization: Bearer <access_token> header. If a request
arrives without credentials, the server responds with 401 and a WWW-Authenticate challenge
pointing at Chalk’s OAuth discovery endpoints
(/.well-known/oauth-protected-resource), so MCP clients that implement the
MCP authorization spec
(including Dynamic Client Registration) can negotiate a token interactively. For headless and
server-to-server use, the X-Chalk-Client-Id / X-Chalk-Client-Secret headers are the simplest
option.
Interactive registration currently works for clients whose callback is a hosted web address, such as the claude.ai web app. A client that runs on your own machine, including Claude Code and other terminal or desktop clients, asks to be sent back to a local address on a random port, and Chalk does not yet accept those, so registration fails before a browser opens. Use the header-based setup in Connecting a client for those clients. As an alternative for Claude Code specifically, adding Chalk as a claude.ai custom connector, under Settings then Connectors, uses an allowlisted callback and syncs down into the CLI.
By default, requests run against the environment associated with your service token. To target a different environment, either:
X-Chalk-Env-Id: <environment_id> header, orenvironment_id argument to an individual tool call.Environment overrides are only honored for user (personal) credentials. Use the list_environments
tool to discover the environment IDs available to your team.
The server currently advertises the following 66 tools. The tools/list response is the runtime
source of truth for their input schemas and behavior annotations.
Every tool is authorized individually: it checks the permissions on the credentials that called it
and returns a permission error if they fall short, so what a client can do is set by its token
rather than by the server. run_online_query requires query.online. The observability and
Kubernetes inspection tools require monitoring.read. Sandboxed Python execution and the deployment
filesystem tools require deploy.redeploy, which is also the permission for running a notebook
cell, so a token that can run notebook cells can also execute code against a deployment.
The deployment file tools provision or reuse a source sandbox, including tools that only read or search files. The server therefore marks those tools as destructive and non-idempotent.
| Tool | Description |
|---|---|
echo | Return a supplied message. This is primarily useful for testing a connection. |
whoami | Return the authenticated identity and selected Chalk environment. |
next_steps | Propose a follow-up action for the user without executing it. |
list_environments | List environments available to your team, including their IDs. |
list_environment_secrets | List environment secret names and metadata without returning secret values. |
search_docs | Search the Chalk documentation, or read one exact documentation page. |
search_docs_functions | Search exact Chalk function signatures and API reference entries. |
| Tool | Description |
|---|---|
run_online_query | Run an online query for one or more features. |
execute_sql_query | Execute a ChalkSQL query, with preview support. |
search_offline_queries | Search offline queries with filters, or fetch one complete query by operation ID. |
search_sql_catalog | Browse catalogs and schemas, or search tables and columns. |
lint_sql_query | Plan ChalkSQL against the catalog without executing it. |
propose_sql_worksheet_edit | Return a complete SQL worksheet edit for review in the Chalk dashboard. |
| Tool | Description |
|---|---|
search_graph | Search deployed features and resolvers, or fetch one exact definition. |
list_branches | List the deployment’s branches. |
get_deployment | Return metadata for a deployment. |
list_functions | List external functions in the environment. |
inspect_function | Inspect an external function’s metadata, schemas, configuration, readiness, and source when available. |
invoke_function | Invoke an external function with JSON or Arrow IPC input. |
deploy_chalk_function | Create an external function or deploy a new revision from Python source. |
deployment_read | Read one file from a deployment source sandbox. |
search_deployment_files | Search deployment source files by regular expression or glob. |
write_deployment_file | Write a complete deployment file or replace exact text in one. |
deployment_bash | Run a shell command in a deployment source sandbox. |
These tools create, edit, and run Chalk Notebooks and their cells.
Several of them propose a change instead of making it. A proposal renders in the notebook as a pending card at the position the agent chose, showing the new or rewritten source as a diff with Confirm and Undo controls, and the notebook is unchanged until someone confirms. Confirming inserts the cell but does not run it.
That review step only exists in the Chalk dashboard, where a notebook is open to display it. A client connecting over this endpoint has no reviewer, so a proposal it returns is never shown to anyone and nothing is written.
add_notebook_cell and delete_notebook_cell take persist=true, which applies the change
directly and requires deploy.redeploy. edit_notebook_cell has no such argument: to change an
existing cell from a client like this, use edit_and_run_notebook_cell, which persists the new
source but also executes the cell. That path covers python and sql cells only.
| Tool | Description |
|---|---|
create_notebook | Create a notebook. |
list_notebooks | List the notebooks in the environment. |
read_notebook | Read a notebook’s ordered cells and optionally their most recent execution results. SQL and query results include the column schema, a row count, and a capped sample rather than the full dataframe, and the sampled rows are referenced rather than inlined in the response. |
add_notebook_cell | Propose adding a python, sql, text, markdown, or input cell. Returns a proposal for the user to confirm rather than persisting; pass persist=true to apply it directly. |
edit_notebook_cell | Propose a rewrite of a cell’s source. Returns a before/after diff for the user to confirm rather than persisting. |
move_notebook_cell | Move a cell to a new position. Persists immediately. |
delete_notebook_cell | Propose deleting a cell. Returns a proposal for the user to confirm rather than persisting; pass persist=true to apply it directly. |
run_notebook_cells | Execute cells and wait for them to finish, provisioning the kernel if needed. Omit the cell ids to run every runnable cell in document order. |
add_and_run_notebook_cell | Add a python or sql cell and execute it in one call, returning the run output. Persists immediately, so it requires deploy permission. |
edit_and_run_notebook_cell | Replace a python or sql cell’s source and execute it in one call. Persists immediately, so it requires deploy permission. |
install_python_dependencies | Install python packages into a notebook’s kernel by adding and running a !uv pip install cell. The cell persists immediately, so this requires deploy permission. Packages last for the kernel’s lifetime, and rerunning the notebook reinstalls them. |
attach_secrets_to_notebook | Attach existing environment secrets to a notebook by reference, without values passing through the conversation. |
These tools run commands or Python in a general-purpose sandbox.
| Tool | Description |
|---|---|
start_sandbox | Start a general-purpose sandbox and return its id, for reuse across exec_in_sandbox calls. Defaults to the python:3.12-slim image. |
exec_in_sandbox | Run a command in an existing sandbox. |
eval_python | Execute Python in a fresh ephemeral sandbox and return its output. Bare expressions produce nothing, so print what you want back. For repeated work, start_sandbox and exec_in_sandbox reuse one container. |
| Tool | Description |
|---|---|
get_query_errors | List recorded query errors, with filtering and pagination. |
get_query_plan_json | Return a chalk://query-plans/... resource URI for a query plan. Plans can run to hundreds of kilobytes, so the tool hands back the URI and the client reads the resource. |
get_perf_summary_json | Return a chalk://performance-summaries/... resource URI for a query’s performance summary, read the same way as a query plan. |
search_logs | Search application logs for the environment. |
inspect_log_facets | List log facets, or inspect the observed values and counts for one facet. |
search_traces | Search distributed traces and their spans. |
search_kube_events | Search Kubernetes cluster events (scheduling, OOM kills, crashes). |
list_kube_events_in_namespace | List recent Kubernetes events in one namespace. |
get_kube_pod | Inspect a pod’s specification, status, and recorded events. |
inspect_kube_deployments | List Kubernetes deployments or inspect one deployment in full. |
inspect_kube_capacity | List or inspect Karpenter NodePools and NodeClasses. |
get_unschedulable_workloads | Diagnose workloads that Kubernetes cannot schedule. |
| Tool | Description |
|---|---|
list_datasets | List datasets and their latest revision metadata. |
inspect_dataset | Fetch one dataset’s metadata and optionally its revision history. |
get_dashboard_authoring_context | Return the dashboard JSON contract and metric authoring catalog. |
find_dashboards | Search dashboards, or fetch one complete dashboard definition. |
validate_dashboard | Validate a dashboard definition without saving it. |
create_dashboard | Create a dashboard from a validated definition. |
get_chart | Fetch one saved metric chart. |
get_monitor_authoring_context | Return the monitor JSON contract, metric catalog, and alert channels. |
find_monitors | List monitors, or fetch one complete monitor definition. |
validate_monitor | Validate a monitor definition without saving it. |
create_monitor | Create a monitor from a validated definition. |
list_volumes | List Chalk volumes, optionally filtering by name prefix. |
create_volume | Create a versioned Chalk volume. |
create_volume_from_github_repo | Copy a GitHub repository into a Chalk volume. |
create_github_pr_from_volume | Open a GitHub pull request that makes a repository match a Chalk volume. |
Alongside tools, the server exposes MCP resources, which a client reads by URI rather than calling. Two tools hand back a resource URI instead of the payload itself, because a query plan or performance summary can run to hundreds of kilobytes.
Two resources are available directly:
| URI | Contents |
|---|---|
chalk://sql/catalogs | The ChalkSQL catalogs for the environment, including the built-in chalk catalog, offline_store, and any connected data sources. Use these names when writing ChalkSQL. |
chalk://server/info | Basic information about the Chalk server. |
Others are addressed by filling in a template:
| URI template | Contents |
|---|---|
chalk://environments/{environment_id} | An environment’s name, project, cloud provider, and region. |
chalk://sql/schemas/{catalog} | The schemas within a ChalkSQL catalog. |
chalk://query-plans/{query_plan_id} | A query plan, as JSON. Call get_query_plan_json first to obtain a valid URI. |
chalk://performance-summaries/{operation_id} | A query’s performance summary, as JSON. Call get_perf_summary_json first to obtain a valid URI. |
The server also advertises resource subscriptions, so a client that supports them can be notified when a resource changes.
One prompt is available, help, which takes a topic argument and returns guidance on Chalk
operations.
execute_sql_query.