Mcp Db Agent — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited Mcp Db Agent (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
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.
<p align="center"> <img src="docs/PlainQuery_GIF.gif" alt="PlainQuery demo — querying a database in plain English from an MCP client" width="800"> </p>
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.
INSERT/UPDATE/DELETE/DDL) are blocked, dangerous functions and patterns are scanned out, and a LIMIT is injected automatically.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<p align="center"> <img src="docs/diagram/plainquery-architecture.png" alt="PlainQuery architecture diagram showing clients, Next.js frontend, Starlette/FastAPI backend, FastMCP endpoint, query pipeline, LLM provider, and customer database" width="900"> </p>
That's it — start asking questions.
See Self-hosting & local development below.
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.
uvpnpm for the frontendANTHROPIC_API_KEY or GROQ_API_KEY)uv sync
cp .env.example .envEdit .env with at least:
CREDENTIAL_ENCRYPTION_KEYSREGISTRATION_OPEN=trueLLM_PROVIDERRun the backend:
uv run uvicorn src.app:app --reload --host 0.0.0.0 --port 8000The backend mounts:
http://localhost:8000/apihttp://localhost:8000/mcpcd frontend
pnpm install
pnpm devOpen 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.
src.app:appfrontend/oauth_only), API keys (api_key_only), or both (hybrid) — set via MCP_AUTH_MODEPOST /api/v1/account/setup-payloadsThe product model is single-account and user-scoped: signup → verify email → connect database → link OAuth identity → use /mcp → upgrade with Stripe
<p align="center"> <img src="docs/diagram/plainquery-security.png" alt="PlainQuery security diagram showing URL validation, SSRF protection, encrypted credential storage, MCP authentication, per-request isolation, SQL validation, rate limits, and controlled execution" width="900"> </p>
LIMIT injection.| 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.
POST /api/v1/auth/signupGET /api/v1/auth/verify-emailPOST /api/v1/auth/request-login-linkGET /api/v1/auth/exchange-login-linkPOST /api/v1/auth/logoutAll account routes use session token auth (x-session-token: <session-token> or Authorization: Bearer <session-token>):
GET /api/v1/accountGET /api/v1/account/statusPUT /api/v1/account/databaseGET /api/v1/account/api-keysPOST /api/v1/account/api-keysDELETE /api/v1/account/api-keys/{id}POST /api/v1/account/api-keys/{id}/rotatePOST /api/v1/account/setup-payloadsGET /api/v1/account/dashboardGET /api/v1/account/usage/recentGET /api/v1/account/billingPOST /api/v1/account/billing/checkout-sessionPOST /api/v1/account/billing/portal-sessionPOST /api/v1/billing/webhookStripe 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.
GET /api/v1/account/mcp-oauth/statusPOST /api/v1/account/mcp-oauth/startGET /api/v1/account/mcp-oauth/callbackDELETE /api/v1/account/mcp-oauth/linkPOST /mcpMCP_AUTH_MODEPOST /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.
uv run pytest tests/ -m "not integration"
uv run pytest tests/ -m integration
uv run ruff check .
uv run mypy src --ignore-missing-importsAfter 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.
Run the hosted HTTP stack:
docker compose up --buildThe container image serves only the hosted HTTP runtime. The MCP endpoint remains http://localhost:8000/mcp.
MIT © 2026 PlainQuery
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.