Skip to main content

faucet_cli/commands/
mcp.rs

1//! `faucet mcp` — an MCP server over stdio (issue #420).
2//!
3//! Reads newline-delimited JSON-RPC 2.0 messages from stdin and writes each
4//! response to stdout (one JSON object per line), dispatching through the
5//! shared [`crate::mcp`] handler. stdio is local-trust: there is no bearer /
6//! RBAC layer, so mutating tools require the explicit `--allow-mutations` flag.
7//!
8//! Logs go to **stderr** (installed in `run_main`) so the stdout JSON-RPC
9//! stream stays clean.
10
11use crate::cli::McpArgs;
12use crate::error::CliResult;
13use crate::mcp::{McpContext, serve_stdio};
14use tokio::io::BufReader;
15
16pub async fn run(args: McpArgs) -> CliResult<()> {
17    let cwd = std::env::current_dir()?;
18    let env_path =
19        crate::env_loader::resolve_env_file(args.env_file.as_deref(), args.no_env_file, &cwd)?;
20    crate::env_loader::load_env_file_if_present(env_path.as_deref())?;
21
22    // stdio mode has no shared `auth:` catalog; inline connector auth still
23    // works for configs passed to preview/validate/run_pipeline.
24    let auth = crate::auth_catalog::build_auth_catalog(None)?;
25    #[cfg_attr(not(feature = "templates"), allow(unused_mut))]
26    let mut ctx = McpContext::new(auth, args.allow_mutations);
27
28    // Pipeline-template registry (#444): opt-in over stdio, since there is no
29    // `--history` backend to inherit. Without it the template tools are not
30    // advertised at all.
31    #[cfg(feature = "templates")]
32    if let Some(url) = args.template_store.as_deref() {
33        ctx = ctx.with_templates(crate::templates::resolve_store_url(url).await?);
34        tracing::info!(store = %url, "pipeline-template registry attached");
35    }
36
37    tracing::info!(
38        allow_mutations = args.allow_mutations,
39        "faucet mcp stdio server started"
40    );
41
42    let mut stdout = tokio::io::stdout();
43    serve_stdio(&ctx, BufReader::new(tokio::io::stdin()), &mut stdout).await?;
44
45    tracing::info!("faucet mcp stdio server stopped (stdin closed)");
46    Ok(())
47}