Deployment

August 1, 2026 · View on GitHub

English | 简体中文

This guide covers supported 1.0 deployment shapes. Start from loopback, add an intentional authentication mode, and validate the real Apache Doris route before exposing the Server to a Host.

Choose a transport

ShapeUse whenProcess modelAuthentication boundary
stdioOne local Host launches one Serverchild processlocal OS/process boundary plus Doris credentials
Streamable HTTP, loopbackLocal tools share a serviceone or more workers, subject to auth modetoken/JWT/OAuth optional but recommended
Streamable HTTP behind TLS proxyControlled remote accessproxy + Server workersauthenticated HTTP, trusted proxy policy, TLS

The retired standalone SSE transport is not supported. New HTTP integrations use POST /mcp and MCP 2026-07-28.

stdio deployment

Example Host command:

{
  "command": "doris-mcp-server",
  "args": ["--transport", "stdio"],
  "env": {
    "DORIS_HOST": "127.0.0.1",
    "DORIS_PORT": "9030",
    "DORIS_USER": "mcp_reader",
    "DORIS_PASSWORD": "<secret>",
    "DORIS_DATABASE": "information_schema"
  }
}

Operational rules:

  • stdout is reserved for MCP frames;
  • logs must use stderr or configured files;
  • the Host owns process restart and environment injection;
  • do not share the process with unrelated users when credentials are in the environment;
  • stdio initialization establishes a working Doris route before accepting ordinary work.

Streamable HTTP deployment

Local command:

export TRANSPORT=http
export SERVER_HOST=127.0.0.1
export SERVER_PORT=3000
export DORIS_HOST=127.0.0.1
export DORIS_PORT=9030
export DORIS_USER=mcp_reader
export DORIS_PASSWORD='<secret>'

doris-mcp-server --transport http --host 127.0.0.1 --port 3000

Endpoints:

  • POST /mcp — modern MCP requests;
  • GET /live — process/protocol liveness;
  • GET /ready — bounded Doris-backed readiness;
  • GET /health — compatibility health view;
  • /mcp/legacy — default-off protocol migration adapter.

Enable /mcp/legacy only for validated handshake-era clients such as Dify 1.16.1 (2025-06-18) or SDK v2 clients using 2025-11-25:

export ENABLE_LEGACY_HTTP_ADAPTER=true

Configure those Hosts with the exact /mcp/legacy URL. Keep modern 2026-07-28 Hosts on /mcp; the Server never silently downgrades that endpoint.

Keep the Server on loopback until authentication, Host/Origin policy, proxy behavior, TLS termination, timeouts, and secret injection are tested together.

Authentication and worker count

Stateless MCP requests do not require sticky sessions. Authentication and provider modes can impose tighter constraints:

ModeWorker guidance
static tokenmultiple workers are possible with shared token/state configuration
JWTmultiple workers are possible with consistent keys/policy
external OAuth/OIDCmultiple workers require consistent validation and mapping configuration
Doris-backed OAuthexactly one worker in 1.0; tokens and user pools are process-local
custom provider rate limitingquotas are per process unless the provider supplies external state

Independently launched replicas behind a load balancer must share the same high-entropy MCP_STATE_HANDLE_SECRET so pagination/state handles remain valid across instances. They must also share compatible authorization policy and visible catalogs. Do not share Doris OAuth traffic across replicas in 1.0.

Docker

Build locally:

docker build -t doris-mcp-server:1.0.0 .

Run with an environment file stored outside the image:

docker run --rm \
  --env-file /secure/path/doris-mcp.env \
  --publish 127.0.0.1:3000:3000 \
  doris-mcp-server:1.0.0

Or review docker-compose.yml and .env.example before using Compose. The checked-in examples contain placeholders and security assertions; they are not production credentials.

Container requirements:

  • pin the image/release rather than deploying mutable latest;
  • mount secret files read-only with owner-restricted permissions;
  • keep /live and /ready as separate probes;
  • set memory/CPU limits compatible with query concurrency and result ceilings;
  • allow only required FE MySQL, FE HTTP, BE HTTP, OAuth, and provider egress;
  • avoid publishing the port on all interfaces until the proxy/auth boundary is complete.

Reverse proxy and TLS

When traffic leaves the machine:

  1. terminate TLS with a controlled proxy or in the platform ingress;
  2. preserve required MCP headers and request body without method/name rewrite;
  3. configure exact public Host/Origin behavior;
  4. configure trusted proxy CIDRs before honoring forwarded headers;
  5. reject oversized requests before they reach the process, while keeping limits compatible with MCP Schema/instance ceilings;
  6. disable buffering/timeouts that would truncate valid Streamable HTTP responses;
  7. never log bearer or admin authorization headers.

Binding 0.0.0.0 only selects a network interface. It does not authorize a public hostname, proxy, or Origin.

Apache Doris routing

Single FE:

export DORIS_HOST=fe.example
export DORIS_PORT=9030
export DORIS_FE_HTTP_HOST=fe.example
export DORIS_FE_HTTP_PORT=8030

Multiple FE candidates:

export DORIS_HOSTS='fe-1.example:9030,fe-2.example:9030'
export DORIS_FE_HTTP_HOSTS='fe-1.example:8030,fe-2.example:8030'

Explicit BE HTTP allowlist:

export DORIS_BE_HOSTS='be-1.example:8040,be-2.example:8040'

The route manager validates candidates and preserves route identity. Do not allow MCP callers to supply arbitrary FE/BE hostnames. Network policy should restrict egress to the configured cluster and reviewed providers.

Exposure mode

Default:

export MCP_TOOL_EXPOSURE_MODE=hierarchical

Host compatibility fallback:

export MCP_TOOL_EXPOSURE_MODE=flat

Changing the mode requires process restart and Host reconnect. It is a startup contract, not a per-request switch.

Optional providers

  • ADBC: enable the default-off advanced provider and configure Arrow Flight SQL ports; ordinary queries still use MySQL, and ADBC calls require explicit end-user intent plus explicit_adbc=true.
  • Ossie: set OSSIE_ENABLED=true, mount reviewed models and private Doris bindings, and grant explicit semantic scopes.
  • MetricFlow: configure an absolute reviewed sidecar command and project; validate Doris-dialect compilation and real Doris read-only/negative-write behavior before enabling it.
  • Native lineage: configure the canonical queryable store/provider and verify required columns and delivery health.
  • Custom tools: install the package and list its exact provider name in MCP_TOOL_PROVIDERS.

An optional provider that is absent should make relevant children unavailable, not prevent unrelated domains from working. An explicitly allowlisted but invalid custom provider fails startup.

Rollout procedure

  1. Pin the package/image and capture configuration hashes without secrets.
  2. Validate startup configuration offline/in a staging process.
  3. Check /live and /ready independently.
  4. Run server/discover and tools/list from the target Host.
  5. Discover all authorized domains and record callable states/reason codes.
  6. Execute a read-only SELECT 1 through the formal Query child.
  7. Execute negative tests: write SQL rejection, unauthorized child, invalid cursor, permission-denied table, result/timeout ceiling.
  8. Validate FE failover and readiness if multiple FE routes are configured.
  9. Compare the generated tool registry and release artifacts with the deployed package version.
  10. Enable production traffic gradually and monitor typed failures/truncation.

Upgrade and rollback

  • Read Migrating to 1.0 before replacing a pre-1.0 Server.
  • Restart Hosts so cached pre-1.0 schemas disappear.
  • Treat exposure-mode changes as an API change requiring reconnect.
  • Roll back package/image and configuration together.
  • A rollback does not make 1.0 state handles or manifests valid on an older process; Hosts must rediscover.
  • Do not use the legacy HTTP adapter as a permanent mixed-version deployment.

See Configuration reference and Reliability and limits.