MCP server (agent tools)
faucet can expose itself as an MCP (Model Context Protocol) server, so an LLM agent (Claude Desktop / Code, or any MCP client) can operate faucet: discover connectors, read their config schemas, scaffold and validate a pipeline YAML, preview sample records, and — behind an explicit opt-in — run a pipeline.
MCP is not a data connector (there is no faucet-source-mcp); it is a
second front-door onto the operations faucet serve already implements. The
MCP layer adds no pipeline capability — it re-exposes existing,
schema-introspective surfaces in the shape an agent speaks.
The prebuilt binaries (Homebrew, the curl | sh installer and the release
archives — see Installation) include it,
so faucet mcp works out of the box. From crates.io it is the mcp feature
(off in the default build; included in full):
cargo install faucet-cli --features mcpTwo transports
Section titled “Two transports”stdio — faucet mcp
Section titled “stdio — faucet mcp”For a local agent. Reads newline-delimited JSON-RPC on stdin, writes responses on stdout (logs go to stderr):
faucet mcp # read-only toolsfaucet mcp --allow-mutations # also expose run_pipelinefaucet mcp --template-store sqlite:./faucet-templates.db # + the template toolsClaude Desktop config (claude_desktop_config.json):
{ "mcpServers": { "faucet": { "command": "faucet", "args": ["mcp"] } }}stdio has no bearer/RBAC layer. Without --allow-mutations the server treats
every config the client sends as untrusted, because preview builds and reads
the source it is handed: configs are screened like a body submitted to
faucet serve — subprocess connectors (singer), ${env:} / ${file:} /
secret-manager directives and local file paths are refused. Pass
--allow-mutations only for a trusted local agent: its configs then run with
your user’s access and run_pipeline is exposed. Do not expose stdio remotely —
use the HTTP transport with auth for that.
Streamable HTTP — faucet serve --mcp
Section titled “Streamable HTTP — faucet serve --mcp”Mounts a /mcp route on the running control plane. It inherits serve’s
bearer-auth + RBAC + audit — an MCP request is authenticated, authorized, and
recorded exactly like any other API call:
faucet serve --mcp --auth-token "$TOKEN"faucet serve --mcp --mcp-allow-mutations --auth-config rbac.yamlcurl -s localhost:8080/mcp -H "Authorization: Bearer $TOKEN" \ -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'Read-only tools are always available; the mutating run_pipeline tool appears
only when the server is started with --allow-mutations and (on HTTP) the
caller holds the RunWrite RBAC scope — so a Viewer token can never mutate,
even on a mutation-enabled server.
| Tool | Mutating? | What it does |
|---|---|---|
list_connectors |
no | Sources, sinks, transforms, state stores + conformance tier. |
get_connector_schema |
no | JSON Schema for a connector / transform config. |
scaffold_config |
no | A commented YAML skeleton for a source→sink pair. |
validate_config |
no | Full load-time validation (matrix or topology). |
preview |
no | Up to 100 sample records from the first source (source side only). |
run_pipeline |
yes | Run an inline config. Pass dry_run: true to validate + preview only, and selection ({select, only, skip, tags, status, include_parents}) to run only some matrix rows. |
list_templates |
no | Registered pipeline templates and the typed params each takes. |
get_template |
no | One template: declared params, stored config body, and its release state (status, stable / previous / newest, channel pointers, launch log). |
list_template_rows |
no | A template’s selectable rows — a source template’s streams (write resolution and guarantees against sink when given) or a pipeline’s matrix rows — with status, tags, hierarchy, read/write facts, params used and the last run’s state. With selection, also the run_set a run with it would execute, the ancestors it pulls in, and the rows it blocks. See Running a subset of streams. |
register_template |
yes | Register a template document as a new version — kind: source-template, kind: sink-template, or kind: pipeline. Inert by default — pass launch: true to make it live. |
run_template |
yes | Run a template with given params / env, at a version or named channel (default stable — the launched version). A source template also takes sink (a registered sink template) + sink_version, and optionally overlay (a registered deployment id or an inline mapping — an inline one is screened under the caller reference policy and refused for a tenant) + overlay_version. dry_run: true materializes + validates only and reports the per-stream write-mode plan. selection runs a subset of the streams / rows (the dry run reports the run_set). |
On faucet serve --mcp, run_pipeline and run_template submit through the
server exactly as POST /v1/runs / POST /v1/templates/{id}/runs do, as the
calling principal — the approval gate, the server --policy, the
--default-config, the run queue and the run record all apply — and answer
with the run_id (or the pending change request). Poll it with
GET /v1/runs/{id}. On stdio they run the pipeline in the MCP process and
report its counts. A run_template env override names a variable the
template reads (${env:NAME} / ${secret:NAME}) and is literal text: a value
containing ${ is refused, and a tenant-scoped principal may not pass env.
The four template tools appear only when a registry is wired — faucet serve --mcp uses its own --history backend; faucet mcp needs
--template-store <url>. Without one they are not advertised at all, so an agent
never sees a tool it cannot use.
Templates are the ergonomic shape for agent-driven runs: the agent discovers the
typed parameter surface with list_templates / get_template and then supplies
only the values that change, instead of composing (and possibly mis-composing) a
whole config. A secret: true param is echoed back as "***".
Every MCP call over HTTP is written to the audit log; secret material is redacted from any tool output.
Protocol
Section titled “Protocol”A JSON-RPC 2.0 subset: initialize, tools/list, tools/call,
resources/list, ping. The advertised protocol version is 2024-11-05.
// → initialize{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}// ← {"result":{"protocolVersion":"2024-11-05","serverInfo":{"name":"faucet",…}}}
// → discover + generate + check, then (with permission) run{"jsonrpc":"2.0","id":2,"method":"tools/call", "params":{"name":"scaffold_config","arguments":{"source":"rest","sink":"bigquery"}}}Security model
Section titled “Security model”- Read-only by default.
run_pipeline,register_template, andrun_templateare absent fromtools/listunless mutations are enabled.previewstill executes the source it is given, so without mutations the stdio server screens configs as untrusted (see above). - HTTP inherits serve auth. Bearer/RBAC + audit apply to
/mcpas to any route; mutations additionally require theRunWritescope. previewis bounded (≤100 rows) — never a full extract. It reads pages only until the limit is reached and stops after 30 seconds, returning what it has with"timed_out": true;run_pipeline {dry_run: true}previews the same way.- Secrets never leak — tool output is run through the same redactor as the rest of the control plane.