给 Claude Code 接入数据库:用 MCP 直接查真实数据

用 MCP 把 PostgreSQL 接入 Claude Code,配置只读账号和权限控制,让 Claude 直接读 schema、写查询、分析数据,不再需要手动粘贴表结构。


接了数据库之后,Claude Code 的工作方式会变。你不需要把表结构复制进 prompt,不需要告诉它字段叫什么——它直接连上去,自己读 schema,自己写查询,结果出来就给你分析。

这篇文章用 PostgreSQL 做示例,从配置到实际使用完整走一遍。

用哪个 MCP Server

官方维护的 @modelcontextprotocol/server-postgres 支持:

  • 读取所有表的 schema(字段名、类型、约束)
  • 执行 SQL 查询并返回结果
  • 支持多 schema

只读。这个 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 看(比如 sessionsaudit_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 能看到什么

默认情况下,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 → 它分析。现在是:你描述问题 → 它自己查 → 直接给结论。