Connect an agent with MCP
Use the shared product operations through authenticated, scoped tools.
BytesMap exposes its registered product operations through a stateless Streamable
HTTP endpoint at /api/mcp. Tools use the real API routes and the shared platform
authorization layer. There is no separate agent implementation of query, chart,
or dashboard logic.
Connect
Open Settings → Agents & MCP for this instance's endpoint and supported authentication method. Hosted instances support OAuth-capable clients. BytesMap advertises its authorization server through the MCP challenge and protected-resource metadata. The client opens Connect to BytesMap, where you sign in, choose a workspace, and approve full access or selected resources. The same permission editor is used for people, API keys, and assistant conversations. Settings → Agents & MCP lets you edit access or disconnect.
Packaged BytesMap Desktop accepts local clients with a scoped, expiring API key. The CLI's desktop transport discovers and authenticates the current instance, so clients do not need to save its changing localhost port. Choose Selected resources, include MCP connection → View, and set an expiry. Full-workspace keys and keys without an expiry are rejected. The private host capability is never an agent credential. Desktop OAuth and automatic editing of other applications' client settings are not provided.
Choose your client
Settings includes client-specific recipes with copy controls for Claude Code, Codex, Cursor, VS Code, Claude Desktop, Windsurf, Zed, and other MCP clients. Select your client and either Sign in with BytesMap or API key. The guide uses the instance's advertised endpoint; it does not guess from the browser address.
For a hosted OAuth connection, replace the example with your actual endpoint:
# Claude Code: use /mcp after adding the server to finish authorization.
claude mcp add --scope user --transport http bytesmap https://api.example.com/api/mcp
# Codex: add the endpoint, then complete the browser sign-in.
codex mcp add bytesmap --url https://api.example.com/api/mcp
codex mcp login bytesmap| Client | Where to connect |
|---|---|
| Claude Code | User-scoped claude mcp add; authorize through /mcp. |
| Codex CLI and IDE extension | codex mcp add and codex mcp login; shared user configuration. |
| Cursor | Personal ~/.cursor/mcp.json, under mcpServers. |
| VS Code | Run MCP: Add Server from the Command Palette and select HTTP or local stdio. |
| Claude Desktop | Add a remote custom connector in its connector settings, or use claude_desktop_config.json for local stdio. |
| Windsurf | ~/.codeium/windsurf/mcp_config.json, with serverUrl for HTTP. |
| Zed | context_servers in settings, with a native url for HTTP. |
Claude's remote connectors must reach the API from the provider's infrastructure; a private localhost address is not a hosted connector. Use local stdio for BytesMap Desktop. Client availability and authentication features can vary by client version. The in-app guide links to each client's official setup instructions.
For Codex API-key authentication, keep the credential in an environment variable available to the Codex process:
[mcp_servers.bytesmap]
url = "https://api.example.com/api/mcp"
bearer_token_env_var = "BYTESMAP_API_KEY"Do not put real keys in project configuration or source control. The guide supplies placeholders only. Connected OAuth clients appear in Agents & MCP, where you can edit resource access or disconnect. API-key clients are managed under API keys.
Desktop clients using stdio
Keep BytesMap Desktop running. Save the selected-resource key using stdin or your secret manager; do not put it in command arguments:
bytesmap login --desktop --name desktop-agent --token-stdinConfigure a client that supports MCP stdio:
{
"mcpServers": {
"bytesmap": {
"command": "bytesmap",
"args": ["--context", "desktop-agent", "mcp", "--desktop"]
}
}
}Alternatively provide the scoped key through BYTESMAP_API_TOKEN and run
bytesmap mcp --desktop. Remove BYTESMAP_API_URL for this transport. Remote and
native contexts' saved credentials are never reused for desktop discovery.
bytesmap logout desktop-agent removes the saved connection; revoke its key in
Settings to disconnect all clients using that key.
The desktop publishes only its per-launch public identity and loopback origin in
the current user's private ~/.bytesmap/desktop.json. Before each request, the
CLI verifies a fresh Ed25519 challenge and sends the key on that same TCP
connection. The connector cannot silently create another connection after the
proof. A stale port, changed key, redirect or lost connection fails closed; no
tool call is automatically replayed. Reopening the app publishes its new identity.
The private record's integrity depends on the operating system user account;
this is not a sandbox against other code already running as that same user.
Requests are bounded to 4 MB, replies to 8 MB and transport time to two minutes,
with at most 16 outstanding stdio operations. Cancellation remains available
when that limit is reached.
Direct URL/header clients can still use the exact current endpoint shown in Settings. Prefer the discovered stdio transport for a persistent desktop setup; an old localhost URL alone does not authenticate the process now listening there.
Hosted and directly configured HTTP clients
For clients using an API key:
- Open Settings → API keys in the workspace you want the client to use.
- Create a key with MCP connection → View, plus the resource permissions it needs. An authoring key can have source read access and query/chart/dashboard edit access without permission to execute queries.
- Copy the key when it is shown. Configure the client with the API's
/api/mcpURL and anAuthorization: Bearer <key>header.
For clients supporting URL/header configuration:
{
"mcpServers": {
"bytesmap": {
"url": "http://localhost:4077/api/mcp",
"headers": { "Authorization": "Bearer YOUR_API_KEY" }
}
}
}Use the actual HTTPS API URL for remote hosting. Prefer the client's secret or environment-variable support rather than committing credentials in a config file. The Settings page also shows the endpoint and a configuration example.
Keys are fixed to their workspace and intersect with the owner's current access. Expiry, revocation, demotion, or removal applies to later tool calls. Full-access keys still cannot mint API or event-ingestion keys, or manage account security, memberships or invitations. Existing event-key metadata and revocation have the separate dataset administration boundary described below. See identity and access.
Tools and execution
tools/list is the authoritative list for the current caller. It comes from
the mcp metadata beside each route/contract and uses the route's request schema.
Current capabilities include:
| Area | Tools |
|---|---|
| Workspace | workspace_list |
| Sources | source_list, source_kinds_list, source_schema_read, source health/profile and key-value preview tools |
| Query authoring | query_list, query_read, query_create, query_update, query_delete |
| Visual nodes | flow_catalog, flow_validate: actual node templates, ports, controls, operators and the saved graph protocol |
| Views | view_catalog, view_validate, view_list, view_get, view_create, view_update, view_remove |
| Chart authoring | chart_list, chart_read, chart_create, chart_update, chart_delete, chart_suggest |
| Dashboards | dashboard_list, dashboard_read, dashboard_create, dashboard_update, overview/home tools |
| Dashboard folders | dashboard_folder_create, dashboard_folder_rename, dashboard_folder_remove, dashboard_move |
| Explicit execution | source_sql_run, query_run, flow_preview, view_data; view_submit explicitly runs a configured workflow |
| Planning | query_cost, view_cost, dashboard_cost |
| Events | Dataset and destination setup, typed fields, events_search, events_inspect, events_groups_read |
| Activity | audit_list, when the key has workspace audit read access |
This is a capability overview. The operation reference lists
every public tool with its exact input schema, permission and effect annotation.
Views are the public component-authoring family; internal panel transport aliases
are not a second set of discoverable tools. Read view_catalog before authoring
and use view_validate with real sample columns before publication.
Event ingestion is an effect: events_ingest appends using the caller's existing
dataset ingest permission. It does not create a bearer key. The user creates
ingestion credentials in Events; tools can list redacted credential metadata and,
with dataset administration access, revoke an existing credential.
The permission layer filters capabilities; individual calls also check the exact resource ids. A client may have access to one source without access to another. Source connection/discovery tools are opt-in per route. Desktop tools may inspect and scan an authorized saved server; public MCP does not expose host-only routes. There is no raw SSH or operating-system command tool.
Read a definition before editing it. query_update accepts the same saved query
protocol as the app, including flow graphs and native statements; the existing
flow/query validators apply. chart_update changes rendering settings without
executing the query. dashboard_update changes title, description, layout, or
parameters through the same handler as the dashboard UI.
Saving does not run a query. Run/preview requires explicit execution permissions, including every source a flow references. Query-plan estimation does not execute the data query, but it contacts the database planner; its permission checks still apply. Schema/profile tools may also contact the database.
Dashboard promotion uses three separate tools. dashboard_promotion_review
reads saved metadata and prior catalog evidence; it returns blockers and a comparison
fingerprint without contacting source databases. source_promotion_schema_capture
explicitly reads bounded database catalogs and stores compatibility evidence; it
never reads application rows or accepts caller-supplied schema. After reviewing
explicit destination mappings, dashboard_promotion_apply creates new unpublished
drafts atomically. It does not copy credentials, publish workflows, run effects or
activate schedules. Native SQL, HTTP effect remapping and unresolved dependencies
remain blocked. A reviewable result is draft-copy readiness, not a production safety
certificate. Reuse the exact request key and body after an uncertain copy response;
a stale-review conflict requires a fresh review before a new copy intent.
Tool output can contain real database values when execution or inspection is
authorized. Results retain their estimated, sampled, and truncated metadata;
clients should preserve those distinctions. There is no claim that attaching an
agent keeps every returned value away from that agent's model provider.
Transport and authorization
MCP request → authenticate key/session → permission-filtered tool
→ app.fetch(internal Request + verified context)
→ route validation + current resource permissions → handler
→ shared platform operation → audit recordThe verified internal context is attached in a process-local WeakMap. It is not a JSON argument or a forwarded identity header. The inner request rechecks current membership/key restrictions without authenticating or counting the credential a second time. API and MCP share errors and response shapes.
The server supports initialize, ping, tools/list, and tools/call with
protocol version 2025-06-18. Notifications receive 202 without a JSON-RPC
response. There is no server event stream or persistent MCP session; authenticated
GET/DELETE probes receive 405 with Allow: POST. Tool failures use
isError: true; protocol failures use JSON-RPC errors. The server does not offer
resources, prompts, or subscriptions.
OAuth and live access
The maintained Better Auth OAuth provider owns registration, S256 PKCE, signed
consent requests, authorization codes, rotating refresh tokens, and signing keys.
The configured API origin is the issuer; caller-supplied Host/Forwarded headers
cannot change it. Set BYTESMAP_ADVERTISED_ORIGIN to the external API origin when
hosting behind a proxy. Access tokens are audience-bound to that origin's
/api/mcp and cannot be replayed against ordinary REST or account endpoints.
OpenShip's grant-holder pattern ties each user/client connection to one workspace. JWTs contain a binding reference, not a frozen copy of permissions. Every tool call resolves current membership and intersects its current grants with the connection's selected grants. Disconnect removes tokens, consent, and the binding; reconnect creates a new binding so old JWTs cannot regain access. Revoking a JWT through the OAuth revocation endpoint also closes that connection. Revoking only a refresh token prevents future refreshes; use Disconnect to revoke all existing access. Userinfo and introspection also honor live binding and membership state.
An explicitly local development host can still use a framework session for OAuth consent. A one-use host assertion creates its HttpOnly cookie only after the normal kernel-peer and pinned-user checks. No identity header or browser-supplied user ID can bootstrap this session. This development path does not expose OAuth to external clients through the packaged desktop's private host boundary.
Desktop Mindwire
The desktop assistant uses Mindwire's SDK and daemon natively inside the existing control plane. Its private MCP bridge is generated from the same operation catalog and calls the same shared platform services with a delegated user context. Native agent capabilities cannot bypass that bridge. See the assistant guide for sign-in, approvals, supported harnesses, and verification.