
Your agent needs to query ClickHouse. ClickHouse now gives you more than one way in: a hosted remote MCP server, an open-source MCP server you run yourself, a native SQL-over-HTTP interface, and a full Cloud management API. They do not cover the same ground, they do not authenticate the same way, and the read-versus-write line runs straight down the middle. Here is how to decide which one your agent should build against.
There are four objects in play, not two. Two of them are MCP servers; two are API surfaces. Getting the comparison right starts with separating them.
ClickHouse maintains two MCP servers, built for different deployments. The remote server is a managed endpoint for ClickHouse Cloud. The open-source server is a package you run against any ClickHouse instance, self-hosted or Cloud. Both are first-party; neither is a community fork. The rest of this article treats them together as the MCP path and calls out where they diverge.
The remote MCP server is fully managed by ClickHouse Cloud and speaks Streamable HTTP at https://mcp.clickhouse.cloud/mcp. You enable it per service from the Connect menu; there is nothing to deploy. Authentication is OAuth 2.0 against your ClickHouse Cloud credentials, and access is scoped to the organizations and services the signed-in user can already reach. It exposes 13 documented tools spanning query execution, schema exploration, service details, backups, ClickPipes, and billing, and every tool is annotated readOnlyHint: true. Details are in ClickHouse's remote MCP server documentation.
For self-hosted ClickHouse, the open-source mcp-clickhouse server is a Python package built on FastMCP. It runs locally over stdio by default, with http and sse transports available for networked deployments. It ships three core tools: query execution via run_query, plus list_databases and list_tables, and an optional chDB query tool. It connects to your database with environment-variable credentials such as CLICKHOUSE_HOST, CLICKHOUSE_USER, and CLICKHOUSE_PASSWORD, and it runs read-only unless you set CLICKHOUSE_ALLOW_WRITE_ACCESS=true. The source lives in the official ClickHouse MCP server repository.
On the API side there are also two surfaces, and they answer different questions. The native HTTP interface runs SQL against a service. The ClickHouse Cloud API manages the service itself. An agent that both queries data and provisions infrastructure touches both.
Every ClickHouse deployment exposes a SQL-over-HTTP interface, on port 8123 for HTTP and 8443 for HTTPS. It accepts the full SQL surface: SELECT, INSERT, CREATE, ALTER, DROP, and bulk or streaming inserts, constrained only by the connecting user's grants. Authentication is HTTP Basic, with the ClickHouse username and password passed as credentials or request headers. This is where write throughput lives.
The ClickHouse Cloud API is a REST control plane at https://api.clickhouse.cloud/v1. It creates and scales services, provisions API keys, manages organization members and roles, configures backups, and creates or pauses ClickPipes. Authentication is HTTP Basic with a Key ID as the username and a Key Secret as the password. Keys map to roles: the developer role is read-only, and the admin role has full read and write access. The reference is in ClickHouse's Cloud API documentation.
Four objects, one practical question: for a given agent action, which path can actually perform it, and what does that path demand of your auth stack? Three dimensions decide it: capability, auth, and what you operate in production.
The MCP path is a read path. The API path is the read-plus-write path. The table below maps the actions an agent typically needs.
The open-source server covers the query and schema rows only; the management rows are specific to the remote server and the Cloud API. The self-hosted server can perform the write and DDL rows only if you explicitly set CLICKHOUSE_ALLOW_WRITE_ACCESS=true; the remote server cannot, on any credential.
The gap is not a set of missing tools that will ship next month. It is architectural. The remote MCP server is read-only by design, so any agent that ingests data, mutates schema, provisions a service, or pauses a ClickPipe cannot do it through MCP at all. Those actions require the HTTP interface or the Cloud API. If your agent is an analyst that reads, summarizes, and explains, the MCP surface is enough. If it is an operator that writes, the API is not optional.
Pick MCP and you are on OAuth, scoped to what a user can already read. Pick the API and you are on credential-based auth that can carry write access. The path you choose sets your credential model before you write a line of agent logic.
The remote MCP server uses OAuth 2.0 exclusively. When a client connects, it runs a browser-based consent flow, and the agent inherits the authenticated user's organization and service access. There is no API-key option on this path, and there is no write path. The open-source server is different in shape: it authenticates to the database with environment-variable credentials, and for http or sse transports it protects the endpoint with a static bearer token, an OAuth provider through FastMCP, or, for local development only, no auth at all. For a deeper look at how securing FastMCP with OAuth works in practice, that pattern applies directly here.
The Cloud API authenticates with a Key ID and Key Secret over HTTP Basic. The role attached to the key is the write switch: developer keys read, admin keys read and write. The native HTTP interface authenticates with a ClickHouse database user, and that user's grants decide what SQL is allowed. This is the deliberate design ClickHouse describes for its own tooling: browser OAuth grants read access, and anything that mutates state requires explicit key-based authentication.
Both paths require per-user credential isolation in a multi-tenant B2B agent. MCP's OAuth flow gives you a token per user. Direct API calls give you a credential per user, whether that is a Cloud API key or a database login. In neither case does the path itself solve storage, rotation, or revocation. Those are infrastructure problems regardless of which path you choose, and they are where the identity of every action is either preserved or lost. Credential ownership across agent tool-calling patterns is worth reading before you commit to either model.
On the remote server, ClickHouse owns the endpoint, the tool schemas, and the OAuth broker. You own per-user token storage, refresh, and revocation, plus the fact that the surface is read-only, so any write feature has to route somewhere else. On the open-source server, you own the whole process: the container, the transport, the database credentials, the write-access flags, and every schema change that lands when you upgrade the package.
With the API you own the full stack: endpoint selection, request construction, pagination, error handling, retries, and the token lifecycle. The trade is control. The Cloud API is versioned under /v1, and the HTTP interface is a stable SQL contract, so a scheduled ingestion agent calling the same endpoints is not exposed to tool-schema drift the way an MCP client can be when a server updates.
Use the MCP path when the agent reads more than it writes.
Use the API path when the agent has to change state.
Both paths leave the same gap: per-user credentials at scale. Scalekit closes it for either one and gives your agent a single tool-calling interface on top. Here is the build, in Python with LangChain, plus a TypeScript quickstart.
Scalekit's ClickHouse connector gives your agent the same tool surface as ClickHouse's remote MCP server: querying, schema, service, backup, ClickPipe, and billing tools, plus the newer managed-Postgres tools, for a total of 17. It authorizes over OAuth 2.1 with Dynamic Client Registration (DCR), and Scalekit stores each user's credential in an AES-256 token vault, namespaced per tenant. AgentKit tool calling and audit are on the free tier, so per-user auth is not a paid gate for getting to production.
Start by looking up or creating a connected account for the user, then send them through the OAuth flow. The connection_name string must match the connection you configured in the Scalekit dashboard; a mismatch here is the single most common integration error.
The agent should not receive a flat connector catalog. It should receive the tools the current user's connected account is authorized to call. list_scoped_tools returns exactly that scoped surface for one identifier, filtered to the ClickHouse connection.
The LangChain tool calling adapter maps the scoped ClickHouse tools straight into StructuredTool objects, so you register them on an agent without hand-writing schema conversion. Each tool call the agent makes resolves the user's credential server-side and executes as that user.
When you want deterministic control instead of an agent loop, call a tool by name. Every ClickHouse tool needs a serviceId; fetch it once from clickhouse_get_organizations and clickhouse_get_services_list, then query. The response carries an execution_id, which is the handle you use later for the audit trail.
The same flow in Node uses getAuthorizationLink and executeTool. The connection name still has to match the dashboard.
Whether you chose MCP or the API, the token or key still has to live somewhere, refresh on schedule, and disappear when a user leaves. The path changed the credential type. It did not build the infrastructure around it.
In a multi-tenant B2B agent, every customer has their own ClickHouse access. MCP's OAuth flow gives you a token per user. The API gives you a Cloud API key or a database login per user. Fifty customers is fifty credentials, each with its own lifecycle, each needing to be stored encrypted, isolated per tenant, and revocable on its own. Secure token management for AI agents at scale covers the storage and rotation patterns in detail.
A single admin API key looks fine in a demo. It does not survive production scale. Every query, every INSERT, every service change then traces back to one service account, so your audit trail cannot tell you which user or agent actually ran a destructive statement. When an employee leaves, the key generated eight months ago and stored in an environment variable is still valid. The agent does not decide to keep using it. It just does.
Scalekit's ClickHouse connector resolves the per-user credential on every tool call, so each query runs as the user who authorized it, never a shared key. The credential stays in the vault, never enters the LLM context, and never appears in your logs. The same auth infrastructure works whether you build on the read-only MCP surface or reach the write surface through a custom tool that proxies the Cloud API or HTTP interface. The MCP vs API decision does not change what you need at the credential layer.
This is the part a comparison table does not show and the part that decides whether an agent survives a security review. Three capabilities matter once real users arrive: attribution, least privilege, and isolation.
Every execute_tool call returns an execution_id and is written to Scalekit's auth logs with full attribution: who authorized the call, which agent ran it, the connection used, and the outcome. A shared token collapses that to one service account; per-user credentials keep the triggering user and the executing identity distinct on every record. Logs filter by user, organization, and status, and export to your SIEM, which is what turns "an agent ran a query" into "this user's agent ran this query and got this result." This is the foundation of audit trails for agent auth in B2B SaaS.
The ClickHouse connector exposes 17 tools, but an analytics agent needs three: clickhouse_run_select_query, clickhouse_list_databases, and clickhouse_list_tables. Handing it all 17 is both an accuracy problem and a cost problem. A server with 40 tools at roughly 200 tokens each burns about 8,000 tokens before the agent does any work, and larger tool surfaces produce worse tool selection. The fix is not better prompting; it is surface reduction. MCP is up to 32× more expensive than CLI — surface reduction is one of the key levers for controlling that cost. Virtual MCP servers let you declare exactly which tools an agent sees, scoping ClickHouse to the three it needs and dropping the fourteen management tools from its context entirely.
A Virtual MCP server is defined once per agent role and produces a static mcp_server_url. Before each run, you mint a short-lived session token scoped to one user's connected accounts, so one server definition serves all users with no credential sharing between them. Scope is a function of identity, not connector configuration: what the user cannot do, the agent cannot do. That is the property that lets the same ClickHouse agent run for user A and user B on the same endpoint without user A's data ever being reachable by the agent acting for user B. The mechanics behind this are detailed in access control for multi-tenant AI agents.
If your agent reads ClickHouse, summarizes it, and explains results to a user who is present, build on the MCP path. It is the faster route, ClickHouse maintains the server and the schemas, and the read-only surface is a feature for an analyst agent, not a limitation. If your agent ingests data, changes schema, or provisions and manages Cloud services, build on the API, because the read-only MCP surface simply cannot perform those actions. Many production systems end up doing both: MCP for the interactive read path, the API for background writes. The credential management problem is identical across both, and that is the part that needs production-grade infrastructure.
Browse the Scalekit ClickHouse connector and the full connector catalog if your agent also spans Snowflake or BigQuery. For patterns that put a data agent to work, see the revenue forecast commentary agent, the competitive intelligence briefing agent, and the incident response agent.
Building ClickHouse agents and want a second set of eyes on the auth model? Join the Scalekit Slack community, or talk to us for immediate help.