MCP Flow
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@MCP Flowadd the GitHub MCP server and list its tools"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
MCP Flow is one process that serves three things on one port. It serves the
MCP gateway at /mcp. It serves an admin web user interface (UI). It serves a
health endpoint at /health. The Python package and the console command keep
the name mcpflow.
The gateway runs child MCP servers as subprocesses. It also proxies remote MCP servers. A failed child does not stop the gateway or another child. A change to a child takes effect without a process restart.
How it works
agent ──┐ ┌── uvx <python package> (namespace a)
agent ──┼── Bearer token ──► /mcp ─┼── npx <npm package> (namespace b)
agent ──┘ MCP Flow ├── https://remote/mcp (namespace c)
│ └── mcpflow_* built-in admin tools
/login / /marketplace /tokens /apiAn agent connects to
/mcpwith one bearer token. The gateway publishes every visible tool of every running child as{namespace}_{tool}. A muted tool stays hidden.The admin adds, edits, mutes, and restarts children in the web UI, over the Representational State Transfer (REST) application programming interface (API) at
/api, or with the built-inmcpflow_*MCP tools.The gateway keeps its persistent state under one data directory. See "Files under
DATA_DIR".
Related MCP server: mcpstead
Screens
Select a picture to open it at full size.
Contents
Install
Install the package with pip. The package needs Python 3.12 or newer.
pip install mcpflowSet the admin password
The process needs an admin password. Create a password hash first.
mcpflow hash-passwordThe command prints one line that starts with pbkdf2_sha256$. Set the line as
ADMIN_PASSWORD_HASH. You can also set the clear-text ADMIN_PASSWORD instead,
but the hash is safer.
Run the server
Start the gateway with serve. The flags override the environment variables.
export ADMIN_PASSWORD_HASH='pbkdf2_sha256$...'
mcpflow serve --host 127.0.0.1 --port 8000 --data-dir ./dataOpen http://127.0.0.1:8000/login and log in with the admin password.
Run with Docker
Copy the example environment file and set the values.
cp .env.example .env
# set ADMIN_PASSWORD_HASH and SECRET_KEY in .env
docker compose up -dThe compose file builds the image, maps port 8000, and mounts a named volume
at /data. Open http://localhost:8000/login.
The named volume is mcpflow-data.
To build the image from a local wheel, run make docker-build-local. The
command builds the wheel and passes it to Docker through a named build context.
Environment variables
Name | Default | Purpose |
|
| registry, tokens, logs, caches |
|
| bind address |
|
| bind port |
| unset | clear-text admin password; hashed in memory at start |
| unset | output of |
| unset | cookie signing key; else |
|
| set |
|
| session lifetime |
|
| probe timeout in seconds |
|
| process log level |
| unset | externally reachable base URL; else the request host |
| Docker: | uvx cache |
| Docker: | npx cache |
Files under DATA_DIR
The process keeps all state under one data directory.
servers.json: the persisted list of child servers.tokens.json: the API tokens. The file holds only the SHA-256 digest of each token.secret_key: the cookie signing key. The process creates it on first start with mode0600.logs/{namespace}.log: the stderr of one child. The process truncates it on each start.servers/{namespace}/: the inline source files of one child (see Inline source servers). Directories are mode0700, files0600.creds/{namespace}/:client.jsonandtoken.jsonfor an OAuth child. Files are mode0600.cache/uvandcache/npm: the package caches in Docker.
Add a server
Open / and select Add server. The add window opens over the dashboard
and has three tabs.
Python: run a Python MCP server with
uvx <package>. Enter the package and arguments.npm: run a Node MCP server with
npx -y <package>. Enter the package and arguments.JSON: paste a raw MCP config block. The form reads a
mcpServersobject or a bare name map.
The add form supports two more kinds through import. A remote server proxies
an HTTP or SSE URL. A custom server runs any command.
Source: run a package from a git repo or a local directory
The Python and npm tabs accept an optional Source. It names where to
install the package from: a git URL, a github: shorthand, or an absolute
directory path. It must start with git+https://, https://, github:, or
/. Only the Python and npm kinds accept a source.
With a source, the gateway runs uvx --from <source> <package> or
npx -y --package=<source> <bin>. On the npm tab, Package is then the bin
name, not the npm package name.
# Python from a git repo
source: git+https://github.com/owner/repo
package: my-tool
# npm from a github shorthand
source: github:owner/repo
package: my-binA source may embed a credential for a private repo, for example
git+https://oauth2:<token>@gitlab.example/owner/repo. The gateway stores the
raw URL in servers.json (mode 0600) and shows the redacted form
git+https://***@gitlab.example/owner/repo in the servers table and in every
REST API response. The edit form shows the raw value.
Import from mcpmarket
The mcpmarket tab posts a listing URL. The importer fetches the page and pre-fills the add form from the first server that it finds. The admin always confirms before the registry changes.
The importer accepts only https URLs on the allowed hosts mcpmarket.com,
www.mcpmarket.com, github.com, and raw.githubusercontent.com. It does not
follow redirects.
The import can fail. mcpmarket.com can answer 429. The page can carry no MCP
config. On a failure the UI shows the error and a JSON paste field. Paste the
server config and confirm.
API tokens
An MCP client authenticates to /mcp with a bearer token. Open /tokens to
manage the tokens.
Enter a name and a scope, then select Create token. The page shows the token once. It starts with
mcpflow_. Copy it now. The server stores only the SHA-256 digest.Select revoke to delete a token. The next request with that token fails.
A token has one scope. An mcp token authenticates /mcp only. An admin
token authenticates /api and /mcp. An admin session on /mcp also sees
the built-in admin tools (see Admin MCP tools below). The scope selector
defaults to mcp.
Send the token in the Authorization header.
Authorization: Bearer mcpflow_<token>The gateway publishes every tool of a running child as {namespace}_{tool}.
Connect an agent
Every client needs the same two facts: the URL of the gateway and one bearer
token. MCP Flow speaks streamable HTTP at /mcp. It is one server to the
client, however many children it runs behind that address.
Create a token at /tokens first. That page prints the two blocks below with
your real host and token already filled in, so copy from there rather than
retyping.
URL https://mcp.example/mcp
Header Authorization: Bearer mcpflow_<token>Claude Code
Run one command. It writes the server into the Claude Code config for you.
claude mcp add --transport http mcpflow https://mcp.example/mcp --header "Authorization: Bearer mcpflow_<token>"Check it with claude mcp list. To share the server with a repository instead
of your user account, add --scope project; Claude Code then writes .mcp.json
beside your code, so use a token you are willing to commit, or none at all.
Any client that reads an mcpServers block
Most clients take the same JSON. Paste this into the client's MCP config file:
{
"mcpServers": {
"mcpflow": {
"type": "http",
"url": "https://mcp.example/mcp",
"headers": {
"Authorization": "Bearer mcpflow_<token>"
}
}
}
}Where that file lives differs by client:
Client | Config file |
Claude Code |
|
Cursor |
|
Windsurf |
|
Claude Desktop |
|
Two clients differ from the block above. VS Code names the top-level key
servers, not mcpServers, and reads .vscode/mcp.json in a workspace.
Codex CLI keeps its servers in ~/.codex/config.toml as
[mcp_servers.mcpflow] rather than in JSON.
These formats move. If a client rejects the block, check that client's own
documentation for the current key names; the URL and the Authorization header
are the parts that come from MCP Flow.
Check the connection
Ask the agent to list its tools. Every tool MCP Flow publishes carries its
namespace as a prefix, so a time server appears as time_get_current_time.
If the agent sees nothing, confirm the child reports running on the dashboard
and that the namespace is not muted.
An admin token additionally exposes the built-in mcpflow_* tools, so the
agent can add and restart servers itself. See "Admin MCP tools" below.
Admin API
The gateway serves a JSON REST API under /api. A script manages the same
servers, tools, and tokens as the HTML pages. Every route needs an admin
token in the Authorization header. The session cookie does not authenticate
/api. An mcp token authenticates /mcp only; an admin token
authenticates /api and /mcp. Create an admin token on /tokens.
Method | Path | Body | Result |
GET |
| — | list the children |
POST |
|
| add a child, |
GET |
| — | one child |
PUT |
|
| replace a child |
DELETE |
| — | remove a child, |
POST |
| — | enable a child |
POST |
| — | disable a child |
POST |
| — | restart a child |
GET |
| — | the log tail as text |
GET |
| — | the tool list |
PUT |
|
| mute or show all tools |
PUT |
|
| mute one namespace |
PUT |
|
| mute one tool |
GET |
| — | list the tokens |
POST |
|
| create a token, |
DELETE |
| — | revoke a token, |
A PUT /api/servers/{ns} is a full replacement. An omitted field takes the
ServerSpec default, so an omitted enabled starts a stopped child. Send
"enabled": false to keep it stopped.
An error answers with a JSON body {"error": "<message>"}. A bad request is
400. An unknown namespace or token is 404. A missing or wrong-scope token
is 401.
List the servers:
curl -H "Authorization: Bearer mcpflow_<admin token>" http://localhost:8000/api/serversAdmin MCP tools
The gateway mounts one built-in MCP server under the namespace mcpflow. Its
tools manage the gateway over /mcp, so an agent that speaks only MCP adds a
child, reads a log, or unmutes a tool without the REST API. The tools publish
as mcpflow_<tool>. An admin token is required on /mcp to see and call them.
An mcp session never lists or calls a mcpflow_* tool. A muted root hides the
child tools but never a mcpflow_* tool, so an admin session can always unmute.
The namespace mcpflow and every namespace that starts with mcpflow_ are reserved.
A child cannot take one, so no child tool name shadows an admin tool.
Tool | Purpose |
| list the children |
| one child |
| add a child from a spec and start it |
| replace a child spec; the argument names the child |
| remove a child |
| enable a child |
| disable a child |
| restart a child |
| the log tail as text, capped at 1000 lines |
| the tool list with visibility |
| mute or show all child tools |
| mute one namespace |
| mute one child tool |
| fetch candidate specs from a URL; adds nothing |
| write inline source files for a child (see Inline source servers) |
mcpflow_import_from_url returns candidates only. The agent confirms each one
with mcpflow_add_server. No tool mints a token; tokens stay on the REST API and
the tokens page.
Call a tool with an MCP client that sends the admin token. For example, with
the FastMCP client:
from fastmcp import Client
from fastmcp.client.transports import StreamableHttpTransport
transport = StreamableHttpTransport(
"http://localhost:8000/mcp",
headers={"Authorization": "Bearer mcpflow_<admin token>"},
)
async with Client(transport) as c:
servers = await c.call_tool("mcpflow_list_servers", {})Inline source servers
An agent can write a small MCP server as source files and run it, with no git
host and no shell access. The flow is three steps over /mcp with an admin
token:
mcpflow_write_source(namespace, files)writesfilesunderDATA_DIR/servers/<namespace>/and returnspath.mcpflow_add_serverwith kindpythonornpm, apackage, andsourceset to the returnedpath. The gateway runsuvx --from <path> <package>ornpx -y --package=<path> <bin>.The child's tools appear on
/mcp.
files maps a relative POSIX path to file text. Limits: at most 200 files,
512 KiB per file, 1 MiB total. A key may not be absolute, hold a . or ..
segment, a backslash, or a NUL, and no key may be a directory prefix of
another. A bad key returns a ToolError that names the key.
A write replaces the whole tree at once: a file absent from the new files is
gone. restarted in the result is true when the write bounced an existing
running or failed child onto the new files. It is false for a starting
child (call mcpflow_restart_server once it settles), a stopped child
(enabled owns the process), and a namespace with no child yet (call
mcpflow_add_server next). If a call fails at the restart step, the files are
already written; call mcpflow_restart_server.
A child's source must point at its own directory. mcpflow_remove_server
deletes the directory; mcpflow_update_server to a git source and
mcpflow_disable_server keep it.
Development
The project uses uv and pytest. Run the tests from the repository root.
uv sync --extra dev
make testThe project uses OpenSpec. The published specs live in openspec/specs/. An
in-flight change lives in openspec/changes/<change>/. Run openspec validate
before you archive a change.
The logo lives at src/mcpflow/static/logo.svg. The web UI serves the same
file at /static/logo.svg.
License
MIT. See LICENSE.
MCP Flow runs third-party MCP servers as child processes and proxies remote ones. Each of those carries its own license; this one covers MCP Flow itself.
This server cannot be deployed
Maintenance
Related MCP Connectors
Governed MCP gateway: one endpoint for your tools, with credential custody and audit log.
MCP server for mandates, delegation, policy-gated execution, credential grants, and audit.
Unified gateway exposing 150+ tools across all NexGenData MCP servers via one endpoint.
- gatewayOAuthai.sealgate
MCP gateway with runtime security policy, tool-call-level control, and audit of agent actions.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables centralized management and unified interface for multiple child MCP servers (filesystem, sqlite, etc.), allowing users to discover, launch, and execute tools across different MCP servers through a single gateway.-
- AlicenseNot gradedqualityDmaintenanceMCP Gateway that aggregates multiple upstream MCP servers into a single endpoint with persistent connections, tool registry, and authentication.14 npm2MIT
- AlicenseNot gradedqualityCmaintenanceA gateway that aggregates multiple MCP servers into a single endpoint, namespacing their tools and forwarding calls, so an agent connects to one MCP to access the entire stack.MIT
- AlicenseNot gradedqualityCmaintenanceAn agent gateway that aggregates multiple local MCP servers into a single MCP endpoint with runtime control, hot-reloadable configuration, and meta tools like bridge__execute for calling any child server tool without restart.29 npmMIT