Skip the slide decks. Clone one repo, run one command, and ask a working AI agent questions about a demo pump company. Then peek under the hood.
MCP is the future. Everyone says so. Few have actually used one.
I'm a digitalization consultant. Every other client conversation now ends with the same question: "so… should we be doing MCP?" I've drawn the same diagram on the same whiteboard a hundred times, and I've watched eyes glaze over a hundred times. So I stopped explaining.
I built a demo company instead. It has customers, orders, invoices, deliveries, complaints, and a chat agent that knows how to use all of them. You clone one repo, run one command, wait a few minutes, and you're talking to it. Then you open a second tab and watch every call the AI makes, in real time, with the same arguments and answers the protocol sees.
This article is the shortest path I know from "I keep hearing about MCP" to "oh, that's what it does." No code required from you. Just a laptop with Docker.
MCP (Model Context Protocol) is a standard contract that lets an AI use your business tools — read a CRM, query a database, file a ticket — through plain language. This post walks you through a public demo you can run locally in under five minutes. By the end you'll have asked a demo B2B company a question, watched it pull data from its own backend, and inspected every tool call in a built-in dashboard.
Meet the demo: a pump maker — and its agent
Say hello to Rheintal Pumpen GmbH, a fictional German industrial pump manufacturer. About 60 customers, 250 orders, complaints, deliveries, service tickets — the kind of data shape every mid-market B2B has lying around in some ERP nobody likes touching.
The demo runs all of it on your laptop: a SQLite database, an MCP server exposing 13 tools (search products, look up a customer, list open invoices, file a service ticket, and so on), and a chat UI on top.
The chat UI is LibreChat — open source, runs in the same docker-compose stack — and inside LibreChat there's a configured agent called "Rheintal Pumpen Demo." You don't see a generic chat box; you see a named persona with conversation starters, a short system prompt, and a curated set of MCP tools wired up to it.
That distinction matters. The pattern emerging across the industry is: tools come from MCP, personality and policy come from the agent. The MCP server says "here is what's possible." The agent says "here is who I am, what I'm here for, and what I'm allowed to use." In this demo the agent is a LibreChat-native feature — no extra service, no extra container — but the architectural idea is the same one you'd use in production.
Ask one question. Watch what happens.
Here's the moment.
You open the chat, click the agent, and type:
"Which submersible pumps with stainless steel housing are in stock?"
You get an answer. Plain English, four model names, stock counts, a one-line summary. Nice.
Then you expand the tool-call card — that little dropdown most chat UIs hide unless you go looking — and you see what the agent actually did.
It picked the right tool out of thirteen. It chose the correct category from a fixed enum (centrifugal_pump, submersible_pump, dosing_pump, accessory). It knew that material was a substring filter and that stainless would catch both "stainless steel" and "cast iron / stainless steel". None of that was in your prompt. It read the tool's description, made the choice, and ran it.
Now flip the picture for a second. Without MCP, the same question is a developer ticket. Somebody has to write this:
SELECT * FROM products
WHERE category = ?
AND flow_rate_m3h >= ?
AND LOWER(material) LIKE ?
ORDER BY category, name
LIMIT 100;
Then somebody has to know that category accepts only four values, that material is a LIKE substring match, and that the database lives behind some VPN. Then somebody has to plumb that query into a Slack bot, a dashboard, or a request form — and maintain it for five years.
With MCP, that whole chain collapses into one line:
"Which submersible pumps with stainless steel housing are in stock?"
The SQL still runs. It runs correctly, with parameter binding and bounds checks. It just runs underneath a sentence.
That's the whole pitch in one beat: MCP turned a SQL skill into a sentence — and kept the SQL safely under the hood.
What just happened, in four lines
If you want to know what MCP actually is — the protocol, not the marketing — it really fits in four lines.
A tool advertises three things: a name, a human-readable description, and a JSON schema for its parameters. The model reads that catalog, picks a tool, fills in the parameters, and calls it. That's the whole contract.
Here's what the model saw for the question above. This is the entire description string for search_products in this repo:
"Search products. Filters: 'category' (centrifugal_pump, "
"submersible_pump, dosing_pump, accessory), 'min_flow_m3h' "
"(minimum flow rate), 'material' (substring, e.g. 'stainless')."
That paragraph — and a tiny JSON schema — is everything the agent had to work with. The category enum, the substring hint, the example value: that's where its apparent cleverness came from. It wasn't magic. It was a well-written description.
Look closely and you can see the design lever: how good your tool descriptions are is how good your agent is. This is the new programmer's craft.
The lid lifts cleanly from there: any function in your existing stack — a CRM lookup, an SAP RFC, a Salesforce query — can become an MCP tool with the same shape. Name, description, schema. Done.
Look under the hood: the Inspector and the Activity stream
The chat is the headline. But the demo wouldn't be very convincing if you had to trust that something sensible was happening behind it. So the repo ships two small dashboards, served straight from the MCP server itself, that let you see everything.
The MCP Inspector — Swagger UI for tools
Open http://localhost:8765/ in a second browser tab. You land on the MCP Inspector — a single page that lists every tool the server exposes, with the same metadata the model sees, just rendered for humans.
Each tool entry shows you four things at a glance:
- What it does — the human description string, identical to what the LLM reads when it decides whether to call this tool.
- What it takes — the parameter schema, expanded into a small form-style block: which fields are required, which are enums (with the allowed values listed inline), which are free text, what the defaults are.
- Who can call it — an allowed_roles chip (admin, sales, accounting, service). Role-based access isn't an afterthought bolted onto MCP; it's right there next to the tool, at the protocol level.
- Whether it changes anything — a small orange write tag for tools that mutate state (only two, in this demo). Read tools have no tag. Anyone scanning the page sees the blast-radius surface in two seconds.
This is the page I send to a customer when they ask: "so what could we wire up to your AI?" It answers without slides, without hand-waving, and without me on the call. They scroll thirteen tools. They see exactly which fields are typed and which are loose. They see two write tools, the rest read-only. In about two minutes they've done what would otherwise take a workshop. That's the meeting I no longer have to take.
The Live Activity stream — every call, in real time
Now open http://localhost:8765/activity. This is the Live Activity stream: every tool call the server has handled, newest first, refreshing as you chat.
Every card is one call. Click one and it expands into a side-by-side view: on the left, the JSON arguments the model picked; on the right, the JSON result the tool returned. If a call fails — a missing customer, an invalid filter — the card goes red and the error sits there in plain text. You can scroll back through your last ten questions and see, for each, exactly what the model decided to do.
This is the second page I never have to make as slides. "How do we know what the AI is actually doing?" The activity stream answers it. "What if we want to audit which questions an agent answered yesterday?" Same answer — events are persisted; the page just shows the latest. "What if we want to wire it into Splunk?" Read the same JSON from /activity.json and ship it.
The deeper point: the visibility layer that makes natural-language tool use safe to deploy isn't separate from MCP — it's a thin wrapper around it. The Inspector and the Activity stream together are maybe 200 lines of HTML and one JSON endpoint. The protocol is doing the heavy lifting; the dashboards just expose what was already there.
From curious to running — in five minutes
Here's the practical part.
Prerequisite (yes, just one): Docker. Specifically Docker with the Compose plugin.
On macOS or Windows: install Docker Desktop. It bundles everything you need.
On Ubuntu or Debian Linux: the repo ships a one-shot helper that installs Docker plus a small set of system tools (make, git, jq, python3). It's idempotent — safe to re-run.
sudo ./scripts/install-prereqs.sh
That's the only thing on a fresh Linux box that touches your system. After it, everything else lives inside containers.
Then the three lines that bring the company to life:
git clone git@github.com:dataAiOliver/rheintal-pumpen-mcp.git
cd rheintal-pumpen-mcp
make up
make up is the entire setup. It writes a .env from the example, generates the SQLite seed data, brings up four containers (the MCP server, LibreChat, MongoDB for chat history, Meilisearch for search), seeds a demo user, and seeds the LibreChat agent so you don't have to wire it up yourself. First run takes a couple of minutes — mostly pulling images.
Most tutorials stop here. This one doesn't, because the part that breaks is usually the part nobody verifies. So:
make smoke-test
That probes /healthz on the MCP server, fetches /tools.json to confirm the catalog is being served, hits the LibreChat root on port 3080, and reads /activity.json to confirm audit logging is alive. If any of those fail, you know exactly where the problem is — not just "the chat doesn't work." (If you'd rather chain both, there's make up-verify.)
Open your browser at http://localhost:3080. Register an account (it's local — no email leaves your laptop), pick the Rheintal Pumpen Demo agent, and ask it something. The 13 tools available are right there in the side panel.
One last detail: the agent needs an LLM provider to actually talk. If your .env doesn't have one, make up stops with a loud error block at the end and tells you exactly what to do — drop OPENAI_API_KEY=sk-... or ANTHROPIC_API_KEY=sk-ant-... into .env and run make up again.
The script is idempotent; nothing is lost. You'll know the moment your key is missing, not three steps later in a broken chat.
Audit logs don't disappear when the interface becomes a conversation — they get more useful.
Why a business reader should care
The most common fear I hear from clients is: "AI will replace our APIs." The demo proves something more nuanced — and more useful. APIs don't go away. They get a new front door.
Three things this demo deliberately keeps intact, because real companies need them:
- Role-based access stays. The MCP server in this repo has four roles — admin, sales, accounting, service. Each agent persona is bound to a role, and each role sees only the tools it should. The accountant agent can flag invoices but can't file service tickets. The service agent can open tickets but can't read accounting data. RBAC isn't a casualty of natural language; it's a parameter of it. You can see this exposed at the protocol level: every entry in /tools.json carries an allowed_roles array right next to its description, which is what the Inspector page renders.
- Audit logging stays — and gets richer. Every tool call is logged with the calling key's role, the tool name, the arguments, and the result. The Live Activity stream you saw above is the human-readable face of that log; /activity.json is the machine-readable one. That's the compliance story your CISO has been asking about, with no extra integration work.
- Validation stays. Every tool input goes through a strict schema before it touches the database. Bad input is rejected before SQL ever runs. The model can't accidentally drop your products table because it doesn't have a "drop" tool — and that constraint is visible to every reader of the Inspector page.
The strategic shift, once you put all of that together, is small but real: the bottleneck moves from "can we integrate?" to "which questions are worth asking?" That's a much better problem to have.
Try it
Clone the repo, run make up, ask the agent a question, and keep the Activity tab open. That's the whole article.
→ https://github.com/dataAiOliver/rheintal-pumpen-mcp
If you got curious, clap. If you're a consultant being asked the same question I was — share this with a client. They'll come back with better questions.











