Skip to main content
Glama
Jarvis-27

PlainQuery

by Jarvis-27

PlainQuery

Ask your database questions in plain English. PlainQuery connects PostgreSQL databases to Claude, Cursor, or VS Code — and answers with real, structured data instead of guesses.

MCP Registry CI Python


What it does

You connect a database once. Then, from any MCP client, you ask questions like:

"How many orders did we ship in March?" "Which 5 customers spent the most last year?" "What's the average order value by month?"

PlainQuery introspects your schema, generates SQL with an LLM, validates it for safety, runs it, and returns structured JSON. If a query fails, it reads the error and retries automatically.

Related MCP server: dbecho

Why PlainQuery

  • Natural language, real answers — no SQL required; results come from your actual data, not a hallucination.

  • Read-only and safe by design — every query is checked before it runs: writes (INSERT/UPDATE/DELETE/DDL) are blocked, dangerous functions and patterns are scanned out, and a LIMIT is injected automatically.

  • Self-correcting — when a generated query errors, the agent feeds the error back to the LLM and retries (up to a configurable limit).

  • Schema-aware — automatically introspects and caches your schema, so questions map to the right tables and columns.

  • Works with any MCP client — Claude Desktop, Cursor, VS Code Copilot, or anything that speaks MCP.

  • Secure multi-tenant hosting — database URLs and LLM keys are Fernet-encrypted at rest; user-supplied connection strings are SSRF-guarded; every request is tenant-scoped.

  • Hosted or self-hosted — use the managed service, or run the whole stack yourself with Docker.

  • Bring your own LLM — Anthropic Claude or Groq.

How it works

Your question
   → Schema introspection      (reads tables/columns, cached)
   → SQL generation            (schema + question → LLM → SQL)
   → Safety validation         (blocks writes, scans dangerous patterns, injects LIMIT)
   → Execution                 (runs read-only, with a timeout)
   → Self-correction retry     (on error: feed it back to the LLM, fix, re-run)
   → Structured JSON result

Architecture


Quick start

Option 1 — Use the hosted service (no install)

  1. Sign up at https://plainquery.in and verify your email.

  2. Connect your PostgreSQL database and create an API key.

  3. Add the server to your MCP client (see Connect your MCP client).

That's it — start asking questions.

Option 2 — Run it yourself

See Self-hosting & local development below.

Connect your MCP client

PlainQuery is published on the official MCP Registry as io.github.Jarvis-27/mcp-db-agent, so registry-aware clients can discover it directly.

To configure a client manually, point it at the MCP endpoint and pass your API key:

{
  "mcpServers": {
    "plainquery": {
      "url": "https://plainquery.in/mcp",
      "headers": { "X-API-Key": "mdbk_your_key_here" }
    }
  }
}

The backend can also generate ready-to-paste config for VS Code, Cursor, and generic HTTP clients — call POST /api/v1/account/setup-payloads (see Setup payloads). MCP clients can authenticate with an OAuth 2.1 bearer token or an API key, depending on MCP_AUTH_MODE.


Self-hosting & local development

Prerequisites

  • Python 3.12+

  • uv

  • Node.js 20+ and pnpm for the frontend

  • At least one LLM API key (ANTHROPIC_API_KEY or GROQ_API_KEY)

Backend

uv sync
cp .env.example .env

Edit .env with at least:

  • CREDENTIAL_ENCRYPTION_KEYS

  • REGISTRATION_OPEN=true

  • one LLM provider key plus LLM_PROVIDER

Run the backend:

uv run uvicorn src.app:app --reload --host 0.0.0.0 --port 8000

The backend mounts:

  • REST API at http://localhost:8000/api

  • MCP endpoint at http://localhost:8000/mcp

Frontend

cd frontend
pnpm install
pnpm dev

Open http://localhost:3000, sign up, complete setup, link your OAuth identity via account settings, then connect an MCP client at http://localhost:8000/mcp. The client will complete the OAuth flow automatically, or you can use an API key in api_key_only / hybrid mode.

Runtime model

  • Backend API: FastAPI/Starlette at src.app:app

  • Frontend: Next.js app in frontend/

  • Auth: passwordless email verification and login links

  • MCP auth: OAuth 2.1 bearer tokens (oauth_only), API keys (api_key_only), or both (hybrid) — set via MCP_AUTH_MODE

  • Setup payloads: POST /api/v1/account/setup-payloads

  • Billing: Stripe Checkout, Customer Portal, and webhook-confirmed Free/Pro entitlements

The product model is single-account and user-scoped: signup → verify email → connect database → link OAuth identity → use /mcp → upgrade with Stripe

Security

  • User-supplied database URLs are validated against SSRF, path traversal, private IPs, and DNS rebinding before any connection attempt.

  • Database URLs and LLM keys are Fernet-encrypted at rest, with support for key rotation.

  • Generated SQL is validated before execution: single-statement guard, forbidden-function scan, dangerous-pattern scan, write/DDL block, table-existence check, and automatic LIMIT injection.

  • Per-request context scoping prevents cross-tenant data leaks.

  • Per-user rate limits and fallback-LLM quotas limit cost abuse.

Important environment variables

Variable

Description

AUTH_DATABASE_URL

Auth/account database used by the hosted product

CREDENTIAL_ENCRYPTION_KEYS

Encrypts stored database URLs and other secrets

REGISTRATION_OPEN

Enables or disables public signup

ANTHROPIC_API_KEY / GROQ_API_KEY

LLM credentials for SQL generation

LLM_PROVIDER

Active provider name

APP_BASE_URL

Base URL used in setup payloads

FRONTEND_BASE_URL

Base URL used in email links

STRIPE_SECRET_KEY / STRIPE_WEBHOOK_SECRET

Stripe API and webhook credentials

STRIPE_PRO_PRICE_ID

Stripe Price ID that maps to the Pro plan

STRIPE_CHECKOUT_SUCCESS_URL / STRIPE_CHECKOUT_CANCEL_URL

Optional Checkout redirect overrides

STRIPE_CUSTOMER_PORTAL_RETURN_URL

Optional Customer Portal return URL override

See .env.example for the current full set.

API surface

Auth

  • POST /api/v1/auth/signup

  • GET /api/v1/auth/verify-email

  • POST /api/v1/auth/request-login-link

  • GET /api/v1/auth/exchange-login-link

  • POST /api/v1/auth/logout

Account (session-authenticated)

All account routes use session token auth (x-session-token: <session-token> or Authorization: Bearer <session-token>):

  • GET /api/v1/account

  • GET /api/v1/account/status

  • PUT /api/v1/account/database

  • GET /api/v1/account/api-keys

  • POST /api/v1/account/api-keys

  • DELETE /api/v1/account/api-keys/{id}

  • POST /api/v1/account/api-keys/{id}/rotate

  • POST /api/v1/account/setup-payloads

  • GET /api/v1/account/dashboard

  • GET /api/v1/account/usage/recent

Billing

  • GET /api/v1/account/billing

  • POST /api/v1/account/billing/checkout-session

  • POST /api/v1/account/billing/portal-session

  • POST /api/v1/billing/webhook

Stripe webhooks are the source of truth for plan transitions. Checkout or subscription activation moves a user to plan_code=pro; canceled, unpaid, or past-due states restrict paid entitlements without deleting database setup.

OAuth MCP account linking (session-authenticated)

  • GET /api/v1/account/mcp-oauth/status

  • POST /api/v1/account/mcp-oauth/start

  • GET /api/v1/account/mcp-oauth/callback

  • DELETE /api/v1/account/mcp-oauth/link

MCP

  • POST /mcp

  • Auth: OAuth 2.1 bearer token, API key, or both — controlled by MCP_AUTH_MODE

Setup payloads

POST /api/v1/account/setup-payloads returns client configuration material for VS Code, Cursor, generic HTTP MCP clients, and the current ChatGPT placeholder.

curl -X POST http://localhost:8000/api/v1/account/setup-payloads \
  -H "Authorization: Bearer <session-token>" \
  -H "Content-Type: application/json" \
  -d '{"raw_api_key":"mdbk_..."}'

The backend never stores raw API keys after creation. A raw key is only embedded in setup payloads when you explicitly send it in the request.

Tests

uv run pytest tests/ -m "not integration"
uv run pytest tests/ -m integration
uv run ruff check .
uv run mypy src --ignore-missing-imports

Deployment smoke test

After each hosted deploy, verify the public MCP OAuth discovery surface:

uv run python scripts/smoke_mcp_deployment.py \
  --mcp-url https://mcp.example.com/mcp \
  --issuer-url https://YOUR_DOMAIN.auth0.com/

The smoke test checks the unauthenticated /mcp challenge, protected resource metadata, ChatGPT/Claude well-known discovery routes, and issuer metadata. To also verify authenticated MCP initialize, tools/list, and resources/list, pass a linked user's access token with --access-token or MCP_SMOKE_ACCESS_TOKEN.

Docker

Run the hosted HTTP stack:

docker compose up --build

The container image serves only the hosted HTTP runtime. The MCP endpoint remains http://localhost:8000/mcp.

License

MIT © 2026 PlainQuery

A
license - permissive license
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

  • F
    license
    -
    quality
    D
    maintenance
    Enables natural language querying of PostgreSQL databases through the Model Context Protocol. It translates user questions into validated SQL, executes read-only queries safely, and returns results to MCP-compatible clients like Claude Desktop.
    Last updated
  • A
    license
    A
    quality
    A
    maintenance
    An MCP server that gives AI agents direct read-only access to PostgreSQL databases, enabling natural language analytics through tools for schema exploration, querying, trend analysis, and data quality checks.
    Last updated
    11
    5
    MIT
  • A
    license
    -
    quality
    B
    maintenance
    Enables SQL queries against PostgreSQL databases through MCP-compatible clients and includes a natural language agent for forming SQL queries from natural language.
    Last updated
    208
    PostgreSQL

View all related MCP servers

Related MCP Connectors

  • 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

  • MCP server for managing Prisma Postgres.

View all MCP Connectors

Latest Blog Posts

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/Jarvis-27/mcp-db-agent'

If you have feedback or need assistance with the MCP directory API, please join our Discord server