modular-agent-core 0.25.0

Modular Agent Core
Documentation

Language Crates.io Documentation License

English | 日本語

A Rust framework for building modular multi-agent systems with stream-based message orchestration.

Features

Agents

  • Stream-Based Data Flow — Real-time data streaming between agents
  • Built-in Agents — LLM, Web/HTTP, Slack, SQL databases, screen capture, and more (via agent libraries)
  • Extensible — Add agent plugins via Rust crates

Runtime

  • Local Execution — All processing happens on your machine; no cloud dependency
  • Cross-Platform — Windows, macOS, Linux
  • Embeddable — Minimal dependencies; embed into CLI tools, desktop apps, servers, or any Rust application

Overview

modular-agent-core provides an asynchronous, stream-based architecture for orchestrating multiple agents. Agents communicate through message passing and can be composed into networks using Presets. This is the core library with minimal dependencies—individual agent implementations are available separately.

Installation

[dependencies]
modular-agent-core = "0.25"

To disable default features:

[dependencies]
modular-agent-core = { version = "0.25", default-features = false, features = ["llm"] }

Quick Start

use modular_agent_core::{AgentError, AgentValue, ModularAgent, ModularAgentEvent};

#[tokio::main]
async fn main() -> Result<(), AgentError> {
    // 1. Initialize
    let ma = ModularAgent::init()?;
    ma.ready().await?;

    // 2. Subscribe to output BEFORE starting (avoid race condition)
    let mut rx = ma.subscribe_to_event(|event| {
        if let ModularAgentEvent::ExternalOutput(name, value) = event {
            if name == "output" { return Some(value); }
        }
        None
    });

    // 3. Load and start preset
    let preset_id = ma.open_preset_from_file("preset.json", None).await?;
    ma.start_preset(&preset_id).await?;

    // 4. Send input / receive output
    ma.write_external_input("input".into(), AgentValue::string("hello")).await?;
    if let Some(value) = rx.recv().await {
        println!("Output: {:?}", value);
    }

    // 5. Cleanup
    ma.stop_preset(&preset_id).await?;
    ma.quit();
    Ok(())
}

Feature Flags

Feature Default Description
file Yes File handling support for presets
image Yes Image processing via photon-rs
llm Yes LLM integration with Message and ToolCall types
mcp Yes Model Context Protocol integration
mcp-server No Built-in MCP server (implies file)
test-utils No Testing utilities

External Agent Editing (MCP Server)

With the mcp-server feature, a host application can expose its running ModularAgent over a localhost MCP endpoint, so external AI agents such as Claude Code can inspect agent definitions, build and edit presets, and verify running flows through natural language.

modular-agent-core = { version = "0.25", features = ["mcp-server"] }
use modular_agent_core::mcp_server::{McpServerConfig, start_mcp_server};

// Serves streamable HTTP at http://127.0.0.1:8765/mcp (localhost only).
let handle = start_mcp_server(
    ma.clone(),
    McpServerConfig {
        port: 8765,
        // Root directory for the save_preset tool; None disables saving.
        presets_dir: Some("/path/to/presets".into()),
        // Required Bearer token; None disables authentication.
        token: Some("secret".into()),
    },
)
.await?;
// ...
handle.stop().await;

Connect from Claude Code:

claude mcp add --transport http modular-agent http://127.0.0.1:8765/mcp \
    --header "Authorization: Bearer secret"

Then ask, for example:

Create a flow that listens to a Slack channel, sends each message to a Chat agent, and posts the reply back to the channel.

The external agent typically calls list_agent_definitions to discover the catalog, then create_presetadd_agent ×4 (Slack Listener, Slack To Message, Chat, Slack Post) → add_connection ×3 → save_preset. It can then verify the flow end to end: start_preset, feed a test value with write_external_input, and poll get_external_outputs / get_agent_errors. Both polling tools return latest_seq — the seq of the last record returned — which the agent passes back as since_seq on the next call to receive only new records; dropped > 0 means the event collector fell behind the broadcast stream and some events were never captured. Separately, the capture buffer keeps only the most recent 200 records per kind, so records not polled in time can age out without affecting dropped. Structure changes emit ModularAgentEvent::PresetStructureChanged so hosts (e.g. modular-agent-desktop) can refresh their UI live. The full tool list (17 tools) covers definitions, preset CRUD, agent/connection editing, config updates, start/stop, and runtime verification.

The server binds 127.0.0.1 only. When token is set, every request must carry an Authorization: Bearer <token> header and is rejected with 401 otherwise; without a token the server is unauthenticated, so enable it deliberately. modular-agent-desktop exposes it via Settings → Core (with an auto-generated token); modular-agent-cli via the --mcp-port <PORT> and --mcp-token <TOKEN> flags.

Documentation

Full API documentation is available at docs.rs/modular-agent-core.

Related Repositories

Applications

Agent Libraries — General

Agent Libraries — Data Sources

Agent Libraries — Databases

Plugins

License

Dual-licensed under Apache 2.0 or MIT.