mcp server
agents-mcp-system
Production-grade multi-agent collaboration framework powered by MCP orchestration, Ollama (local LLM), and Streamlit UI
Set up
Runs on your computer. Pick your agent and operating system.
This project does not publish an install method we can turn into a config. Follow the README instead.
README
synced Oct 23, 2026🤖 Agents MCP System
Production-Grade Multi-Agent Collaboration Framework
Powered by Model Context Protocol • Ollama • Streamlit
Executive Summary
Enterprise-grade multi-agent system where four specialized AI agents collaborate through an MCP-inspired orchestration pipeline to solve complex business tasks — research, summarization, strategic planning, and professional reporting — all running locally via Ollama with zero cloud dependency.
The system includes 6 free MCP tool connectors (file system, web search, SQLite database, ChromaDB vector store, date/time, calculator) that agents can invoke to access external resources during execution.
Enter a business query (e.g., "Generate a compliance summary for HR policies") and watch agents collaboratively produce a polished, executive-ready report in real time through the Streamlit UI.
Architecture
┌─────────────────────┐
│ User Query │
└──────────┬──────────┘
│
▼
┌──────────────────────────────────┐
│ Streamlit UI │
│ (app.py) │
│ • Task input & model config │
│ • Real-time pipeline viz │
│ • Markdown / PDF export │
└──────────────┬───────────────────┘
│
▼
┌──────────────────────────────────┐
│ MCP Orchestrator │
│ (orchestrator.py) │
│ • Pipeline sequencing │
│ • Shared AgentContext protocol │
│ • Tool Manager integration │
│ • Logging & error recovery │
└──────────────┬───────────────────┘
│
┌────────────────────┼────────────────────┐
│ │ │
▼ ▼ ▼
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ Agent Layer │ │ Tool Manager │ │ Ollama Client │
│ │ │ (tool_manager) │ │ (ollama_client) │
│ 🔍 Researcher │ │ │ │ │
│ 📋 Summarizer │◄─┤ Connector Pool: │ │ • chat() │
│ 📐 Planner │ │ 📁 FileSystem │ │ • embed() │
│ 💼 Communicator │ │ 🌐 WebSearch │ │ • health_check() │
└──────────────────┘ │ 🗄️ SQLite DB │ │ • list_models() │
│ 🧠 ChromaDB │ └──────────┬────────┘
│ 🕐 DateTime │ │
│ 🧮 Calculator │ ▼
└──────────────────┘ ┌──────────────────┐
│ Ollama Server │
│ (Local LLM) │
│ llama3 · mistral │
│ gemma · phi3 │
└──────────────────┘
Step-by-Step Flow: How Agents Interact with MCP
This section walks through exactly what happens when you submit a task, from UI input to final report.
Step 1: Task Submission
User types: "Generate a compliance summary for HR policies"
→ Clicks "🚀 Execute Pipeline"
The Streamlit UI (app.py) captures the task and instantiates the MCPOrchestrator.
Step 2: Orchestrator Initialization
orchestrator = MCPOrchestrator() # Loads config.yaml
# What happens inside:
# 1. Parses config.yaml → agent configs + tool configs
# 2. Creates OllamaClient(base_url, timeout)
# 3. Creates ToolManager → instantiates enabled connectors
# 4. Creates agent instances in pipeline order:
# [ResearcherAgent, SummarizerAgent, PlannerAgent, CommunicatorAgent]
Step 3: Pipeline Execution Begins
context = AgentContext(task="Generate a compliance summary...")
# context holds: task, messages=[], artifacts={}, tool_results={}
The orchestrator creates a shared AgentContext — this is the MCP-inspired "context protocol" that accumulates state as it flows through agents.
Step 4: Research Agent Executes
┌─────────────────────────────────────────────────────────┐
│ 🔍 Research Agent │
│ │
│ 1. Receives: AgentContext(task="Generate a compliance…")│
│ 2. Builds prompt: │
│ system: "You are a Research Agent specializing in…" │
│ user: "Research the following topic thoroughly…" │
│ 3. Calls: ollama_client.chat(model="llama3", messages) │
│ 4. Receives: ChatResponse(content="…findings…") │
│ 5. Appends to context: │
│ → context.messages += Message(role="agent", …) │
│ → context.artifacts["Research Agent"] = "…findings…" │
│ 6. Yields: ("researcher", message) → UI updates │
└─────────────────────────────────────────────────────────┘
Step 5: Summarizer Agent Executes
┌─────────────────────────────────────────────────────────┐
│ 📋 Summarizer Agent │
│ │
│ 1. Receives: AgentContext with research artifacts │
│ 2. Reads: context.artifacts["Research Agent"] │
│ 3. Builds prompt: │
│ system: "You are a Summarizer Agent…" │
│ user: "Summarize these findings… [research output]" │
│ 4. Calls Ollama → gets condensed summary │
│ 5. Appends: context.artifacts["Summarizer Agent"] = … │
│ 6. Yields → UI shows summarizer output │
└─────────────────────────────────────────────────────────┘
Step 6: Planner Agent Executes
┌─────────────────────────────────────────────────────────┐
│ 📐 Planner Agent │
│ │
│ 1. Receives: AgentContext with summary artifacts │
│ 2. Reads: context.artifacts["Summarizer Agent"] │
│ 3. Creates: structured action plan with priorities │
│ 4. Appends: context.artifacts["Planner Agent"] = … │
└─────────────────────────────────────────────────────────┘
Step 7: Communicator Agent Produces Final Report
┌─────────────────────────────────────────────────────────┐
│ 💼 Communicator Agent │
│ │
│ 1. Receives: AgentContext with ALL prior outputs │
│ 2. Reads: context.get_conversation_history() │
│ → concatenates all agent contributions │
│ 3. Synthesizes: polished executive report │
│ 4. Output includes: │
│ • Executive Summary │
│ • Key Findings │
│ • Action Items │
│ • Next Steps │
└─────────────────────────────────────────────────────────┘
Step 8: Export & Display
Pipeline complete!
├── 📄 Report Tab → rendered Markdown
├── 📥 Download Markdown → report_20240615_143022.md
├── 📑 Download PDF → report_20240615_143022.pdf
└── 📋 Logs Tab → timestamped execution log
How MCP Tool Connectors Work
Agents can leverage MCP tool connectors to access external resources. The ToolManager loads enabled connectors from config.yaml and makes them available to the orchestration pipeline.
Tool Invocation Flow
Agent needs data
│
▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Agent asks │────▶│ ToolManager │────▶│ Connector │
│ for tool │ │ routes call │ │ executes │
│ execution │ │ │ │ │
└──────────────┘ └──────────────┘ └──────┬───────┘
│
┌──────────────────────────────────────────┘
▼
┌──────────────┐
│ ToolResult │ → success, output, metadata
│ returned to │ → injected into AgentContext
│ agent │ → available to downstream agents
└──────────────┘
Available Connectors (All Free)
| Connector | What It Does | Dependencies | API Key |
|---|---|---|---|
| 📁 FileSystem | Read, list, and search files in a sandboxed directory | pathlib (built-in) | None |
| 🌐 WebSearch | Query DuckDuckGo Instant Answer API for web results | requests | None |
| 🗄️ SQLite DB | Run read-only SQL queries against a local database | sqlite3 (built-in) | None |
| 🧠 ChromaDB | Semantic similarity search over document embeddings | chromadb>=0.4.22 | None |
| 🕐 DateTime | Current time, timezone conversion, date arithmetic | datetime (built-in) | None |
| 🧮 Calculator | Safe math expression evaluation (no eval()) | ast (built-in) | None |
Connector Configuration
All connectors are configured in config.yaml:
tools:
filesystem:
enabled: true
params:
base_dir: "data"
web_search:
enabled: true
params: {}
database:
enabled: true
params:
db_path: "data/knowledge.db"
vector_store:
enabled: true
params:
collection_name: "mcp_knowledge"
persist_dir: "data/chroma"
datetime:
enabled: true
params: {}
calculator:
enabled: true
params: {}
Security Features
- FileSystem: Sandboxed to
data/directory — path traversal attempts are blocked - SQLite: Read-only access — only
SELECTqueries allowed;DROP,INSERT,UPDATErejected - Calculator: AST-based evaluation — no
eval(), no code injection, exponent limit enforced - WebSearch: Uses only the public DuckDuckGo API — no credentials stored
Agents
| Agent | Role | What It Does |
|---|---|---|
| 🔍 Research Agent | Information Gathering | Investigates the topic with comprehensive analysis, facts, and data points |
| 📋 Summarizer Agent | Knowledge Distillation | Condenses research into concise, actionable insights with clear structure |
| 📐 Planner Agent | Strategic Planning | Organizes insights into workflows with priorities, timelines, and dependencies |
| 💼 Communicator Agent | Executive Reporting | Synthesizes all outputs into a polished, presentation-ready report |
All agents are config-driven — model, temperature, system prompt, and token limits are defined in config.yaml.
Features
- MCP-Inspired Orchestration — protocol-based agent communication with shared context accumulation
- 6 Free MCP Tool Connectors — file system, web search, SQLite, ChromaDB, datetime, calculator
- Local LLM Inference — fully offline via Ollama (llama3, mistral, gemma, phi3)
- Real-Time Pipeline Visualization — watch agents collaborate step-by-step in the Streamlit UI
- Export — download final reports as Markdown or PDF
- Config-Driven Architecture — YAML-based agent + tool definitions, no hardcoded paths
- Docker-Ready — single-command deployment with Docker Compose
- Comprehensive Test Suite — 71 tests covering agents, orchestrator, and all connectors
- Security-First — sandboxed file access, read-only SQL, safe math evaluation
- Structured Logging — timestamped session logs for debugging and audit
Repository Structure
agents-mcp-system/
├── app.py # Streamlit UI — task input, pipeline viz, export
├── orchestrator.py # MCP orchestration engine — pipeline + context
├── ollama_client.py # Ollama REST API wrapper — chat, embed, health
├── tool_manager.py # Tool connector registry and lifecycle manager
├── utils.py # Logging, file storage, PDF export helpers
├── config.yaml # Agent + tool configuration (YAML)
├── requirements.txt # Pinned Python dependencies
├── Dockerfile # Multi-stage container build
├── docker-compose.yml # Ollama + App orchestration
├── agents/
│ ├── __init__.py # Agent registry
│ ├── base.py # BaseAgent ABC + Message/AgentContext protocol
│ ├── researcher.py # Research Agent implementation
│ ├── summarizer.py # Summarizer Agent implementation
│ ├── planner.py # Planner Agent implementation
│ └── communicator.py # Communicator Agent implementation
├── connectors/
│ ├── __init__.py # Connector package exports
│ ├── base.py # MCPTool ABC + ToolResult dataclass
│ ├── filesystem.py # 📁 File system connector (sandboxed)
│ ├── websearch.py # 🌐 DuckDuckGo web search connector
│ ├── database.py # 🗄️ SQLite database connector (read-only)
│ ├── vectorstore.py # 🧠 ChromaDB vector store connector
│ ├── datetime_tool.py # 🕐 Date/time utilities connector
│ └── calculator.py # 🧮 Safe math expression evaluator
├── tests/
│ ├── test_agents.py # Agent unit tests (15 tests)
│ ├── test_orchestrator.py # Orchestrator unit tests (11 tests)
│ └── test_connectors.py # Connector + ToolManager tests (45 tests)
├── sample_tasks/
│ ├── compliance_summary.txt # Sample: HR compliance analysis
│ └── strategy_plan.md # Sample: Go-to-market strategy
├── data/ # Tool data directory (sandboxed)
├── outputs/ # Generated reports (git-ignored)
└── logs/ # Session logs (git-ignored)
Prerequisites
| Component | Version | Installation |
|---|---|---|
| Python | 3.11+ | python.org |
| Ollama | Latest | ollama.ai |
| Docker | 24+ | docker.com (optional) |
Quick Start
1. Clone and Install
git clone https://github.com/maneeshkumar52/agents-mcp-system.git
cd agents-mcp-system
python -m venv .venv
source .venv/bin/activate # macOS/Linux
# .venv\Scripts\activate # Windows
pip install -r requirements.txt
2. Start Ollama
# Terminal 1 — start the Ollama server
ollama serve
# Terminal 2 — pull a model (one-time)
ollama pull llama3
3. Launch the Application
streamlit run app.py
Open http://localhost:8501 → enter a task → watch agents collaborate → download the report.
Docker Deployment
Single Container
docker build -t agents-mcp-system .
docker run -p 8501:8501 \
-e OLLAMA_BASE_URL=http://host.docker.internal:11434 \
agents-mcp-system
Full Stack (Ollama + App)
docker compose up -d
# Pull a model into the containerized Ollama
docker compose exec ollama ollama pull llama3
# Open http://localhost:8501
Configuration
All agent behavior is controlled via config.yaml:
ollama:
base_url: "http://localhost:11434"
default_model: "llama3"
timeout: 120
agents:
researcher:
name: "Research Agent"
model: "llama3"
temperature: 0.3
max_tokens: 2048
system_prompt: |
You are a Research Agent specializing in ...
orchestration:
pipeline: [researcher, summarizer, planner, communicator]
Customization options:
- Change
modelper agent to use different LLMs for different tasks - Adjust
temperaturefor creativity vs. precision trade-offs - Modify
system_promptto specialize agents for your domain - Reorder or remove agents from the
pipelinelist
Running Tests
# Run the full test suite (71 tests)
pytest tests/ -v
# Run with coverage
pytest tests/ -v --tb=short
The test suite uses mocked Ollama responses — no running Ollama instance required for testing.
Usage Examples
Compliance Analysis
Task: "Generate a comprehensive compliance summary for enterprise HR policies
covering GDPR, workplace safety, and anti-discrimination regulations."
Go-to-Market Strategy
Task: "Develop a Q3 go-to-market strategy for launching an AI-powered customer
support platform targeting mid-market SaaS companies."
Technical Architecture Review
Task: "Evaluate the microservices architecture of our e-commerce platform and
recommend improvements for scalability and reliability."
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
ConnectionError: Cannot reach Ollama | Ollama not running | Run ollama serve in a separate terminal |
Model not found | Model not pulled | Run ollama pull llama3 (or your chosen model) |
config.yaml not found | Wrong working directory | Run streamlit run app.py from the project root |
| Slow responses | Large model on limited hardware | Switch to a smaller model (phi3, gemma:2b) in config.yaml |
| PDF export unavailable | fpdf2 not installed | Run pip install fpdf2 |
Production Checklist
- Pin Ollama model versions for reproducibility
- Configure log rotation for
logs/directory - Set up output archival for
outputs/directory - Enable HTTPS via reverse proxy (nginx/Caddy) in production
- Add authentication middleware for multi-user deployments
- Monitor Ollama GPU/memory usage for capacity planning
- Back up
config.yamlin version control - Review tool connector permissions (file access scope, SQL query limits)
- Populate the vector store with domain-specific documents
- Configure DuckDuckGo rate limiting for high-traffic deployments
Adding Custom Connectors
Create a new connector by extending MCPTool:
from connectors.base import MCPTool, ToolResult
class MyCustomTool(MCPTool):
@property
def name(self) -> str:
return "my_tool"
@property
def description(self) -> str:
return "Description shown to agents in their system prompt"
def execute(self, **kwargs) -> ToolResult:
# Your tool logic here
return ToolResult(tool_name=self.name, success=True, output="result")
Then register it in tool_manager.py:
TOOL_REGISTRY["my_tool"] = MyCustomTool
And add config in config.yaml:
tools:
my_tool:
enabled: true
params: {}
License
This project is licensed under the MIT License — see LICENSE for details.