用 MCP 把 PostgreSQL 接入 Claude Code,配置只读账号和权限控制,让 Claude 直接读 schema、写查询、分析数据,不再需要手动粘贴表结构。
接了数据库之后,Claude Code 的工作方式会变。你不需要把表结构复制进 prompt,不需要告诉它字段叫什么——它直接连上去,自己读 schema,自己写查询,结果出来就给你分析。
这篇文章用 PostgreSQL 做示例,从配置到实际使用完整走一遍。
官方维护的 @modelcontextprotocol/server-postgres 支持:
只读。这个 Server 设计上只做查询,不执行 INSERT/UPDATE/DELETE。
npm install -g @modelcontextprotocol/server-postgres
编辑 .claude/settings.json(项目级):
{
"mcpServers": {
"db": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-postgres",
"postgresql://readonly_user:password@localhost:5432/myapp_production"
]
}
}
}
连接字符串格式:postgresql://USER:PASSWORD@HOST:PORT/DATABASE
如果不想把密码写进配置文件,用环境变量:
{
"mcpServers": {
"db": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres"],
"env": {
"DATABASE_URL": "postgresql://readonly_user:password@localhost:5432/myapp_production"
}
}
}
}
注意:.claude/settings.json 如果要提交 git,确保里面没有明文密码。敏感配置放 .claude/settings.local.json(加入 .gitignore)。
不要把有写权限的账号给 Claude 用。在 PostgreSQL 里建一个只读账号:
-- 创建只读用户
CREATE USER claude_readonly WITH PASSWORD 'your_password';
-- 授予连接权限
GRANT CONNECT ON DATABASE myapp_production TO claude_readonly;
-- 授予 schema 使用权限
GRANT USAGE ON SCHEMA public TO claude_readonly;
-- 授予所有表的查询权限
GRANT SELECT ON ALL TABLES IN SCHEMA public TO claude_readonly;
-- 确保未来新建的表也有权限
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT ON TABLES TO claude_readonly;
如果有些表不想让 Claude 看(比如 sessions、audit_logs),就不要授权那些表,或者把它们放在单独的 schema 里。
重启 Claude Code,然后问它:
列出数据库里有哪些表
如果 Claude 返回了表名列表而不是说"我没有访问数据库的能力",说明 MCP 连接成功。
配置完成后,Claude 能做的事情变了很多。下面是几个真实场景。
场景一:理解数据结构
这个数据库的 users 和 orders 表是什么关系?
有没有外键约束?
Claude 会直接查 information_schema 读取表结构和约束,然后给你一个清晰的解释,而不是让你先把 schema 粘给它。
场景二:数据分析
最近 30 天注册的用户里,下过订单的比例是多少?
按注册渠道分组
Claude 会写 SQL,执行,然后分析结果。如果查询写错了(比如字段名对不上),它能直接看到报错然后自己修。
场景三:排查问题
orders 表里有 status = 'pending' 但 created_at 超过 7 天的记录,
看看有多少,最近一条是什么时候
这类临时排查,过去要你自己写 SQL 或者去数据库工具里手动查。现在直接说需求就行。
场景四:辅助开发
我要给 users 表加一个 last_login_at 字段,
帮我写迁移 SQL,顺便检查一下现有索引够不够用
Claude 会先看当前表结构,再写迁移,同时分析索引情况给出建议。
默认情况下,Claude 能看到你授权的所有表的完整 schema 和数据。根据实际需要,可以做以下限制:
按表控制
不给某些表授权:
-- 只授权特定表,而不是全部
GRANT SELECT ON TABLE users, orders, products TO claude_readonly;
-- 不授权 sessions, payment_tokens, audit_logs 等敏感表
用 view 过滤敏感字段
如果表里有敏感字段(密码 hash、API key、手机号),建一个 view 屏蔽掉:
CREATE VIEW users_safe AS
SELECT id, email, created_at, plan, status
FROM users;
-- 不包含 password_digest, phone, payment_method_id
GRANT SELECT ON users_safe TO claude_readonly;
-- 不授权原表
Claude 只能查 view,看不到原始字段。
限制行数
@modelcontextprotocol/server-postgres 默认对查询结果有行数限制(通常 1000 行),防止把整张表拉回来。这个限制是合理的,不需要调大。
如果生产数据库在远程服务器,通常不会直接暴露端口。可以用 SSH 隧道:
# 在本地建隧道,把 localhost:5433 映射到远程服务器的 5432
ssh -L 5433:localhost:5432 [email protected] -N
然后配置文件里用本地端口:
"postgresql://readonly_user:password@localhost:5433/myapp_production"
或者用 pgBouncer 这类连接池中间件。
如果项目有多个数据库(主库 + 分析库 + 缓存库),可以配置多个 MCP Server:
{
"mcpServers": {
"main-db": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres", "postgresql://...主库..."]
},
"analytics-db": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres", "postgresql://...分析库..."]
}
}
}
Claude 会同时连两个库,你告诉它去哪个库查就行。
接了数据库之后,最明显的变化是:和 Claude 讨论数据相关的问题不需要铺垫了。不用先解释表结构,不用先说字段叫什么类型,直接说需求,它自己去查。
排查 bug 的时候尤其有用。过去的流程是:你查数据库 → 复制结果 → 粘给 Claude → 它分析。现在是:你描述问题 → 它自己查 → 直接给结论。