mcp-agent-toolkit
Provides a tool to query a read-only PostgreSQL database, enabling the agent to retrieve data from a sample commerce dataset using SELECT statements.
Click on "Install 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., "@mcp-agent-toolkitWhat's the total revenue from Dubai customers and the weather there?"
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-agent-toolkit
Live demo: not deployed yet — planned at agent.build-with-deepak.com.
This repo is complete and locally verified (build, lint, 25 unit tests —
including a real MCP protocol round-trip — and 5 e2e tests); it has not
yet been deployed or exercised against a live Ollama/Postgres. See
Status.
The problem
Most "AI agent" demos are a single hidden tool call dressed up as autonomy. This one shows its work: a Model Context Protocol agent with three real tools — a read-only PostgreSQL commerce database, a live weather API, and a calculator — answering questions that genuinely need more than one of them ("total revenue from Dubai customers, and what's the weather there?"). Every tool invocation, its arguments, its result, its latency, and — importantly — its failures and the model's recovery from them stream to the screen as they happen.
Related MCP server: MCP Tool Server
Try it
Continue with demo account issues a real 2-hour session against the
real API — same agent, same tools, same data. The sample database is
shared and read-only, so demo sessions need no per-user cleanup: nothing
a visitor does can write anything. Registration (persistent per-user
data) is in progress; the Register button and POST /api/auth/register
(501) both say so honestly.
Architecture
flowchart TB
subgraph Browser
UI[Angular SPA<br/>login → live tool-call timeline]
end
subgraph VPS -- host nginx, TLS
Nginx[nginx :443]
end
subgraph "Docker Compose stack"
Web[web container]
subgraph API [api container — NestJS]
Loop[Agent loop]
Client[MCP Client]
Server[MCP Server]
end
PG[(PostgreSQL<br/>sample dataset<br/>mcp_readonly role)]
end
Ollama[Ollama llama3.1 — on the VPS]
Meteo[Open-Meteo API]
UI -->|HTTPS| Nginx --> Web -->|/api/*| Loop
Loop -->|chat + tools| Ollama
Loop -->|listTools / callTool| Client
Client <-->|MCP protocol, in-memory transport| Server
Server -->|query_database| PG
Server -->|get_weather| Meteo
Server -->|calculate| ServerThe loop: the model receives the question plus the MCP-discovered tool schemas → emits tool calls → each call runs through the MCP client → results (including errors) go back to the model → repeat until it answers in prose or hits the step ceiling (default 6). Every hop is an SSE event.
Key decisions and trade-offs
A real MCP server and client, in one process. The tools could have
been plain functions — the protocol boundary is the point. The agent loop
talks only to the MCP client: it discovers tools via listTools() and
invokes them via callTool(), exactly as it would against an external
server over stdio or HTTP. Moving a tool out of this process changes one
transport line, not the agent. The in-memory transport keeps a single-VPS
demo free of extra ports and subprocess supervision while the SDK still
validates schemas both ways — and the unit suite exercises that actual
handshake, not a mock of it.
SQL injection is treated as the DEFAULT state, not an edge case. The
agent writes SQL from a stranger's natural-language question — that is
untrusted input by construction. Two layers: an app-side guard
(sql-guard.ts: comment stripping, single-statement, SELECT/WITH-only, a
keyword denylist that knows set_config is not set, and a subquery
wrap capping results at 100 rows) fails fast with messages the model can
act on; beneath it, the query executes as a dedicated mcp_readonly
Postgres role — SELECT-only grants, default_transaction_read_only=on,
5s statement timeout — which holds even if the guard has a bug. The
guard's own tests document its accepted lexical limitation.
Tool errors are fed back to the model, not surfaced as failures. A
failed tool call returns as an isError result and goes into the
conversation as tool output. The model reads the error, fixes its SQL or
picks another city, and retries — and the UI annotates exactly that
("the error goes back to the model — watch the next step"). Watching
recovery is worth more, as evidence of engineering, than never failing.
The calculator is a 60-line parser, not eval. An LLM-written
expression handed to any JavaScript evaluator turns a calculator into a
code-execution tool. Recursive descent with an explicit grammar is the
boring, correct alternative; its tests include 1 + 1; process.exit().
Loop steps are non-streaming; the timeline is the stream. Whether a model response is a tool call or the final answer is only knowable when it's complete, and tool-call responses are short. What streams live is what's actually interesting — the tool calls and results as they happen. The final prose answer arrives as one event. (Same SSE-over-POST transport decision as the sibling router demo, same reasons.)
Open-Meteo for weather. Free and keyless: an unattended public demo with a third-party API key in it is a leak waiting to happen and a bill waiting to be run up. The trade-off — no SLA — is acceptable because a weather-tool outage is itself a live demonstration of the error-handling path.
Fixed sample dataset with fixed IDs. Seeding uses ON CONFLICT DO NOTHING, so every boot converges to the same 15 customers / 12 products
/ 32 orders instead of accumulating duplicates. Cities were chosen so
DB + weather questions compose naturally (Dubai, New Delhi, London…).
Database setup and reset
Schema, sample data and the mcp_readonly role's grants live in
apps/api/db/schema.sql, applied idempotently on every API boot; the
role itself (password from MCP_READONLY_PASSWORD) is created in
db.service.ts because CREATE ROLE can't take a parameterized
password. pnpm db:reset drops the sample tables; the next boot
recreates everything. There is no routine demo-data cleanup here by
design — visitors cannot write.
What I'd change at 100x scale
The in-memory MCP transport is the first thing that moves: real
multi-tenant tool servers run as separate services (stdio subprocesses or
HTTP), with per-tool authz and audit logging at the protocol boundary —
this codebase is already shaped for that swap. The agent loop would gain
persistent conversations (a conversations table keyed by session — the
natural first feature of registered accounts), parallel tool execution
where calls are independent, and a token-budget ceiling alongside the
step ceiling. And the SQL tool would stop exposing raw SELECT entirely:
at scale you publish named, parameterized query templates and let the
model fill parameters — the guard-plus-readonly-role pattern here is the
demo-sized version of that idea, not a substitute for it.
Local setup
Node 22+, pnpm; for the full experience, Postgres and an Ollama with a
tool-capable model (ollama pull llama3.1:8b — plain llama3 does not
reliably emit tool calls).
corepack enable && pnpm install
pnpm dev:api # :3000
pnpm dev:web # :4200, proxies /api → :3000Gate checks:
pnpm --filter api build && pnpm --filter api lint && pnpm --filter api test && pnpm --filter api test:e2e
pnpm --filter web build && pnpm --filter web testDeploying to the VPS
cp .env.example .env— setPOSTGRES_PASSWORD,MCP_READONLY_PASSWORDandJWT_SECRET(compose refuses to start without them). Confirmollama liston the VPS showsllama3.1:8b.docker compose up -d --build— web binds127.0.0.1:8092only.Install
nginx/agent.build-with-deepak.com.confinto the host nginx, thencertbot --nginx -d agent.build-with-deepak.com.GET /api/healthis the unauthenticated liveness probe.
Status
Real MCP server + client over the SDK's in-memory transport, three tools, protocol round-trip covered by tests
Agent loop with live SSE tool-call timeline, error-recovery feedback, step ceiling
Two-layer SQL protection (guard + dedicated read-only Postgres role)
Demo-account auth end to end; register = honest 501 coming-soon
Builds, lints, passes all tests (API: 25 unit + 5 e2e; web: 6)
Not yet run against live Ollama/Postgres — this environment had neither; the agent loop's Ollama tool-calling path in particular needs a real llama3.1 run before this goes in front of anyone
Not yet deployed
Registration/persistent accounts — in progress (demo-first by design)
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- FlicenseBqualityDmaintenanceA demonstration server showcasing MCP capabilities with basic tools including addition calculations and weather API integration for fetching city weather data.22
- Flicense-qualityDmaintenanceA production-ready Python MCP server providing tools for fetching live weather data, querying local SQLite databases, reading files, summarizing webpages, and performing safe mathematical calculations. It enables MCP-compatible LLM clients to execute these tasks autonomously as part of agentic workflows.
- Flicense-qualityCmaintenanceA demonstration MCP server that provides math (add/multiply) and weather tools, connecting via stdio and streamable HTTP, and integrates with LangChain and LangGraph for agentic workflows.
- FlicenseAqualityCmaintenanceA production-grade MCP server that provides real-time weather data and demonstrates the complete MCP protocol surface including tools, resources, prompts, and structured output.22
Related MCP Connectors
AI Reasoning Cache & Consensus Layer with 11 MCP tools via Streamable HTTP.
Analytical memory for AI agents: a real Postgres queried in plain English over MCP. One command.
GibsonAI MCP server: manage your databases with natural language
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/build-with-deepak/mcp-agent-toolkit'
If you have feedback or need assistance with the MCP directory API, please join our Discord server