business-tools
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., "@business-toolsRefund $45 on order O00012, customer got the wrong item"
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.
MCP server for business tools
A Model Context Protocol server that lets Claude and other AI assistants work with a company's order system: look up customers, orders and stock, and take real actions such as creating an order or requesting a refund.
It is for teams that want an assistant to do routine operations work but cannot hand a language model a database password. Every API key has a role, the business rules are enforced in code, and every call is written to an audit log that shows if anyone edits it afterwards.
What it does
Offers 13 tools over MCP: six that read (customers, products and stock, orders, sales figures, the audit log) and seven that act (customer note, create order, change order status, request and decide refunds, adjust stock).
Works over both MCP transports: stdio for desktop assistants, and HTTP with a bearer token for remote or shared use.
Gives each API key one of three roles. A key sees and can call only the tools of its role.
Masks customer email and phone for roles that may not read them.
Enforces the business rules in code: an order moves only along allowed steps, refunds never exceed what was paid, large refunds wait for a manager, nobody decides their own refund.
Writes one audit record per call, allowed or refused. Records are chained by hash, so an edited or deleted record is detected.
Accepts an idempotency key on every action, so a retried call does not act twice.
Returns errors as structured results with a code and a plain message, so the assistant can correct itself.
Includes a demo agent and an evaluation script. Everything runs with no API key.
Related MCP server: ParcelPilot MCP Server
How it works
flowchart TD
A[AI assistant<br/>Claude Desktop, Claude Code,<br/>or the demo agent] -->|MCP over stdio<br/>key in the environment| S
A2[Remote assistant or service] -->|MCP over HTTP<br/>Authorization: Bearer key| B[Bearer check<br/>401 without a valid key]
B --> S[MCP server<br/>server.py]
S -->|tools/list| F[Tool list filtered by role]
S -->|tools/call| G
subgraph G[Gateway: the single path for every call]
direction TB
G1[1. Rate limit per key] --> G2[2. Permission of the role]
G2 --> G3[3. Arguments validated<br/>with Pydantic]
G3 --> G4[4. Idempotency key<br/>already used?]
G4 --> G5[5. Tool runs in one transaction<br/>business rules first]
end
G5 --> D[(SQLite<br/>customers, products,<br/>orders, refunds)]
G -->|every call: ok, denied or error| L[(Audit log<br/>hash-chained)]
G -->|result, or error with code and message| AThe MCP layer (server.py) only translates protocol messages. All rules live in the gateway
(gateway.py) and the tools, which is why they are tested both directly and through MCP.
Tools and roles
Output of python -m business_mcp tools:
tool kind permission viewer agent manager
search_customers read customers:read yes yes yes
get_customer read customers:read yes yes yes
search_products read products:read yes yes yes
get_order read orders:read yes yes yes
list_orders read orders:read yes yes yes
sales_summary read reports:read yes yes yes
read_audit_log read audit:read - - yes
add_customer_note action customers:write - yes yes
create_order action orders:write - yes yes
update_order_status action orders:write - yes yes
request_refund action refunds:request - yes yes
decide_refund action refunds:approve - - yes
adjust_stock action inventory:write - - yesThe server also publishes two resources (business://policies, generated from the same tables
the gateway enforces, and business://schema) and two prompts (daily_briefing, review_refund).
Real output
The demo agent asks for a refund above the agent's limit. The server stores it as pending and tells the assistant what to say:
$ python -m business_mcp demo "Refund \$300 on order O00012 because the wrong items were sent"
Connected to business-tools over stdio. 10 tools offered to this key. Provider: mock.
Task: Refund $300 on order O00012 because the wrong items were sent
1. get_order({"order_id": "O00012"})
-> {"id": "O00012", "customer_id": "C0011", "status": "delivered", "total": 453.1, "created_at": "2026-04-10T13:14:00Z", "customer_name": "Jonas Petrov", "company": "Granite Bookshop", "lines": [{"product_id": "P029", "name...
2. request_refund({"order_id": "O00012", "amount": 300.0, "reason": "the wrong items were sent"})
-> {"refund_id": "R0001", "order_id": "O00012", "amount": 300.0, "status": "pending", "message": "Waiting for a manager: the amount is above your limit of 100. Tell the customer the refund is under review, not that it is do...
Answer: Refund R0001 of $300.00 on order O00012 is pending. Waiting for a manager: the amount is above your limit of 100. Tell the customer the refund is under review, not that it is done.The same kind of request with a read-only key. The action tool is not even offered:
$ python -m business_mcp demo "Mark order O00300 as shipped" --key demo-viewer-key
Connected to business-tools over stdio. 6 tools offered to this key. Provider: mock.
Task: Mark order O00300 as shipped
Answer: I cannot do that with my access: the tool update_order_status is not available to this API key.The audit log afterwards:
$ python -m business_mcp audit tail -n 5
1 2026-10-12T12:07:04Z demo-agent stdio get_order ok order O00012
2 2026-10-12T12:07:04Z demo-agent stdio request_refund ok refund R0001 pending, 300.0
$ python -m business_mcp audit verify
Audit log intact: 2 records. Head hash: 495d91a08606c80c436d0eddf4ce6e646fbb0dc9aed88685074285639d4eb4c2Results
All numbers below come from commands run for this repository on one 8-core CPU machine.
What was measured | Result | Command |
Automated tests, offline, no key | 46 passed |
|
Role and tool combinations behaving as the written policy says (3 roles x 13 tools, over stdio) | 39 of 39 |
|
Tool list offered to each role matches the policy | 3 of 3 roles |
|
Guardrail cases handled correctly (forbidden moves, bad arguments, masking, retry, rate limit) | 29 of 29 |
|
Refused calls that changed any business data | 0 of 25 |
|
HTTP authentication cases (no key, unknown key, valid key, revoked key) | 4 of 4 |
|
Audit records compared with calls counted by the client | 893 records for 893 calls |
|
Tampering detected (edited record, deleted record, edited record with its hash recomputed) | 3 of 3 |
|
Read call over stdio, median / 95th percentile (300 calls) | 6.0 ms / 8.8 ms |
|
Action call over stdio, median / 95th percentile (100 calls) | 5.1 ms / 7.0 ms |
|
Read call over HTTP, median / 95th percentile (300 calls) | 13.0 ms / 17.1 ms |
|
Action call over HTTP, median / 95th percentile (100 calls) | 12.0 ms / 14.7 ms |
|
Demo agent tasks on the offline scripted provider | 10 of 10 |
|
The offline provider is a script that recognises a fixed set of phrasings. Its 10 of 10 shows that the client, the protocol and the server work together; it says nothing about how well a language model chooses tools.
Real-model check: pending. No OpenAI key was available when this was built, and the local
model that was tried did not answer in time, so the demo agent has not yet been run with a real
language model and nothing was spent. What is covered instead: a test runs the real OpenAI client
library against a local stub server and confirms that the tool definitions and the token cap are
sent and that a tool call and a final answer are read back correctly. python -m evals.live_check
is ready to run the eight live tasks as soon as a key or a local model is set.
The evaluation fails when it should: with the orders:write permission deliberately added to the
viewer role, the same command reported 37 of 39 and exited with an error.
Quick start
No API key is needed. Python 3.12.
git clone https://github.com/BelAnas/mcp-business-tools-server.git
cd mcp-business-tools-server
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
pytest -q # the test suite
python -m business_mcp demo "What is the status of order O00012?"
python -m evals.run_eval # the measurements in the table aboveThe first command that needs the database creates data/business.db: a fictional office-supplies
wholesaler with 60 customers, 40 products and 300 orders, generated from a fixed seed, plus three
demo keys (demo-viewer-key, demo-agent-key, demo-manager-key).
Other requests the offline demo understands:
python -m business_mcp demo "Which products are running low?"
python -m business_mcp demo "Show sales from 2026-09-01 to 2026-09-30 by category"
python -m business_mcp demo "Add a note to customer C0005: asked for a paper quote"
python -m business_mcp demo "Mark order O00012 as cancelled" # refused: a delivered order is finalConnect an assistant
Claude Desktop (claude_desktop_config.json), with the paths of your clone:
{
"mcpServers": {
"business-tools": {
"command": "/path/to/mcp-business-tools-server/.venv/bin/python",
"args": ["-m", "business_mcp", "serve"],
"cwd": "/path/to/mcp-business-tools-server",
"env": { "BUSINESS_MCP_API_KEY": "demo-agent-key" }
}
}
}Claude Code:
claude mcp add business-tools --env BUSINESS_MCP_API_KEY=demo-agent-key \
-- /path/to/mcp-business-tools-server/.venv/bin/python -m business_mcp --db /path/to/mcp-business-tools-server/data/business.db serveThe role of the key decides what the assistant can do. Start with demo-viewer-key to try it
read-only.
Run over HTTP
python -m business_mcp serve --transport http # http://127.0.0.1:8931/mcp
curl -s -X POST http://127.0.0.1:8931/mcp -H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
# {"error": "A valid API key is required: Authorization: Bearer <key>"}Use a real model in the demo agent
export LLM_PROVIDER=openai OPENAI_API_KEY=... # or OPENAI_BASE_URL for a local model
python -m business_mcp demo "Cancel order O00298 and tell me what happened to the stock"
python -m evals.live_check # 8 tasks judged by the databaseReal keys
python -m business_mcp keys create --label support-bot --role agent # printed once, stored as a hash
python -m business_mcp keys list
python -m business_mcp keys revoke --label support-botBefore any real use, delete the demo keys (keys revoke --label demo-agent, and so on).
Configuration
Copy .env.example to .env. Environment variables take precedence over the file.
Setting | Default | Meaning |
| empty | The key the server runs as over stdio. It refuses to start without a valid one. |
|
| Database file. |
|
| Address of the HTTP transport. |
|
| Calls allowed per key per minute. |
|
| Largest refund an agent key gets approved at once. |
|
| Largest refund a manager key gets approved at once. |
|
| Demo agent only: |
| empty, | Demo agent only. Set the base URL for Ollama or another compatible server. |
|
| Demo agent only: cap on each model reply. |
Project structure
business_mcp/
config.py settings read from the environment
db.py SQLite schema and connections (read tools get a read-only connection)
seed.py the synthetic wholesaler, generated from a fixed seed
auth.py API keys (hashed), roles and their permissions
errors.py the error codes tools return
ratelimit.py per-key call limit
audit.py hash-chained audit log and its verification
gateway.py the single path for every call: checks, transaction, audit
policy.py the policy text served as an MCP resource, generated from the code
server.py the MCP server: stdio, HTTP with bearer check, resources, prompts
cli.py serve, seed, keys, audit, tools, demo
tools/
registry.py one entry per tool: argument model, permission, handler
read.py the six read tools
write.py the seven action tools and the business rules
agent/
providers.py offline scripted provider and OpenAI-compatible provider
loop.py the agent loop over an MCP client
run.py the demo command
evals/
run_eval.py permission matrix, guardrails, audit, HTTP auth, latency, agent tasks
live_check.py the demo agent with a real model, judged by the database
report.json the full report of the last evaluation run
tests/ pytest suite: gateway rules, MCP over three transports, agentLimits
The business system is a demo SQLite database with synthetic data. A real deployment replaces the SQL in the tools with calls to the company's own system; the gateway stays the same.
Authentication is by static API key. There is no OAuth sign-in and no per-user identity behind a key: the audit log names the key, not the person using the assistant.
The audit chain detects edits and deletions inside the log. It cannot detect the removal of the most recent records unless the head hash (printed by
audit verify) is also stored somewhere the server cannot write to. That export is not automated here.The audit log stores the arguments of each call, capped at 1,000 characters. Free text such as a note or a search term is therefore copied into the log.
The rate limit is kept in memory per server process. Several processes behind a load balancer would each count separately.
SQLite allows one writer at a time. The response times were measured with one client making calls one after another, not under concurrent load.
Amounts have no currency and no tax. A refund is a record with a status; no payment provider is called.
The offline provider of the demo agent is a script for a fixed set of phrasings, not a model.
Claude Desktop and Claude Code were not driven by hand in this build. Compatibility was tested with the official MCP client library, with both the current protocol and the older handshake.
The HTTP transport has no TLS of its own; it is meant to sit behind a reverse proxy.
License
MIT. See LICENSE.
This server cannot be deployed
Maintenance
Related MCP Connectors
Connect AI to store orders, products and inventory with scoped access and human approvals.
AI agents run business processes on your business data. Every change is attributed and reversible.
- StackOneOAuthcom.stackone
Give AI agents 30,000+ safe, token-optimized actions across Workday, SAP, Oracle + hundreds more.
Every AI tool call runs as the person who asked, under your rules, fully audited.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables AI assistants to interact with a commercial management system through controlled capabilities for querying orders, analyzing invoices, summarizing customer activity, and creating orders, with role-based access control and audit trails.-
- FlicenseNot gradedqualityCmaintenanceEnables AI agents to retrieve customer, order, ticket, policy, and agreement information, and to prepare or execute state-changing support actions like escalations and follow-ups with confirmation and access control.-
- FlicenseNot gradedqualityCmaintenanceEnables AI agents to provide e-commerce customer service with product search, RAG-based FAQ answers, human handoff, and automated security auditing with a review workflow.-
- FlicenseNot gradedqualityCmaintenanceEnables AI agents to securely call enterprise MCP tools with tenant-scoped RBAC, human approvals, audit logging, and multi-tool workflows across customer, order, document, and ticket data.-