Skip to content

Semos Agentura

CI codecov License Python DOI

A modular multi-agent system for professional and scientific workflows, built on open protocols - MCP (Model Context Protocol) and A2A (Agent-to-Agent Protocol).

Principles

Sovereign architecture. Every agent is an independent service with its own deployment, lifecycle, and data. No central runtime owns agent state. Agents communicate exclusively through standardized protocols - never through shared memory, databases, or framework internals. An organization can host its own agents on its own infrastructure, choose its own LLM providers, and retain full control over data flow.

Federated by design. Agents are discovered via A2A Agent Cards and connected via protocol, not configuration. A new agent joins the system by publishing its capabilities - no central registry to update, no monolith to redeploy. This extends across organizational boundaries: a partner institution can expose its own agents over A2A without granting access to its internal systems.

Modular composition. Each agent encapsulates a single domain and exposes it as MCP tools (for LLM-driven use) and A2A skills (for programmatic workflows). The shared semos-agentura-core library provides only protocol wiring - no business logic, no framework lock-in. Agents are plain Python packages that work standalone, with or without the multi-agent layer.

Open standards, no vendor lock-in. MCP and A2A are both Linux Foundation standards (under AAIF) with multi-vendor support. LLM providers are interchangeable via litellm. Agents run as standard HTTP services - deployable with uvicorn, Docker, Kubernetes, or any infrastructure.

Research-grade extensibility. The system is designed for scientific and engineering environments where workflows evolve rapidly. Adding a new capability means adding a new agent - not modifying existing ones.

Components

Core Infrastructure

Component Description Status
semos-agentura-core Shared framework: BaseAgentService, MCP+A2A transport, file middleware, LLMExecutor (universal agentic loop), reference client (AgenturaClient) Done
Virtual Filesystem Unified API for local, WebDAV, SharePoint, and in-memory backends via fsspec. Single namespace for all file operations. Done
File Middleware Symmetric LLM file handling: the LLM only sees symbolic filenames. Client middleware resolves names to base64/URL on input, fetches download URLs and registers files on output. Based on the Virtual Filesystem. Done
Orchestrator Multi-session manager that can run independently in background. Operates on the virtual filesystem, maintains task lists and memory, spawns sub-agents. Email and UI are message paths into shared sessions. In work

User Interfaces

Component Description Status
Agentura UI Multi-session, multi-model chat UI. Visualizes orchestrator state and is itself one message path into the orchestrator. Built on panelini. Partial
Email Agent (as channel) Second message path: incoming emails create/resume orchestrator sessions, replies go back via email. Uses @mailgent tagging. Partial

Specialist Agents

Agent Description Status
Filesystem Agent File operations on the Virtual Filesystem: read, write, edit, copy, move, search, glob, archive browsing across all backends. Done
Document Agent Non-plaintext document processing: OCR digest (PDF, images, Office), compose (Markdown to PDF/PPTX/DOCX/HTML), diagram generation (Mermaid, draw.io), form inspection and filling (PDF/DOCX). Done
Email Agent Email and calendar operations: search, read, draft, reply, send. Calendar events and free slot computation. Backends: IMAP/SMTP, Outlook COM, MS Graph API. Done
Browser Agent Web-based retrieval and website automation via Playwright. Visual navigation, data extraction, form filling on live websites. Planned
Coding Agent Write and execute program code. File exchange via file middleware. Code review, test generation. Planned
Knowledge Agent Long-term memory with retrieve, patch, and auto-consolidation. Based on Object-Oriented Linked Data (OO-LD). Knowledge graph with semantic search. Planned

Each agent's README lists its current tool set.

Architecture

Architecture

Editable source: docs/architecture.drawio

Each agent is a FastAPI app exposing both protocols:

  • MCP at /mcp/sse - LLM selects and calls agent tools (tool-use pattern)
  • A2A at /a2a (REST) and /a2a/rpc (JSON-RPC) - agents invoke each other or receive delegated tasks with full task lifecycle

How It Compares

Semos Agentura OpenClaw / NemoClaw LibreChat LangGraph / CrewAI
Model Independent agents, protocol-connected One agent, many plugins (skills) Chat UI with tool integrations Framework-managed agent graphs
Agent independence Each agent is its own service, deployment, repo Plugins run inside a single process N/A (not an agent system) Agents are nodes in a framework runtime
Protocol MCP + A2A (open standards) Proprietary skill API; MCP/A2A via community plugins MCP client only Framework-internal; MCP via integration
LLM control Bring your own (any provider via litellm) Configurable per agent Configurable per chat Configurable but framework-coupled
Data sovereignty Full - agents run on your infra, no shared state Partial - plugins share the agent's process/memory Full (self-hosted) Depends on deployment
Federation Native - agents discover each other via A2A Agent Cards No - single-instance No - single-instance No
File handling Symmetric middleware (spec), LLM never sees binary Via plugin Not solved for MCP tools Framework-dependent
Best for Multi-domain professional/scientific automation Personal AI assistant Multi-provider chat UI Prototyping complex agent workflows

Why not just use OpenClaw? OpenClaw is a personal assistant - one agent with plugins. Agentura is a distributed system - independent agents that can run on different machines, be developed by different teams, and communicate over standard protocols. OpenClaw could serve as a future chat frontend (via A2A) to the Agentura backend.

Why not just use LibreChat? LibreChat is a chat UI, not an agent system. We use it for MCP testing. It connects to our agents as an MCP client, but it doesn't orchestrate multi-agent workflows, handle agent-to-agent communication, or manage file transfer between tools.

Why not LangGraph/CrewAI? These frameworks are designed for building new agents from scratch. Our agents already exist with clean APIs. Wrapping them with standard protocols (MCP + A2A) is simpler and preserves their independence - no framework runtime to adopt, no vendor lock-in.

Quick Start

# Prerequisites: Python 3.11+, uv
# Install: https://docs.astral.sh/uv/getting-started/installation/

# Install all workspace packages
uv sync --all-packages

# Start all agents + UI
uv run python run_local.py

# Or run individual agents
uv run uvicorn semos.agentura.email.service:app --port 8001
uv run uvicorn semos.agentura.document.service:app --port 8002

Endpoints per Agent

Endpoint Protocol Description
GET /health HTTP Health check
GET /mcp/sse MCP SSE stream for MCP clients (Claude Desktop, etc.)
POST /mcp/messages/ MCP Tool call messages
GET /.well-known/agent-card.json A2A Agent Card (capabilities, skills)
POST /a2a A2A REST endpoint (HTTP+JSON)
POST /a2a/rpc A2A JSON-RPC endpoint

Connect from Claude Desktop

{
  "mcpServers": {
    "semos-agentura-email": { "url": "http://localhost:8001/mcp/sse" },
    "semos-agentura-document": { "url": "http://localhost:8002/mcp/sse" }
  }
}

Adding a New Agent

  1. Create packages/semos-agentura-myagent/ with pyproject.toml and src/semos/agentura/myagent/
  2. Add "semos-agentura-core" as a dependency with workspace = true
  3. Implement BaseAgentService in service.py
  4. Add to workspace members in root pyproject.toml
  5. uv sync --all-packages
from semos.agentura.core import (
    AgentTool, BaseAgentService, SkillDef, agent_tool, create_app,
)

@agent_tool(read_only=True)
async def my_tool(param: str) -> str:
    """Does something useful with param."""
    return f"Result: {param}"

class MyAgentService(BaseAgentService):
    @property
    def agent_name(self) -> str:
        return "My Agent"

    @property
    def agent_description(self) -> str:
        return "Does something useful."

    def get_tools(self) -> list[AgentTool]:
        return [my_tool]

    def get_skills(self) -> list[SkillDef]:
        return [SkillDef(id="my-skill", name="My Skill", description="...")]

    async def execute_skill(self, skill_id, message, *, task_id=None) -> str:
        return "result"

app = create_app(MyAgentService())

Configuration

Each agent loads .env from its own directory, falling back to the workspace root .env for shared keys.

semos-agentura/
  .env                    # Shared: ANTHROPIC_API_KEY, AZURE_API_KEY, ...
  packages/semos-agentura-email/.env       # IMAP_HOST, EMAIL_ADDRESS, ...
  packages/semos-agentura-document/.env    # DOCUMENT_AI_*, DIAGRAM_CODEGEN_*, ...
  packages/semos-agentura-ui/config.yml    # LLM provider config (see config.example.yml)

Environment variables

Agent discovery (all optional, defaults shown):

Variable Default Purpose
SEMOS_AGENTURA_EMAIL_BASE / _URL http://localhost:8001 Email agent base URL / MCP SSE endpoint
SEMOS_AGENTURA_DOCUMENT_BASE / _URL http://localhost:8002 Document agent base URL / MCP SSE endpoint
SEMOS_AGENTURA_FILES_BASE / _URL http://localhost:8003 Filesystem agent base URL / MCP SSE endpoint
SEMOS_AGENTURA_FILES_PORT 8003 Port for the in-process filesystem agent
EXTRA_AGENTS - Additional agents, name:port,name:port

Runtime:

Variable Default Purpose
AGENT_HOST / AGENT_PORT 127.0.0.1 / 8000 Bind address per agent
LOG_LEVEL INFO Log verbosity
ROUTER_LLM_MODEL / _API_KEY / _API_BASE - Optional per-agent LLM router for natural-language A2A requests

Agent-specific keys (LLM endpoints, mail servers, storage credentials) are documented by the agent that reads them:

Protocols

MCP (Model Context Protocol)

Used when an LLM decides which tool to call. The orchestrator's LLM sees all agent tools and selects the right one based on the user's request. Tools return normalized results (str, dict, Path, file-like objects are all auto-converted to CallToolResult with ResourceLink and structuredContent).

A2A (Agent-to-Agent Protocol)

Used for high-level delegation - the requesting LLM sends a natural language task to an agent's LLM, which plans and executes it using its own tools. Also used for deterministic pipelines and cron workflows (no LLM needed).

Each agent exposes dual A2A bindings: REST (/a2a) and JSON-RPC (/a2a/rpc). The LLMExecutor in semos-agentura-core provides the universal agentic loop with 5 synthetic tools (request_input, return_result, report_progress, reject_task, request_auth) that map to A2A task states.

Both protocols are served by every agent. The caller picks which one to use.

Testing

# CI tests (no external deps - mocked backends, no LLM/COM/pandoc)
cd packages/semos-agentura-core && uv run pytest tests/ -m "not integration"
cd packages/semos-agentura-email && uv run pytest tests/ -m "not integration"
cd packages/semos-agentura-document && uv run pytest tests/ -m "not integration"
cd packages/semos-agentura-files && uv run pytest tests/ -m "not integration"

# Integration tests (needs real backends)
uv run pytest -m integration

Pre-commit hook enforces ruff lint + format.

Documentation

License

Dual-licensed. The core infrastructure is open source, specialized agents may be commercial.

Component License
semos-agentura-core Apache 2.0
semos-agentura-ui Apache 2.0
semos-agentura-email Apache 2.0
semos-agentura-document Apache 2.0
semos-agentura-files Apache 2.0
Future specialized agents May be commercial (per-agent license)

See LICENSE for the full Apache 2.0 text. Individual agents may override with their own license file.