anymo Docs
Guides

MCP and plugins

Anymo speaks the Model Context Protocol in both directions: it can consume tools from local and remote MCP servers, and it can serve its own brain to other agents. This page covers consuming; serving is the Runtime Bridge.

Two ways to connect

PathTransportConfigured in
Connectors (remote servers)Streamable HTTP with OAuthDesktop Plugins view: catalog or add-by-URL
Local servers (stdio)stdio subprocess.anymo/mcp.toml in the workspace

Remote connectors

The desktop Plugins view ships a connector catalog (including Hugging Face) plus an add-by-URL path for any remote MCP server over streamable HTTP.

  • OAuth happens in your system browser with a loopback callback; the app shows "Waiting for authorization" and resolves when the callback lands.
  • Tokens are sealed at rest like provider keys. They never appear in config files, and removing a connector removes its token.
  • Errors read as a status sentence with a Reconnect button.

Local stdio servers

The kernel discovers and invokes tools from configured stdio MCP servers. Discovered tools are exposed as ordinary registry entries named mcp.<server_id>.<tool_name>, so every call still goes through policy evaluation, approval, and the executor-enabled gate.

.anymo/mcp.toml
[[servers]]
id = "local-search"
command = "$WORKSPACE/bin/example-mcp-server"
args = ["--stdio"]
enabled = true
tool_allowlist = ["search"]
timeout_ms = 10000
max_output_bytes = 65536

[servers.env]
ANYMO_EXAMPLE_TOKEN = "fake-token"
PATH = "$WORKSPACE/bin"
Resolve paths outside model control

Server commands, arguments, and environment variables come only from trusted config. The model never chooses process commands or launch arguments. Keep real credentials in the host's secret-storage flow, not in this file.

Safety model

  • Every MCP tool is risk_level = high and approval_required = true: it asks for approval in every permission mode.
  • A tool executor is enabled only when its server has enabled = true and its raw tool name is in tool_allowlist. Empty allowlists fail closed.
  • Tool names are sanitized before they enter the public registry. For example, Read File! becomes mcp.local_server.read_file.
  • Tool arguments are not logged by the MCP host. Environment values and common secret assignments are redacted from returned text and error context.
  • Responses are size-capped by max_output_bytes.
  • MCP tool annotations are treated as untrusted hints: they can never lower a tool's risk or approval level.

Using the host from Rust

Embedders can drive the MCP host directly. The first unapproved call returns ApprovalRequired; request user approval through the existing flow before retrying with approved = true:

rust
use std::sync::Arc;
use hive_kernel::{McpManager, SafeDefaultPolicy, ToolContext, ToolRegistry, Workspace};

let manager = Arc::new(McpManager::from_toml_file("$WORKSPACE/config/mcp.toml")?);
let mcp_registry = manager.discover_registry().await?;

let mut tools = ToolRegistry::new(Arc::new(SafeDefaultPolicy));
mcp_registry.register_into(&mut tools);

let workspace = Arc::new(Workspace::new("$WORKSPACE")?);
let ctx = ToolContext::new(workspace);

// approved must be true only after the user grants the approval request.
let output = tools
    .execute(
        "mcp.local-search.search",
        serde_json::json!({ "query": "example" }),
        &ctx,
        true,
    )
    .await?;

Plugin hooks

Plugins can also contribute skills and hooks. Command-hook execution is disabled by default: you trust each plugin explicitly before its command hooks can run. The doctor check plugin_trust reports the current state.

Current limits

  • Local servers use stdio transport only.
  • One client session is opened for discovery and one for each tool call.
  • Disabled servers are not launched during discovery.
Anymo ยท Apache-2.0 GitHub