For the complete documentation index, see llms.txt. This page is also available as Markdown.

Export & self-host your MCP server

Most FlowCP servers run on FlowCP's hosted runtime. On a paid plan you can also export a published server as a portable standard FlowCP folder and run it on your own infrastructure — for data-residency, air-gapped deployments, or running the MCP endpoint inside your own network.

The export is language-agnostic: the folder is a config.yaml plus human-readable per-item files (tools, skills, prompts, widgets, resources, documentation pages), consumed by the FlowCP standalone runtime container. There is no generated per-server code and no second SDK to maintain — the same runtime that powers the hosted platform reads the folder from disk instead of from FlowCP's database.

See The standard FlowCP folder for the full layout.

What you get

flowcp export writes a standard FlowCP folder:

my-server/
├── config.yaml          # server identity, auth mode, apiBaseUrl, requiredEnv
├── README.md            # run instructions specific to your server
├── Tools/
│   ├── openapi.json     # the source OpenAPI document (reference)
│   └── <tool>.yaml      # one file per tool: definition + policy
├── Skills/   <name>.md
├── Prompts/  <name>.md
├── Widgets/  <name>.html (+ <name>.json sidecar)
├── Resources/ <name>.md
├── Docs/     <slug>.md  # documentation pages, nested by slug
├── docker-compose.yml   # runtime-only compose file (no Postgres, no Redis)
└── .env.example         # the environment variables to fill in

Security: secrets are never exported

A folder never contains secrets. Just like a configuration snapshot, the export records only the fact that a credential exists (hasAuthSecret) and the placement of your shared credential (which header or query parameter it goes in) — never the value. You supply the actual secret at run time through the environment (FLOWCP_UPSTREAM_SECRET). The same default-deny, fail-closed, and redaction rules apply to the standalone runtime as to the hosted one.

Export your server

The server must be published first (a draft has no stable contract to self-host).

You can also trigger an export programmatically:

which returns { server, files }, where files maps each folder-relative path to its contents.

Run it

Your MCP endpoint is served at http://localhost:3002/mcp/<serverId> (and at /mcp). Point your AI client at that URL.

Environment

The variables you need depend on the server's auth mode:

Variable
When
Description

FLOWCP_FOLDER_PATH

always

Path to the FlowCP folder (set by the compose file).

FLOWCP_RUNTIME_MODE

always

standalone (set by the compose file).

FLOWCP_UPSTREAM_SECRET

bearer / api_key

The token / key sent to your upstream API.

MCP_RUNTIME_PORT

optional

Listen port (default 3002).

MCP_RUNTIME_PUBLIC_URL

optional

Public URL of the server (used in OAuth metadata).

MCP_ALLOWED_ORIGINS

optional

Browser origins allowed to call the server (see below).

FLOWCP_SYNC_URL

optional

FlowCP API origin to poll for config updates (see below).

FLOWCP_DEPLOY_TOKEN

with sync

Deploy token presented when polling FLOWCP_SYNC_URL.

FLOWCP_SYNC_INTERVAL

optional

Sync poll interval in seconds (default 60, min 10).

Earlier exports shipped a single flowcp.bundle.json. The standalone runtime still boots from one via the deprecated FLOWCP_BUNDLE_PATH for backward compatibility, but new exports use the folder format above.

Restricting browser origins

MCP asks servers to validate the Origin header so a page on another site cannot drive your server through a visitor's browser. Set MCP_ALLOWED_ORIGINS to the browser origins you serve:

Requests with no Origin header (Claude Desktop, Cursor, the CLI — anything that is not a browser) and same-origin requests are always allowed. Leaving the variable unset accepts every origin, which is the default; the runtime logs a warning at boot while it is unset.

Keep a self-hosted server up to date

An exported folder is a point-in-time artifact: when you later change the server on FlowCP (enable a tool, edit a prompt, publish a new version), the self-hosted copy does not change by itself. Two update mechanisms are supported — pick whichever fits your operations.

Option A: sync mode (pull/watch)

The standalone runtime can poll FlowCP for the latest published config and hot-swap it in memory — no redeploy, no restart. Enable it with two variables:

Create the deploy token first — it is a narrow, revocable credential that can only read this one server's export snapshot (it can never mutate anything):

The raw token is returned once, at creation; store it in your deployment's secret manager. Revoking the token stops sync for that machine immediately.

How sync behaves:

  • The runtime polls GET /v1/servers/:serverId/export/snapshot every FLOWCP_SYNC_INTERVAL seconds (default 60) with If-None-Match, so an unchanged config is a cheap 304.

  • When the published config changed, the runtime validates the new snapshot and swaps it atomically. New MCP sessions see the new tools immediately; sessions opened before the swap keep their tool set until they expire.

  • Fail closed, keep serving: a network error, a 403 (revoked token or plan downgrade), or an invalid snapshot never takes the server down — the runtime keeps serving the last good config and retries on the next tick.

  • Secrets are never pulled. Only the config travels; the upstream credential stays in your environment (FLOWCP_UPSTREAM_SECRET).

  • The on-disk folder is not rewritten (it is mounted read-only). After a restart the runtime boots from the folder again and catches up on the first poll. Re-export when you want the folder itself to move forward.

Option B: CI re-export (push)

If you prefer immutable deploys, re-run the export in CI and redeploy the container. The flowcp CLI authenticates with a workspace API token (flowcp_pat_…), which works headlessly in GitHub Actions:

Runtime image updates are the same in both options: the standalone runtime is the shared FlowCP runtime image, so pulling a newer image tag upgrades the runtime without touching your folder.

Supported auth modes

Mode
Self-host support

none

✅ Runs with no secret.

api_key

✅ Supply the key via FLOWCP_UPSTREAM_SECRET.

bearer

✅ Supply the token via FLOWCP_UPSTREAM_SECRET.

user_oauth

⏳ Follow-up — also needs your OAuth provider client credentials.

Shared-credential modes (none / api_key / bearer) self-host today with no database or cache. Per-user OAuth self-hosting is on the roadmap.

Last updated