stationery-inventory
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@stationery-inventoryDo we have the Under the Sea picture book in stock?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Stationery Inventory MCP Server — Phase 0
One tool, one dataset, one job: prove Claude can call real code and get real data back. Everything here was actually run and tested before being handed to you — not just written and assumed to work.
Files
server.py— the MCP server. One tool:check_stationery_inventory.inventory_data.csv— sample product data (edit freely; the server reads it fresh on every call, so changes show up immediately).audit_log.jsonl— created automatically on first tool call. One JSON line per call: timestamp, tool name, input, output.requirements.txt— pinned dependency.
Related MCP server: Alegra MCP
A version gotcha worth knowing (we hit this so you don't have to)
The MCP Python SDK went through a breaking rename: FastMCP (v1.x, what
most tutorials online still show) became MCPServer (v2.x, what pip install mcp gives you today). This server uses the current v2 API:
from mcp.server.mcpserver import MCPServer
mcp = MCPServer("stationery-inventory")If you ever copy MCP server code from an older tutorial and get
ModuleNotFoundError: No module named 'mcp.server.fastmcp', this is why.
Setup
cd stationery-mcp-server
python3 -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txtTest it interactively before wiring it into Claude (recommended first)
The SDK ships an inspector UI for exactly this:
mcp dev server.pyThis opens a local web UI where you can call check_stationery_inventory
directly and see the raw request/response — confirm it works here before
adding the complexity of a full Claude conversation.
Wire it into Claude Desktop
Edit your Claude Desktop config file:
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.json
Add (using the absolute path to this folder's server.py, and the
absolute path to the python inside your venv):
{
"mcpServers": {
"stationery-inventory": {
"command": "/absolute/path/to/stationery-mcp-server/venv/bin/python",
"args": ["/absolute/path/to/stationery-mcp-server/server.py"]
}
}
}Restart Claude Desktop fully (quit, not just close the window). Then ask it something like:
"Do we have the Under the Sea picture book in stock?"
If wired correctly, Claude will call the tool and answer from the real CSV data — including telling you it's out of stock (SKU BK-CH-002 is intentionally set to 0 in the sample data, to test that path).
Wire it into Claude Code
claude mcp add stationery-inventory -- /absolute/path/to/venv/bin/python /absolute/path/to/server.pyThen claude mcp list to confirm it's registered.
What "done" looks like for Phase 0
mcp dev server.pyreturns correct results for an in-stock item, an out-of-stock item, and a misspelled/partial product name.Claude Desktop or Claude Code can call the tool in a live conversation and give a correct answer.
audit_log.jsonlhas one entry per call, with sane input/output.
Deliberately NOT in scope for Phase 0
A real database or live inventory API (CSV is fine for now)
Multiple tools (add
check_order_statusetc. only after this one is solid)Remote deployment / auth beyond local stdio
An orchestration framework on top
Each of those is a later module — adding them now would dilute the one thing Phase 0 is meant to prove: the full loop works.
Module 2: a real deployed agent (agent.py)
Phase 0 proved Claude inside Claude Desktop/Code can call your tool. Module 2 proves you can ship an independent, scriptable agent — the "one deployed agent" gap called out in your roadmap notes — built on the Claude Agent SDK, using this same MCP server as its only tool.
Additional setup
npm install -g @anthropic-ai/claude-code # the CLI the SDK runs underneath
pip install claude-agent-sdk
export ANTHROPIC_API_KEY=your-key-hereWhy the npm install is needed even for a Python project: the Claude
Agent SDK (Python or TypeScript) is a thin wrapper around the Claude Code
CLI — it spawns that CLI as a subprocess to run the actual agent loop. If
you skip this step you'll hit CLINotFoundError the moment you run
agent.py. Confirm it worked with claude --version.
Design choice: narrow scope on purpose
agent.py restricts allowed_tools to exactly one tool —
mcp__stationery-inventory__check_stationery_inventory — and the system
prompt explicitly refuses anything outside stock/pricing questions. This
isn't a limitation to fix later; it's the point. Your notes cite a
benchmark where a policy-constrained, tool-scoped agent hit 110/110
successful runs, while a fully autonomous version of the same task failed
all 330 attempts. Every additional tool or open-ended instruction you add
is a branch point where the agent can go wrong — add them deliberately,
one at a time, not by default.
Run it
python agent.py "Is the Spiral Notebook A5 in stock?"
python agent.py # interactive mode, 'quit' to exitRun the eval harness (eval.py)
Five test cases checking two things that actually matter for a production agent — not "did it sound plausible":
Did it actually call the tool, or hallucinate an answer?
Does the final answer contain the fact you know is true from the CSV?
python eval.pyThis is a deliberately small seed of Module 5 (evaluation/observability) from your roadmap — introduced now because retrofitting eval discipline onto an agent later costs far more than building the habit from agent #1.
What we verified before handing this to you (and what we couldn't)
Tested in this environment, without a real API key:
The SDK's exact API surface (
ClaudeAgentOptions,query, message types) matches what the code uses — checked against the installed package, not assumed from memory.The Claude Code CLI dependency is real and required — confirmed via
CLINotFoundErrorexisting in the SDK and installing the CLI to resolve it.The full pipeline — CLI spawn → MCP subprocess launch → tool discovery → API call — works end to end. With a placeholder key, the session initialized, the MCP server showed
status: connected, and the tool registered as exactlymcp__stationery-inventory__check_stationery_inventory, confirming the wiring is correct up to the authentication boundary.
Not tested here (needs your real key, on your machine):
An actual model response and tool call with real data
The
eval.pypass/fail results
Run eval.py first thing after setup — if all 5 cases pass, Module 2 is
done.
Module 3: tool-scoped subagents (orchestration/)
Module 2 proved one deployed agent (agent.py) can call this server's
single tool. Module 3 proves the same MCP server can sit underneath
multiple delegated subagents instead of one flat agent — each subagent
scoped to the minimum tools it needs, using the Claude Agent SDK's native
AgentDefinition/Agent tool primitives (no LangGraph or other
orchestrator here — that comparison is Module 4, see
learning-notes/module-3-native-subagents-vs-langgraph.md... [see note below]).
inventory-checker— the only agent allowed to call this server'scheck_stationery_inventorytool.order-status— read-only, calls a separate mock orders tool (orchestration/tools/orders_server.py; swap for a real order source later).refund-calculator— zero tools. Computes only from what the parent agent supplies in its prompt; cannot look anything up or issue anything. This is the access-control pattern this module is meant to demonstrate.
Additional setup
pip install -r orchestration/requirements.txtReuses the claude-agent-sdk and CLI dependency already installed for
Module 2 — no new external tooling needed.
Run it
cd orchestration
python run_orchestrator.py --dry-run # no API key needed
python run_orchestrator.py # live, needs ANTHROPIC_API_KEYWhat "done" looks like for Module 3
--dry-runpasses and resolves the real path to../server.pyA live run routes an inventory question to
inventory-checkerand gets a real answer from this server's CSVA live run routes an order question to
order-statusA live run routes a refund question to
refund-calculator, which computes a number without calling any toolOne explicit-invocation prompt ("Use the X agent...") works
Deliberately NOT in scope for Module 3
Real order data (still a mock tool)
A cross-provider orchestrator (LangGraph — that's the next module)
Actually issuing a refund (compute-only, by design)
This server cannot be deployed
Maintenance
Related MCP Connectors
Streamline your Attio workflows using natural language to search, create, update, and organize com…
Search inventory items and folders, low-stock alerts, jobs and purchase orders, and update stock.
Open, inspect, filter, edit and convert xlsx and csv files from your AI chat. Processing is local.
Open, inspect, filter, edit and convert xlsx and csv files from your AI chat. Processing is local.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables Claude Desktop to manage office inventory through natural language, including adding items, issuing stock, checking availability, and low-stock alerts.-
- FlicenseNot gradedqualityDmaintenanceEnables querying and managing Alegra inventory and products through natural language, including stock checks and product searches.-
- FlicenseNot gradedqualityBmaintenanceEnables natural-language shopping queries on a fashion inventory flat file, with tools for searching products and recommending matching items via OpenAI.-
- FlicenseNot gradedqualityCmaintenanceEnables querying sales data, identifying out-of-stock products, viewing top sellers, and receiving restock suggestions through natural language.-