Semos Agentura¶
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¶
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¶
- Create
packages/semos-agentura-myagent/withpyproject.tomlandsrc/semos/agentura/myagent/ - Add
"semos-agentura-core"as a dependency withworkspace = true - Implement
BaseAgentServiceinservice.py - Add to workspace members in root
pyproject.toml 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:
- Document agent: OCR, image generation, diagram tooling
- Email agent: backend selection, IMAP/SMTP, Outlook, Graph
- Filesystem agent: SharePoint and Google Drive backends
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¶
- File Handling Specification - how files flow between LLMs and tools
- Agent Architecture Reference - patterns, tool system, synthetic tools, protocols
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.