[{"data":1,"prerenderedAt":823},["ShallowReactive",2],{"header-counts":3,"playbook-onboarding\u002Fcursor-mcp-database":6,"footer-counts":822},{"tools":4,"reviews":5},65,7,{"id":7,"title":8,"body":9,"category":802,"cover":803,"description":804,"extension":805,"meta":806,"navigation":474,"path":807,"published":808,"relatedTools":809,"seo":814,"stem":815,"tags":816,"updated":808,"__hash__":821},"playbook\u002Fplaybook\u002Fonboarding\u002Fcursor-mcp-database.md","Cursor + MCP 让 AI 直接操作数据库：从零到生产",{"type":10,"value":11,"toc":785},"minimark",[12,16,29,33,42,45,53,57,60,95,98,206,209,213,217,223,334,338,415,421,424,427,516,520,524,527,535,538,557,561,567,569,587,591,597,599,617,620,699,705,708,781],[13,14,15],"h2",{"id":15},"适用场景",[17,18,19,23,26],"ul",{},[20,21,22],"li",{},"开发时频繁需要查表结构、跑 SQL 验证",[20,24,25],{},"AI 生成代码时需要知道数据库 schema",[20,27,28],{},"想让 AI 帮写数据库迁移文件",[13,30,32],{"id":31},"为什么用-mcp-而不是复制粘贴","为什么用 MCP 而不是复制粘贴",[34,35,36,37,41],"p",{},"传统做法：手动跑 ",[38,39,40],"code",{},"\\d table_name"," → 复制结果 → 粘给 Cursor → AI 生成 SQL → 手动执行验证。",[34,43,44],{},"MCP 做法：Cursor 直接连数据库 → AI 自己查 schema → 生成 SQL → 自己执行验证 → 返回结果。",[34,46,47,48,52],{},"省的是",[49,50,51],"strong",{},"中间的复制粘贴往返","。在复杂查询调试时，这个往返可能 5-10 次。",[13,54,56],{"id":55},"第一步装-mcp-postgresql-server","第一步：装 MCP PostgreSQL Server",[34,58,59],{},"用 Smithery 一行装好：",[61,62,67],"pre",{"className":63,"code":64,"language":65,"meta":66,"style":66},"language-bash shiki shiki-themes github-light github-dark","npx @smithery\u002Fcli install @modelcontextprotocol\u002Fserver-postgres --client cursor\n","bash","",[38,68,69],{"__ignoreMap":66},[70,71,74,78,82,85,88,92],"span",{"class":72,"line":73},"line",1,[70,75,77],{"class":76},"sScJk","npx",[70,79,81],{"class":80},"sZZnC"," @smithery\u002Fcli",[70,83,84],{"class":80}," install",[70,86,87],{"class":80}," @modelcontextprotocol\u002Fserver-postgres",[70,89,91],{"class":90},"sj4cs"," --client",[70,93,94],{"class":80}," cursor\n",[34,96,97],{},"或手动配 Cursor Settings → MCP → Add Server：",[61,99,103],{"className":100,"code":101,"language":102,"meta":66,"style":66},"language-json shiki shiki-themes github-light github-dark","{\n  \"mcpServers\": {\n    \"postgres\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@modelcontextprotocol\u002Fserver-postgres\"],\n      \"env\": {\n        \"DATABASE_URL\": \"postgresql:\u002F\u002Fuser:pass@localhost:5432\u002Fmydb\"\n      }\n    }\n  }\n}\n","json",[38,104,105,111,120,128,143,164,172,182,188,194,200],{"__ignoreMap":66},[70,106,107],{"class":72,"line":73},[70,108,110],{"class":109},"sVt8B","{\n",[70,112,114,117],{"class":72,"line":113},2,[70,115,116],{"class":90},"  \"mcpServers\"",[70,118,119],{"class":109},": {\n",[70,121,123,126],{"class":72,"line":122},3,[70,124,125],{"class":90},"    \"postgres\"",[70,127,119],{"class":109},[70,129,131,134,137,140],{"class":72,"line":130},4,[70,132,133],{"class":90},"      \"command\"",[70,135,136],{"class":109},": ",[70,138,139],{"class":80},"\"npx\"",[70,141,142],{"class":109},",\n",[70,144,146,149,152,155,158,161],{"class":72,"line":145},5,[70,147,148],{"class":90},"      \"args\"",[70,150,151],{"class":109},": [",[70,153,154],{"class":80},"\"-y\"",[70,156,157],{"class":109},", ",[70,159,160],{"class":80},"\"@modelcontextprotocol\u002Fserver-postgres\"",[70,162,163],{"class":109},"],\n",[70,165,167,170],{"class":72,"line":166},6,[70,168,169],{"class":90},"      \"env\"",[70,171,119],{"class":109},[70,173,174,177,179],{"class":72,"line":5},[70,175,176],{"class":90},"        \"DATABASE_URL\"",[70,178,136],{"class":109},[70,180,181],{"class":80},"\"postgresql:\u002F\u002Fuser:pass@localhost:5432\u002Fmydb\"\n",[70,183,185],{"class":72,"line":184},8,[70,186,187],{"class":109},"      }\n",[70,189,191],{"class":72,"line":190},9,[70,192,193],{"class":109},"    }\n",[70,195,197],{"class":72,"line":196},10,[70,198,199],{"class":109},"  }\n",[70,201,203],{"class":72,"line":202},11,[70,204,205],{"class":109},"}\n",[34,207,208],{},"重启 Cursor，Agent 模式现在能查数据库了。",[13,210,212],{"id":211},"第二步安全配置重要","第二步：安全配置（重要）",[214,215,216],"h3",{"id":216},"用只读账号",[34,218,219,222],{},[49,220,221],{},"绝对不要用超级用户账号连 MCP。"," 创建只读账号：",[61,224,228],{"className":225,"code":226,"language":227,"meta":66,"style":66},"language-sql shiki shiki-themes github-light github-dark","CREATE ROLE mcp_readonly WITH LOGIN PASSWORD 'xxx';\nGRANT USAGE ON SCHEMA public TO mcp_readonly;\nGRANT SELECT ON ALL TABLES IN SCHEMA public TO mcp_readonly;\nALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO mcp_readonly;\n","sql",[38,229,230,257,280,304],{"__ignoreMap":66},[70,231,232,236,239,242,245,248,251,254],{"class":72,"line":73},[70,233,235],{"class":234},"szBVR","CREATE",[70,237,238],{"class":234}," ROLE",[70,240,241],{"class":109}," mcp_readonly ",[70,243,244],{"class":234},"WITH",[70,246,247],{"class":234}," LOGIN",[70,249,250],{"class":234}," PASSWORD",[70,252,253],{"class":80}," 'xxx'",[70,255,256],{"class":109},";\n",[70,258,259,262,265,268,271,274,277],{"class":72,"line":113},[70,260,261],{"class":234},"GRANT",[70,263,264],{"class":109}," USAGE ",[70,266,267],{"class":234},"ON",[70,269,270],{"class":234}," SCHEMA",[70,272,273],{"class":109}," public ",[70,275,276],{"class":234},"TO",[70,278,279],{"class":109}," mcp_readonly;\n",[70,281,282,284,287,290,293,296,298,300,302],{"class":72,"line":122},[70,283,261],{"class":234},[70,285,286],{"class":234}," SELECT",[70,288,289],{"class":234}," ON",[70,291,292],{"class":109}," ALL TABLES ",[70,294,295],{"class":234},"IN",[70,297,270],{"class":234},[70,299,273],{"class":109},[70,301,276],{"class":234},[70,303,279],{"class":109},[70,305,306,309,312,315,317,319,321,323,325,327,330,332],{"class":72,"line":130},[70,307,308],{"class":234},"ALTER",[70,310,311],{"class":234}," DEFAULT",[70,313,314],{"class":109}," PRIVILEGES ",[70,316,295],{"class":234},[70,318,270],{"class":234},[70,320,273],{"class":109},[70,322,261],{"class":234},[70,324,286],{"class":234},[70,326,289],{"class":234},[70,328,329],{"class":109}," TABLES ",[70,331,276],{"class":234},[70,333,279],{"class":109},[214,335,337],{"id":336},"开发生产隔离","开发\u002F生产隔离",[61,339,341],{"className":100,"code":340,"language":102,"meta":66,"style":66},"{\n  \"mcpServers\": {\n    \"postgres-dev\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@modelcontextprotocol\u002Fserver-postgres\"],\n      \"env\": {\n        \"DATABASE_URL\": \"postgresql:\u002F\u002Fmcp_readonly:xxx@localhost:5432\u002Fmydb_dev\"\n      }\n    }\n  }\n}\n",[38,342,343,347,353,360,370,384,390,399,403,407,411],{"__ignoreMap":66},[70,344,345],{"class":72,"line":73},[70,346,110],{"class":109},[70,348,349,351],{"class":72,"line":113},[70,350,116],{"class":90},[70,352,119],{"class":109},[70,354,355,358],{"class":72,"line":122},[70,356,357],{"class":90},"    \"postgres-dev\"",[70,359,119],{"class":109},[70,361,362,364,366,368],{"class":72,"line":130},[70,363,133],{"class":90},[70,365,136],{"class":109},[70,367,139],{"class":80},[70,369,142],{"class":109},[70,371,372,374,376,378,380,382],{"class":72,"line":145},[70,373,148],{"class":90},[70,375,151],{"class":109},[70,377,154],{"class":80},[70,379,157],{"class":109},[70,381,160],{"class":80},[70,383,163],{"class":109},[70,385,386,388],{"class":72,"line":166},[70,387,169],{"class":90},[70,389,119],{"class":109},[70,391,392,394,396],{"class":72,"line":5},[70,393,176],{"class":90},[70,395,136],{"class":109},[70,397,398],{"class":80},"\"postgresql:\u002F\u002Fmcp_readonly:xxx@localhost:5432\u002Fmydb_dev\"\n",[70,400,401],{"class":72,"line":184},[70,402,187],{"class":109},[70,404,405],{"class":72,"line":190},[70,406,193],{"class":109},[70,408,409],{"class":72,"line":196},[70,410,199],{"class":109},[70,412,413],{"class":72,"line":202},[70,414,205],{"class":109},[34,416,417,420],{},[49,418,419],{},"只在 dev 环境配 MCP","。生产数据库永远不连 MCP。",[214,422,423],{"id":423},"限制可查的表",[34,425,426],{},"如果有些表（用户密码、token）不想让 AI 看到，用视图：",[61,428,430],{"className":225,"code":429,"language":227,"meta":66,"style":66},"CREATE VIEW public_safe.users_safe AS\n  SELECT id, username, created_at FROM public.users;\n\nREVOKE SELECT ON public.users FROM mcp_readonly;\nGRANT SELECT ON public_safe.users_safe TO mcp_readonly;\n",[38,431,432,448,470,476,496],{"__ignoreMap":66},[70,433,434,436,439,442,445],{"class":72,"line":73},[70,435,235],{"class":234},[70,437,438],{"class":234}," VIEW",[70,440,441],{"class":76}," public_safe",[70,443,444],{"class":109},".users_safe ",[70,446,447],{"class":234},"AS\n",[70,449,450,453,456,459,462,465,468],{"class":72,"line":113},[70,451,452],{"class":234},"  SELECT",[70,454,455],{"class":109}," id, username, created_at ",[70,457,458],{"class":234},"FROM",[70,460,461],{"class":90}," public",[70,463,464],{"class":109},".",[70,466,467],{"class":90},"users",[70,469,256],{"class":109},[70,471,472],{"class":72,"line":122},[70,473,475],{"emptyLinePlaceholder":474},true,"\n",[70,477,478,481,483,485,487,489,491,494],{"class":72,"line":130},[70,479,480],{"class":234},"REVOKE",[70,482,286],{"class":234},[70,484,289],{"class":234},[70,486,461],{"class":90},[70,488,464],{"class":109},[70,490,467],{"class":90},[70,492,493],{"class":234}," FROM",[70,495,279],{"class":109},[70,497,498,500,502,504,506,508,511,514],{"class":72,"line":145},[70,499,261],{"class":234},[70,501,286],{"class":234},[70,503,289],{"class":234},[70,505,441],{"class":90},[70,507,464],{"class":109},[70,509,510],{"class":90},"users_safe",[70,512,513],{"class":234}," TO",[70,515,279],{"class":109},[13,517,519],{"id":518},"第三步实战用法","第三步：实战用法",[214,521,523],{"id":522},"场景一查-schema-生成代码","场景一：查 schema 生成代码",[34,525,526],{},"在 Cursor Agent 模式输入：",[61,528,533],{"className":529,"code":531,"language":532},[530],"language-text","帮我写一个查询用户订单的 API，需要分页\n","text",[38,534,531],{"__ignoreMap":66},[34,536,537],{},"Cursor 会：",[539,540,541,548,554],"ol",{},[20,542,543,544,547],{},"调 MCP ",[38,545,546],{},"list_tables"," 看有哪些表",[20,549,543,550,553],{},[38,551,552],{},"describe_table"," 看 orders 和 users 表结构",[20,555,556],{},"生成 JOIN 查询 + 分页代码",[214,558,560],{"id":559},"场景二调试-sql","场景二：调试 SQL",[61,562,565],{"className":563,"code":564,"language":532},[530],"这个查询很慢，帮我优化\nSELECT * FROM orders o JOIN users u ON o.user_id = u.id WHERE o.status = 'pending'\n",[38,566,564],{"__ignoreMap":66},[34,568,537],{},[539,570,571,578,581,584],{},[20,572,573,574,577],{},"跑 ",[38,575,576],{},"EXPLAIN ANALYZE"," 看执行计划",[20,579,580],{},"发现全表扫描",[20,582,583],{},"建议加索引",[20,585,586],{},"生成 migration 文件",[214,588,590],{"id":589},"场景三生成迁移","场景三：生成迁移",[61,592,595],{"className":593,"code":594,"language":532},[530],"给 orders 表加一个 shipping_address 字段，类型 jsonb，可空\n",[38,596,594],{"__ignoreMap":66},[34,598,537],{},[539,600,601,604,611,614],{},[20,602,603],{},"查当前 orders 表结构",[20,605,606,607,610],{},"生成 ",[38,608,609],{},"ALTER TABLE"," SQL",[20,612,613],{},"生成 Drizzle\u002FPrisma migration 文件",[20,615,616],{},"生成回滚 SQL",[13,618,619],{"id":619},"权限边界",[621,622,623,639],"table",{},[624,625,626],"thead",{},[627,628,629,633,636],"tr",{},[630,631,632],"th",{},"操作",[630,634,635],{},"只读 MCP",[630,637,638],{},"可写 MCP",[640,641,642,653,662,671,681,691],"tbody",{},[627,643,644,648,651],{},[645,646,647],"td",{},"查表结构",[645,649,650],{},"✅",[645,652,650],{},[627,654,655,658,660],{},[645,656,657],{},"SELECT 查询",[645,659,650],{},[645,661,650],{},[627,663,664,667,669],{},[645,665,666],{},"EXPLAIN",[645,668,650],{},[645,670,650],{},[627,672,673,676,679],{},[645,674,675],{},"INSERT\u002FUPDATE\u002FDELETE",[645,677,678],{},"❌",[645,680,650],{},[627,682,683,686,688],{},[645,684,685],{},"CREATE\u002FDROP TABLE",[645,687,678],{},[645,689,690],{},"⚠️ 需额外授权",[627,692,693,695,697],{},[645,694,609],{},[645,696,678],{},[645,698,690],{},[34,700,701,704],{},[49,702,703],{},"建议","：日常用只读 MCP，需要写操作时切到可写 MCP 并加确认步骤。",[13,706,707],{"id":707},"踩坑记录",[539,709,710,716,757,763],{},[20,711,712,715],{},[49,713,714],{},"MCP Server 连接池","：默认无连接池，大量查询会打满 PG 连接。用 PgBouncer 做连接池。",[20,717,718,721,722,725,726,729,730],{},[49,719,720],{},"大表 SELECT","：AI 可能跑 ",[38,723,724],{},"SELECT * FROM huge_table","。设 ",[38,727,728],{},"statement_timeout"," 防止卡死：\n",[61,731,733],{"className":225,"code":732,"language":227,"meta":66,"style":66},"ALTER ROLE mcp_readonly SET statement_timeout = '10s';\n",[38,734,735],{"__ignoreMap":66},[70,736,737,739,741,743,746,749,752,755],{"class":72,"line":73},[70,738,308],{"class":234},[70,740,238],{"class":234},[70,742,241],{"class":109},[70,744,745],{"class":234},"SET",[70,747,748],{"class":109}," statement_timeout ",[70,750,751],{"class":234},"=",[70,753,754],{"class":80}," '10s'",[70,756,256],{"class":109},[20,758,759,762],{},[49,760,761],{},"Cursor MCP 不支持事务","：每个 SQL 是独立执行，不能 BEGIN\u002FCOMMIT。多步操作用存储过程。",[20,764,765,768,769,772,773,776,777,780],{},[49,766,767],{},"DATABASE_URL 泄露","：",[38,770,771],{},".cursor\u002Fmcp.json"," 可能被 git 提交。加到 ",[38,774,775],{},".gitignore","，用 ",[38,778,779],{},".cursor\u002Fmcp.local.json","。",[782,783,784],"style",{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}",{"title":66,"searchDepth":122,"depth":122,"links":786},[787,788,789,790,795,800,801],{"id":15,"depth":113,"text":15},{"id":31,"depth":113,"text":32},{"id":55,"depth":113,"text":56},{"id":211,"depth":113,"text":212,"children":791},[792,793,794],{"id":216,"depth":122,"text":216},{"id":336,"depth":122,"text":337},{"id":423,"depth":122,"text":423},{"id":518,"depth":113,"text":519,"children":796},[797,798,799],{"id":522,"depth":122,"text":523},{"id":559,"depth":122,"text":560},{"id":589,"depth":122,"text":590},{"id":619,"depth":113,"text":619},{"id":707,"depth":113,"text":707},"onboarding","\u002Fog\u002Fplaybook\u002Fcursor-mcp-database.png","用 MCP 协议让 Cursor \u002F Claude Code 直接读写 PostgreSQL——AI 能查表结构、跑 SQL、生成迁移文件。含安全配置、权限边界和踩坑记录。","md",{},"\u002Fplaybook\u002Fonboarding\u002Fcursor-mcp-database","2026-06-21",[810,811,812,813],"agent\u002Fprotocol\u002Fsmithery","agent\u002Fprotocol\u002Fcomposio","agent\u002Fprotocol\u002Fmcp-toolbox","coding\u002Fide\u002Fcursor",{"title":8,"description":804},"playbook\u002Fonboarding\u002Fcursor-mcp-database",[817,818,819,820],"MCP","Cursor","PostgreSQL","数据库","Xz0aDqhIFWiE0v5sBvsHZqBKQn_S_xNSzHCeNesIXxA",{"tools":4,"reviews":5,"playbooks":196,"news":184},1782316489335]