local-mcp-postgres
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., "@local-mcp-postgresWhat's the current inventory of Widget B?"
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.
π Operation LOCAL-MCP
A fully local Postgres-backed MCP (Model Context Protocol) server, connected two ways: first to Claude Desktop (which speaks MCP natively), then to a fully local Ollama model via a hand-built bridge β since Ollama has no native MCP client. Both paths sit behind a FastAPI + Streamlit chat console.
Built as a diagnostic exercise as much as a build exercise: the core question was "where exactly does local-model tool-calling reliability break down?", and this project isolates that question with a small, controlled two-tool schema.
What it does
Ask questions in plain English about a local inventory/orders database:
"What's in the inventory?"
"What's John's total order amount?"
"How many Widget B do we have?"
The model decides which tool to call, the tool runs a safe parameterized query against Postgres, and the result gets turned back into a natural-language answer.
Architecture
βββββββββββββββ stdio (MCP) ββββββββββββββββββββ
βClaude DesktopββββββββββββββββββββββΊβ β
βββββββββββββββ β server.py ββββΊ Postgres
β (FastMCP) β (Docker)
βββββββββββββββ hand-built bridge β β
β Ollama ββββββββββββββββββββββΊβ β
β (qwen2.5:7b) β (bridge.py) ββββββββββββββββββββ
ββββββββ¬ββββββββ
β
βΌ
βββββββββββββββ HTTP βββββββββββββββ
β FastAPI βββββββββββΊβ Streamlit β
β (main.py) β β (app.py) β
βββββββββββββββ βββββββββββββββserver.py is the single source of truth for the tools β both Claude Desktop and
the Ollama bridge talk to the exact same FastMCP server. This was deliberate: it
turns "does Claude Desktop succeed where Ollama fails?" into a clean A/B test,
since the only variable that changes is the model, not the tool definitions.
Key finding
The starting hypothesis (from prior local-LLM tooling work) was that 7Bβ12B
models are broadly unreliable at emitting well-formed tool calls. That held for
dense, high-overhead schemas (e.g. Claude Code's tool surface), but did not
hold here: qwen2.5:7b, given this project's small two-tool schema, correctly
selected the right tool on every test β including inferring a sensible default
parameter (min_quantity: 1) that wasn't stated in the prompt β and never once
emitted malformed tool-call JSON.
Takeaway: the earlier reliability problem looks like it's driven more by
schema size / context overhead than by a hard local-model capability
ceiling. Worth revisiting the claude-code-router / hosted-API tradeoff with
that in mind β schema simplification may solve more of the problem than
switching providers does.
Setup
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
docker compose up -d # Postgres, seeded via init.sql
ollama pull qwen2.5:7b # or llama3.1:8b β confirm `tools` under
ollama show qwen2.5:7b # Capabilities before relying on itRunning it
Path 1 β Claude Desktop (MCP native):
Add an entry to claude_desktop_config.json pointing at src/server.py using
your venv's Python (see repo history / commit log for the exact config that
worked after a couple of path-resolution false starts β see Gotchas below).
Path 2 β Local Ollama console:
# terminal 1
uvicorn src.main:app --reload
# terminal 2
streamlit run src/app.pyThen open the Streamlit URL and ask questions in the chat box.
Gotchas hit along the way (kept for the next person, including future me)
python -m src.serverworks from a terminal but not from Claude Desktop's launched subprocess β itscwdhandling doesn't reliably put the project root on Python's module search path for-mresolution. Fix: pointclaude_desktop_config.jsondirectly at the script file (args: ["/abs/path/src/server.py"]) instead of using-m.tool.inputSchemavstool.input_schemaβ the wire-protocol field name and the installedmcpSDK's Python attribute name don't match; the SDK usessnake_case. Worth checking installed SDK attribute names directly rather than assuming they mirror the protocol spec.init.sqlonly runs against Postgres on a fresh Docker volume. If you've already got apgdatavolume from a prior run, editinginit.sqland re-runningdocker compose upsilently does nothing β you needdocker compose down -vfirst to force re-seeding.Model function-call arguments arrive as either a dict or a JSON string depending on the model/quantization β
bridge.py's loop handles both.
Known limitations
No multi-turn memory. Each
/chatrequest (and eachrun_tool_call_loopcall) starts a fresh conversation with no history from prior turns. The Streamlit UI displays prior turns for readability, but doesn't send them back to the backend β a deliberate scope cut for this iteration, not an oversight.Each request respawns the MCP server subprocess rather than keeping one long-lived session β simpler and correct for this scale, but adds latency you'd want to remove for anything beyond a local demo.
Read-only by design: both tools run fixed, parameterized
SELECTs. No write/update tools exist, intentionally, to keep the safety surface small.
Stack
Python 3.12 Β· FastMCP Β· MCP SDK Β· Ollama (qwen2.5:7b) Β· PostgreSQL (Docker) Β·
FastAPI Β· Streamlit Β· psycopg2
Repo layout
local-mcp-postgres/
βββ README.md
βββ MISSION_PLAN.md # phase-by-phase build log / checklist
βββ docker-compose.yml
βββ init.sql
βββ requirements.txt
βββ src/
βββ server.py # FastMCP server: fetch_inventory, fetch_order_total
βββ bridge.py # Ollama-MCP bridge + tool-call loop
βββ main.py # FastAPI backend
βββ app.py # Streamlit consoleTool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
No tool schema history has been recorded yet.
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 Connectors
Analytical memory for AI agents: a real Postgres queried in plain English over MCP. One command.
- mcpOAuthcom.gibsonai
GibsonAI MCP server: manage your databases with natural language
Query your warehouse or a CSV with Claude/ChatGPT over MCP, governed by table-level ACL + audit.
Query your org's data in natural language β read-only MCP access to SQL, NoSQL, files & warehouses.
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/venkatacloud01/local-mcp-postgres'
If you have feedback or need assistance with the MCP directory API, please join our Discord server