use agent_config::{mcp_by_id, AgentConfigError, McpSpec, Result, Scope};
fn main() -> Result<()> {
let project = tempfile::tempdir().expect("create tempdir");
let scope = Scope::Local(project.path().to_path_buf());
let claude = mcp_by_id("claude").expect("claude supports MCP");
let inline_spec = McpSpec::builder("github")
.owner("myapp")
.stdio("npx", ["-y", "@modelcontextprotocol/server-github"])
.env("GITHUB_TOKEN", "ghp_xxxxxxxxxxxxxxxxxxxx")
.try_build()?;
match claude.install_mcp(&scope, &inline_spec) {
Err(AgentConfigError::InlineSecretInLocalScope { name, key }) => {
println!("refused: server={name:?} env_key={key:?}");
}
Err(other) => return Err(other),
Ok(_) => unreachable!("default policy must refuse inline secrets locally"),
}
let safe_spec = McpSpec::builder("github")
.owner("myapp")
.stdio("npx", ["-y", "@modelcontextprotocol/server-github"])
.env_from_host("GITHUB_TOKEN")
.try_build()?;
let install = claude.install_mcp(&scope, &safe_spec)?;
println!(
"\ninstalled github MCP (created={:?}, patched={:?})",
install.created, install.patched
);
let again = claude.install_mcp(&scope, &safe_spec)?;
assert!(again.already_installed, "reinstall must be a no-op");
println!(
"reinstall was idempotent: already_installed = {}",
again.already_installed
);
let public_spec = McpSpec::builder("public-key")
.owner("myapp")
.stdio("npx", ["-y", "@example/server"])
.env("API_KEY", "intentionally-public-value")
.allow_local_inline_secrets()
.try_build()?;
let _ = claude.install_mcp(&scope, &public_spec)?;
let removed = claude.uninstall_mcp(&scope, "github", "myapp")?;
println!(
"\nuninstalled github (removed={:?}, patched={:?})",
removed.removed, removed.patched
);
let wrong_owner_err = claude
.uninstall_mcp(&scope, "public-key", "not-myapp")
.unwrap_err();
assert!(matches!(
wrong_owner_err,
AgentConfigError::NotOwnedByCaller { .. }
));
println!("wrong-owner uninstall refused as expected: {wrong_owner_err}");
let _ = claude.uninstall_mcp(&scope, "public-key", "myapp")?;
Ok(())
}