About valv
@valv/mcp connects coding agents to databases through a read-only-by-default MCP server. It introspects schemas and applies table, field, and policy restrictions so agents can query permitted data without receiving SQL access.
Key features
- 01Inspect live database schemas
- 02Search and describe database resources
- 03Query data through four tools
- 04Restrict access with table and field policies
- 05Filter rows using policy rules
- 06Configure clients with a guided setup
Use cases
- 01Explore permitted database tables
- 02Query data without exposing SQL access
- 03Limit agent visibility to selected tables
- 04Apply row and field restrictions
MCP support
Exposes database schema discovery and query tools to MCP clients. Connections use a database URL; access is read-only by default and can be limited with allow-lists and policy files.
Configuration
Local server config is the same for every client. Copy it into your client’s MCP config file.
npx -y @valv/mcpDATABASE_URLSecretDatabase connection string. PostgreSQL, MySQL, SQLite, CockroachDB, or a ClickHouse HTTP URL.VALV_PROVIDERDatasource provider: postgresql, mysql, sqlite, or clickhouse. Inferred from DATABASE_URL when omitted.VALV_DATABASEDatabase name. Required for ClickHouse, whose URL does not carry one.VALV_TABLESComma-separated allow-list of tables. When set, only these are exposed to the agent.VALV_EXCLUDEComma-separated deny-list of tables, applied after the allow-list.VALV_POLICY_FILEPath to a policy module that takes full control of access. Without it, the server is read-only across all tables.VALV_CONTEXTJSON context object the policy reads, e.g. {"tenant":{"id":"acme"}}.VALV_HTTP_PORTServe over Streamable HTTP on this port instead of stdio.Local servers need a runtime on your machine (e.g. Node.js 18+). Config file locations differ by client; see your client’s docs.
Tools
Local servers expose tools only once running on your machine, and the maintainer has not provided a tool list.
Details
From the project README@valv/mcp
Point it at a database URL. Your agent queries it safely. No SQL, no code.
A zero-config MCP server built on valv. Give it a connection string and it introspects your live schema, serves four tools (list_resources, search_resources, describe_resource, query) read-only by default, and enforces your policies — no SQL ever reaches the model, and it can only read what you allow.
Works with PostgreSQL, MySQL, SQLite, CockroachDB, ClickHouse, and MongoDB.
Guided setup
The fastest way in — it probes your database, lets you choose access, and writes the config:
npx @valv/mcp init
It takes either a connection string or individual fields (host, port, user, password, database), confirms the dialect, connects and shows your tables, then offers read-only / pick-tables / a policy-file stub. It then merges the server entry into the client of your choice — Claude Code, Claude Desktop, Cursor, or Codex — at project or global scope, leaving any existing config in place. Lastly it offers to install the valv skill, which teaches the agent how to query valv and turn results into interactive chart-report HTML files — as a skill for Claude Code (.claude/skills), Codex (.agents/skills), or Cursor (.cursor/skills), at project or global scope. Finally it can copy a kickstart prompt to your clipboard — paste it into your agent to explore the schema (seeding .valv/notes.md for future queries) and generate a single interactive valv-map.html overview of the database.
Manual setup
Add it to your .mcp.json (or Claude Desktop config):
{
"mcpServers": {
"db": {
"command": "npx",
"args": ["-y", "@valv/mcp"],
"env": { "DATABASE_URL": "postgresql://user:pass@localhost:5432/mydb" }
}
}
}
For ClickHouse, use its HTTP URL and a database name:
"env": { "DATABASE_URL": "http://localhost:8123", "VALV_DATABASE": "analytics" }
For MongoDB, use a standard connection string. Set VALV_DATABASE when the
URL does not select a database:
"env": { "DATABASE_URL": "mongodb://localhost:27017", "VALV_DATABASE": "analytics" }
Configuration
All via environment variables:
| Variable | Description |
|---|---|
DATABASE_URL | Connection string (required; or pass as the first CLI arg). |
VALV_PROVIDER | postgresql | mysql | sqlite | mongodb | clickhouse. Inferred from the URL when omitted. |
VALV_DATABASE | Database name for ClickHouse or MongoDB. |
VALV_TABLES | Comma-separated allow-list — only these tables are exposed. |
VALV_EXCLUDE | Comma-separated deny-list, applied after the allow-list. |
VALV_POLICY_FILE | Path to a policy module (below) for tenant scoping / hidden fields. |
VALV_CONTEXT | JSON context the policy reads (e.g. {"tenant":{"id":"acme"}}). |
VALV_HTTP_PORT | Serve over Streamable HTTP on this port instead of stdio. |
Policy file
Without one, access is read-only across all tables. To restrict what the agent can see — which tables, which columns — point VALV_POLICY_FILE at a module that receives the configured valv instance:
// valv.policy.cjs
module.exports = (valv) => {
valv.policy("orders", () => ({
read: true, // allow reads (or { column: value } to filter rows)
fields: { deny: ["internal_notes"] }, // hide columns from the agent
}))
// Tables without a policy are denied (deny-all).
}
Need per-request row scoping by tenant/user? That belongs in the app-controlled path, where your code supplies real identity per request — use @valv/mcp-sdk (or pass a fixed VALV_CONTEXT and read it in the policy here).
License
MIT
Comments
New to MCP?
From what the protocol is to installing your first server, these answers cover most first questions.
An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.