MCP Hub
Back to servers

acme-mcp

A nested MCP system that demonstrates server composition by using an orchestrator to manage an internal vector store for semantic search. It enables complex, multi-hop retrieval and reasoning over a knowledge base through an agentic reasoning loop.

glama
Updated
Feb 21, 2026

acme-mcp

A two-layer nested MCP (Model Context Protocol) system demonstrating MCP composition — a server that is simultaneously a client to another MCP server.

Architecture

Claude Desktop
     │  (stdio)
     ▼
MCP 2: Orchestrator        ← exposed externally
     │  spawns subprocess
     │  (stdio)
     ▼
MCP 1: Vector Store        ← internal implementation detail

MCP 1 (mcp1_vectorstore) is a low-level in-memory vector store. On startup it embeds 10 Acme Robotics documents via Azure OpenAI, then serves semantic search using numpy cosine similarity. It is never registered with Claude Desktop directly.

MCP 2 (mcp2_orchestrator) is what Claude Desktop connects to. It exposes a single ask tool. When invoked, it runs an agentic reasoning loop using GPT-4.1 via Azure AI Foundry: it decomposes the question into tasks, executes retrieval against MCP 1, and synthesizes a final answer. Independent tasks are dispatched in parallel via asyncio.gather.

Project Structure

src/
├── mcp1_vectorstore/
│   ├── settings.py       # pydantic-settings: endpoint, api_key, embedding deployment
│   └── server.py         # MCP server: search + list_documents tools
└── mcp2_orchestrator/
    ├── settings.py       # pydantic-settings: endpoint, api_key, chat deployment, mcp1 path
    ├── mcp1_client.py    # Subprocess MCP client wrapping MCP 1
    ├── agent.py          # Agentic loop: scratchpad, task planning, parallel search dispatch
    └── server.py         # MCP server: exposes the ask tool to Claude Desktop

Each server has its own settings.py with only the fields it actually uses — MCP 1 owns the embedding deployment, MCP 2 owns the chat deployment and the path to MCP 1.

Setup

1. Install dependencies

uv sync

2. Configure environment

cp .env.example .env

MCP1_SERVER_PATH must be an absolute path — MCP 2 uses it to spawn MCP 1 as a subprocess.

3. Register with Claude Desktop

Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS):

{
  "mcpServers": {
    "acme-orchestrator": {
      "command": "uv",
      "args": ["run", "python", "src/mcp2_orchestrator/server.py"],
      "cwd": "/absolute/path/to/acme-mcp"
    }
  }
}

MCP 1 is not registered here — it is spawned internally by MCP 2.

Tools

MCP 1 tools (internal)

ToolInputOutput
searchquery: str, top_k: int = 3[{doc_id, content, score}]
list_documents[{doc_id, content}]

MCP 2 tool (exposed to Claude Desktop)

ToolInputOutput
askquestion: strsynthesized answer string

Agentic Loop

The agent in agent.py maintains a per-request scratchpad:

{
  "question": str,
  "tasks": [{"id", "description", "status", "depends_on", "result"}],
  "final_answer": str | None
}

The LLM drives the loop using four internal tools: add_task, complete_task, search_knowledge, and finish. Tasks with satisfied dependencies are dispatched concurrently. The loop is hard-capped at 10 iterations.

Test Questions

These questions require multi-hop retrieval over the Acme Robotics knowledge base. The answers are not in any LLM's training data.

Sequential (two-hop):

"Who developed the navigation algorithm used in Acme's flagship product, and what is their academic background?"

Parallel + synthesis:

"Compare Acme's market position: how large is their biggest customer relationship, and how do they stack up against their main competitor?"

Multi-hop stretch:

"What is Acme's growth strategy, and does their current funding support it?"

Reviews

No reviews yet

Sign in to write a review