MCP integration
Connect an MCP-compatible host to a running tapstate server through the CLI gateway
MCP (Model Context Protocol) lets an AI desktop app, editor, or agent call selected tapstate control-plane operations through a standard tool interface. Tapstate provides a local MCP gateway in the complete CLI bundle.
The gateway is an optional integration. It does not install or start a tapstate server, provide a web UI, or expose an MCP HTTP endpoint from the server.
How the connection works
The MCP host starts tapstate mcp as a local process and speaks MCP over the
process's standard input and output. The gateway then calls an already-running
tapstate server over its authenticated HTTP(S) control plane.
MCP connection path
The host starts a local gateway; the server authenticates every control-plane request.
MCP host
Codex, Claude Code, or another MCP client.
tapstate mcp
Local gateway from the complete CLI bundle.
tapstate server
Checks the token, exposes tools, and performs operations.
The MCP host receives a scoped machine token through TAPSTATE_TOKEN. It never needs the tapstate administrator password.
This means the CLI and the server have separate responsibilities:
- The MCP host launches and supervises the local gateway.
- The CLI bundle supplies the
tapstate mcpcommand and its sidecar. - The tapstate server authenticates requests and performs the operation.
- The MCP gateway does not replace the server or the server's authorization checks.
The current server-backed path is provided by the disposable Docker Quickstart. This release does not include a standalone server installer. Run the Quickstart when you need a local server to test the integration.
Requirements
Before configuring an MCP host, make sure that:
- You installed the complete CLI bundle, not only a standalone
bin/tapstatebinary. The bundle keepsbinandlibexectogether so the CLI can find its sidecar. - A tapstate server is already running and reachable from the gateway.
- You have administrator credentials to create a scoped machine token, or an existing machine token with the scope required by the tools you plan to use.
- The complete CLI bundle's sidecar is
tapstate-mcp.jar, so Java 21 or newer is required for this release. The native CLI's offline commands do not require Java.
For a loopback server, use http://127.0.0.1:8080 or another loopback address.
For a remote server, use HTTPS. The gateway rejects a non-loopback HTTP URL.
Authenticate the host
Do not give an MCP host the tapstate administrator password. Use the password once in an interactive CLI session, then create a scoped machine token for the host.
Start the CLI and connect to the server:
tapstate -w tapstate-workIn the CLI, log in as an administrator and enter the password only when the prompt requests it:
connect http://127.0.0.1:8080
login admin
Password:Create a read token for read-only tools:
token create --scope read -o jsonUse a dedicated read token for each MCP host. The bearer value is displayed once; copy it into the host's protected local secret configuration. The host presents this token to the tapstate server on every request, and the server verifies its scope. The host does not repeat the administrator-password login.
When an MCP tool accepts connector settings, you can use environment references
in those settings. ${VAR} requires VAR to be set; ${var:NAME:default}
uses default when NAME is not set. The local gateway expands these references
before it sends the request. A missing required variable returns
mcp.environment-missing; keep the values in the host or process environment
instead of putting secrets in tool arguments.
See Manage machine tokens for list and revoke commands, or the REST API machine-token endpoints for the HTTP request and response.
Start the gateway manually
Set TAPSTATE_TOKEN in the environment through your shell's secret-handling
method rather than passing the value as a command argument. The gateway accepts
TAPSTATE_SERVER_URL as a default server URL; passing --server makes the
target explicit:
tapstate mcp --server http://127.0.0.1:8080When the command starts successfully, it waits for MCP JSON-RPC messages on standard input. It is not an interactive tapstate prompt. Keep this process in the foreground when testing it manually; an MCP host normally starts and stops it for you.
If the server is remote, use its HTTPS URL:
tapstate mcp --server https://tapstate.example.comDo not put a real token in a checked-in host configuration, shell history, or a support report. Use the host's secret or environment-variable facility.
Configure an MCP host
MCP hosts use different settings locations, but the registration has the same
shape: launch the installed tapstate executable, pass mcp and the server
URL as arguments, and provide TAPSTATE_TOKEN as an environment variable.
Set TAPSTATE_TOKEN in the current shell using your local secret-handling
method. The following commands copy its current value into the client's local
MCP configuration.
Register the stdio gateway with Codex, then inspect the saved entry:
codex mcp add \
--env TAPSTATE_TOKEN="$TAPSTATE_TOKEN" \
tapstate -- \
"$HOME/.tapstate/bin/tapstate" mcp \
--server http://127.0.0.1:8080
codex mcp get tapstateRegister the stdio gateway for the current user, then inspect the saved entry:
claude mcp add --scope user tapstate \
-e TAPSTATE_TOKEN="$TAPSTATE_TOKEN" -- \
"$HOME/.tapstate/bin/tapstate" mcp \
--server http://127.0.0.1:8080
claude mcp get tapstateProtect the resulting client configuration as a secret-bearing file. Do not commit it to a repository or include it in a support report.
Other MCP hosts
For a host that accepts an mcpServers JSON object, the shape is:
{
"mcpServers": {
"tapstate": {
"command": "/Users/you/.tapstate/bin/tapstate",
"args": [
"mcp",
"--server",
"http://127.0.0.1:8080"
],
"env": {
"TAPSTATE_TOKEN": "<server-token>"
}
}
}
}Replace command with the absolute path to the installed CLI on your system.
If you installed to another directory, use that directory's tapstate entry
point. Keep the corresponding libexec/tapstate-mcp.jar beside the versioned
CLI bundle; moving only the executable breaks sidecar discovery.
After saving the host configuration, restart or reload the host according to
its instructions. A healthy integration should start the process, complete the
MCP initialization handshake, and return the read-only tools from tools/list.
Verify the connection
After reloading the host:
- Confirm that the
tapstateMCP entry starts without a handshake or authentication error. - Confirm that the client's available MCP tools include
system_versionandconnector_list. - Ask the host to call
system_version. It identifies the server before the agent reasons about supported operations. - Ask the host to call
connector_list. A successful call verifies the local process, MCP handshake, server URL, and machine token.
If a tool call returns isError: true, the MCP layer is reporting a failed tool
call. The failure can come from the local gateway, an unreachable server, or a
server-side refusal; a successful handshake or tools/list call does not prove
that every operation will succeed. Inspect the returned code, message, and
params, then check the server URL, token scope, and server state.
Tools
Read-only tools
By default, the gateway exposes read-only tools:
| MCP tool | Purpose |
|---|---|
system_version | Report the server release, accepted DSL versions, and system-data schema version. |
artifact_validate | Validate a complete tapstate/v1 workspace without writing it. |
artifact_get | Read one applied resource and its content hash. |
source_draft | Render canonical YAML for a source from its live connector contract. |
connection_test_result | Read the latest persisted connection-test result. |
connection_schema | Read the latest discovered source schema. |
connector_list | List connectors visible to the online server. |
connector_get | Read a connector's live specification and availability. |
data_browser_collections | List the collections held by a declared source's database. |
data_browser_find | Read a bounded preview of rows from one collection. |
data_browser_stats | Read the collection metadata reported by its connector. |
pipeline_status | Read a pipeline's current lifecycle status. |
pipeline_metrics | Read the latest bounded pipeline metrics. |
pipeline_snapshot | Read the latest per-table snapshot progress. |
pipeline_logs | Read a bounded, secret-redacted pipeline log tail. |
Browse data
The data-browser tools read through a declared source's configured connection.
They do not accept a database URI or a database query language. The source and
collection name are required; data_browser_find also accepts optional
filter, sort, and limit values:
Data access boundary: Data-browser tools are read-only, but they can return source records to the MCP host. In this preview, data-browser access does not have a separate permission and these reads do not create audit events. Give the host a dedicated read-scoped token, restrict who can control the host, and avoid sensitive sources while evaluating the integration.
{
"sourceId": "warehouse",
"collection": "orders",
"filter": {
"field": "status",
"op": "eq",
"value": "paid"
},
"sort": {
"field": "total",
"dir": "desc"
},
"limit": 25
}The filter vocabulary is eq, ne, gt, gte, lt, lte, in, exists,
and contains. You can combine terms with one level of all or any. A
literal dotted field name is written as price\\.usd in JSON. The API rejects
database-native operators and arbitrary nested Boolean groups.
data_browser_find is a one-shot preview: the default is 10 rows, the maximum
is 200 rows, and no cursor or next-page token is available. In this preview,
row previews are available only for sources that use the mongodb connector.
Collection listing and statistics can still be available for other connectors.
The gateway does not expose the CLI's live watch or tail views. Use the
CLI reference
when a person needs to follow changes in a terminal.
The host's tools/list response is the runtime authority if a later release
adds, removes, or renames a tool.
Troubleshooting
| Symptom | Meaning | Action |
|---|---|---|
cli.mcp-unavailable (exit code 3) | The CLI cannot find or start its sidecar, or Java 21 is unavailable. | Use the complete bundle, keep bin and libexec together, and verify java -version. |
TAPSTATE_TOKEN must be set | The gateway did not receive a token through its environment. | Add TAPSTATE_TOKEN to the host environment; do not use --token. |
MCP Server URL must use HTTPS unless host is loopback | A remote server was configured with plain HTTP. | Use an HTTPS URL or test against a loopback server. |
isError: true with control.unreachable | The gateway could not reach the configured server. | Check the server URL, network path, and server logs. |
isError: true with mcp.environment-missing | A required ${VAR} reference was not set. | Set the variable in the MCP host environment or use ${var:NAME:default} when a default is safe. |
isError: true with mcp.connector-spec-unavailable | The gateway could not read the connector contract needed for the operation. | Check the connector ID and the server's connector registry. |
isError: true with mcp.server-rejected | The server returned a refusal without a more specific code. | Inspect the returned status and parameters, then correct the request or server state. |
Protocol error -32602 | The host called an unknown tool or supplied invalid protocol parameters. | Refresh the tool list and use the exact tool name and input schema returned by the server. |
The gateway writes protocol frames to stdout. Do not wrap it in a command that prints banners or diagnostics to stdout; non-protocol output can prevent the host from completing the MCP handshake.