[{"data":1,"prerenderedAt":667},["ShallowReactive",2],{"docs-\u002Fdocs\u002Fmcp\u002Fsafety-and-privacy":3},{"id":4,"title":5,"body":6,"description":658,"extension":659,"meta":660,"navigation":661,"path":662,"redirect":663,"seo":664,"stem":665,"__hash__":666},"docs\u002Fdocs\u002Fmcp\u002Fsafety-and-privacy.md","MCP safety and privacy",{"type":7,"value":8,"toc":647},"minimark",[9,13,26,31,34,104,107,111,114,158,162,165,325,345,349,368,372,379,403,410,414,421,444,447,451,454,464,489,495,544,550,553,556,603,610,614,643],[10,11,5],"h1",{"id":12},"mcp-safety-and-privacy",[14,15,16,17,21,22,25],"p",{},"DBConvert Streams MCP server is ",[18,19,20],"strong",{},"read-only by design"," and runs on ",[18,23,24],{},"your own infrastructure"," — locally on your machine over stdio (the desktop app), or as a service inside your DBConvert Streams deployment over HTTP (Docker \u002F server). Either way it's your hardware, never ours. This page is the complete list of guarantees and tradeoffs.",[27,28,30],"h2",{"id":29},"what-cannot-happen","What cannot happen",[14,32,33],{},"Nothing your AI does through the MCP server can change your data, configuration, or stream state:",[35,36,37,55,67,70,73,76,84,87,90,93],"ul",{},[38,39,40,41,45,46,45,49,45,52],"li",{},"No ",[42,43,44],"code",{},"INSERT"," \u002F ",[42,47,48],{},"UPDATE",[42,50,51],{},"DELETE",[42,53,54],{},"TRUNCATE",[38,56,40,57,45,60,45,63,66],{},[42,58,59],{},"DROP",[42,61,62],{},"ALTER",[42,64,65],{},"CREATE"," \u002F DDL of any kind",[38,68,69],{},"No index creation",[38,71,72],{},"No row editing",[38,74,75],{},"No connection edits, additions, or deletions",[38,77,78,79,83],{},"No stream control ",[80,81,82],"em",{},"in this version"," — no starting, stopping, pausing, resuming, or resetting streams, and no CDC checkpoint or bootstrap-state resets (this may change later, behind explicit safeguards)",[38,85,86],{},"No file writes, deletes, or uploads",[38,88,89],{},"No credential changes",[38,91,92],{},"No S3 object mutation",[38,94,95,96,99,100,103],{},"No arbitrary SQL — only ",[42,97,98],{},"SELECT"," and ",[42,101,102],{},"WITH ... SELECT"," statements pass the safety filter. Everything else is rejected at the MCP server before reaching your database",[14,105,106],{},"When the AI suggests a change, you (or DBConvert Streams via the UI) run it. The AI never touches the trigger.",[27,108,110],{"id":109},"what-the-ai-sees","What the AI sees",[14,112,113],{},"When you ask your AI assistant to inspect or analyze something, the MCP server returns:",[35,115,116,123,128,134,140,146,152],{},[38,117,118,119,122],{},"Connection ",[18,120,121],{},"names, types, and IDs"," (never DSNs or passwords)",[38,124,125],{},[18,126,127],{},"Database, schema, and table names",[38,129,130,133],{},[18,131,132],{},"Column definitions and metadata"," (types, nullability, defaults, indexes, foreign keys, DDL)",[38,135,136,139],{},[18,137,138],{},"Sample rows"," from tables you ask about (bounded by default to 100 rows, max 1000)",[38,141,142,145],{},[18,143,144],{},"SELECT query results"," (same row caps)",[38,147,148,151],{},[18,149,150],{},"File names, schemas, and sample data"," from local file connections",[38,153,154,157],{},[18,155,156],{},"Stream status, statistics, recent errors, and log entries"," (redacted — see below)",[27,159,161],{"id":160},"log-redaction","Log redaction",[14,163,164],{},"Anything returned from stream logs passes through six redaction layers before reaching the AI:",[166,167,168,184],"table",{},[169,170,171],"thead",{},[172,173,174,178,181],"tr",{},[175,176,177],"th",{},"What gets replaced",[175,179,180],{},"Example before",[175,182,183],{},"Example after",[185,186,187,244,259,274,289,304],"tbody",{},[172,188,189,234,239],{},[190,191,192,193,196,197,196,200,196,203,196,206,196,209,196,212,196,215,196,218,196,221,196,224,196,227,196,230,233],"td",{},"Field-name match (any field whose name contains ",[42,194,195],{},"password",", ",[42,198,199],{},"passwd",[42,201,202],{},"secret",[42,204,205],{},"apikey",[42,207,208],{},"api_key",[42,210,211],{},"token",[42,213,214],{},"credential",[42,216,217],{},"credentials",[42,219,220],{},"accesskey",[42,222,223],{},"access_key",[42,225,226],{},"privatekey",[42,228,229],{},"private_key",[42,231,232],{},"passphrase",")",[190,235,236],{},[42,237,238],{},"\"apikey\": \"sk-abc...\"",[190,240,241],{},[42,242,243],{},"\"apikey\": \"REDACTED\"",[172,245,246,249,254],{},[190,247,248],{},"DSN credentials",[190,250,251],{},[42,252,253],{},"postgres:\u002F\u002Fadmin:s3cr3t@host:5432\u002Fdb",[190,255,256],{},[42,257,258],{},"postgres:\u002F\u002Fadmin:REDACTED@host:5432\u002Fdb",[172,260,261,264,269],{},[190,262,263],{},"Bearer tokens",[190,265,266],{},[42,267,268],{},"Bearer eyJhb...",[190,270,271],{},[42,272,273],{},"Bearer REDACTED",[172,275,276,279,284],{},[190,277,278],{},"Authorization headers",[190,280,281],{},[42,282,283],{},"Authorization=...",[190,285,286],{},[42,287,288],{},"Authorization=REDACTED",[172,290,291,294,299],{},[190,292,293],{},"Sensitive-keyword values in SQL",[190,295,296],{},[42,297,298],{},"password = 'abc'",[190,300,301],{},[42,302,303],{},"password = REDACTED",[172,305,306,309,317],{},[190,307,308],{},"Email and IPv4 addresses",[190,310,311,196,314],{},[42,312,313],{},"user@example.com",[42,315,316],{},"10.0.0.5",[190,318,319,196,322],{},[42,320,321],{},"***@***.***",[42,323,324],{},"***.***.***.***",[14,326,327,328,196,331,196,334,196,337,340,341,344],{},"Field-name matching is case-insensitive and uses substring matching, so ",[42,329,330],{},"apiKey",[42,332,333],{},"API_KEY",[42,335,336],{},"user_password",[42,338,339],{},"ssh_passphrase",", and ",[42,342,343],{},"client_secret"," all hit.",[27,346,348],{"id":347},"response-size-limits","Response size limits",[14,350,351,352,355,356,359,360,363,364,367],{},"Tool responses are capped at ",[18,353,354],{},"256 KB"," (soft target) and ",[18,357,358],{},"1 MB"," (hard cap). If the AI asks for a huge result, the server returns a truncated answer with ",[42,361,362],{},"truncated: true"," and a ",[42,365,366],{},"Warnings"," entry. The AI sees the signal and asks you to narrow the query rather than silently returning partial data.",[27,369,371],{"id":370},"activity-logging","Activity logging",[14,373,374,375,378],{},"Every tool call your AI makes is recorded in the MCP server log file (",[42,376,377],{},"stream-mcp.log"," next to the workspace database for the desktop app; inside the container for a Docker deployment) with:",[35,380,381,387,390,393,396],{},[38,382,383,384,233],{},"Tool name (e.g. ",[42,385,386],{},"dbconvert_run_select",[38,388,389],{},"Your user ID",[38,391,392],{},"Duration",[38,394,395],{},"Output size in bytes",[38,397,398,399,402],{},"Field ",[18,400,401],{},"names"," the AI passed — never the values",[14,404,405,406,409],{},"No queries, DSNs, or sensitive values are written to the audit log. If you want to know what your AI did, tail the log and look for ",[42,407,408],{},"mcp tool call"," entries.",[27,411,413],{"id":412},"what-goes-to-your-ai-provider","What goes to your AI provider",[14,415,416,417,420],{},"The MCP server never sends your data anywhere — your ",[18,418,419],{},"AI client"," does. Keep the two roles separate:",[35,422,423,434],{},[38,424,425,426,429,430,433],{},"The ",[18,427,428],{},"MCP server is yours, not ours",". It runs on your machine over stdio (desktop app) or inside your own DBConvert Streams deployment over HTTP (Docker \u002F server), and only ever ",[18,431,432],{},"responds"," to your AI client's requests — over standard input\u002Foutput locally, or over HTTPS to your own host. It never initiates a connection to DBConvert or any AI provider; it does not send anything anywhere on its own.",[38,435,436,437,440,441],{},"Your ",[18,438,439],{},"AI client is a separate program"," (Claude Code, Cursor, Copilot, etc.) that sends prompts and tool results to its provider (Anthropic, OpenAI, etc.) so the model can respond. ",[18,442,443],{},"Whatever the AI sees, the provider sees.",[14,445,446],{},"So any sample rows, query results, schema definitions, or log entries the AI fetches via MCP get sent to your AI provider as part of the chat context.",[27,448,450],{"id":449},"keeping-data-from-the-ai-provider","Keeping data from the AI provider",[14,452,453],{},"If some data must never leave your environment, use these controls — strongest first.",[14,455,456,459,460,463],{},[18,457,458],{},"1. Restrict at the database."," The strongest line of defense, because it limits what ",[80,461,462],{},"any"," tool can read:",[35,465,466,473,486],{},[38,467,468,469,472],{},"The MCP server can read ",[18,470,471],{},"every"," connection in its workspace — there's no per-connection opt-out, and simply not asking about one is not a hard guarantee (an over-eager or prompt-injected AI can still query it).",[38,474,475,476,479,480,485],{},"The fix: connect with a ",[18,477,478],{},"read-only database user that cannot see the sensitive tables"," — see ",[481,482,484],"a",{"href":483},"#read-only-database-users","Read-only database users"," below for a copy-paste grant. The connection itself is fine to keep for Data Explorer and streams.",[38,487,488],{},"To rule the data out completely: don't connect an MCP client to that workspace at all.",[14,490,491,494],{},[18,492,493],{},"2. Limit which tools the AI can call."," Turn off what you don't need so the AI can inspect but never run queries:",[35,496,497,503,513,523],{},[38,498,499,502],{},[18,500,501],{},"Copilot"," — the 🔧 tool picker",[38,504,505,508,509,512],{},[18,506,507],{},"Cursor"," — ",[18,510,511],{},"Settings → Tools & MCP",", then expand the server",[38,514,515,518,519,522],{},[18,516,517],{},"Windsurf"," — the ",[18,520,521],{},"MCPs"," icon in the Cascade panel",[38,524,525,528,529,532,533,536,537,540,541],{},[18,526,527],{},"Claude Code"," — permission rules: add the tool to ",[42,530,531],{},"permissions.deny"," via ",[42,534,535],{},"\u002Fpermissions"," or ",[42,538,539],{},"settings.json",", e.g. ",[42,542,543],{},"mcp__dbconvert-streams__dbconvert_run_select",[14,545,546,549],{},[18,547,548],{},"3. Use a self-hosted AI"," if your client supports it — the MCP server works with any MCP-compliant client, so nothing has to reach a third-party provider at all.",[27,551,484],{"id":552},"read-only-database-users",[14,554,555],{},"A ready-to-use grant for the read-only user from control 1 above. The MCP server already filters non-SELECT SQL at the application layer; this adds a second, independent layer at the database itself, so even if that filter ever has a bug, writes are still rejected:",[557,558,563],"pre",{"className":559,"code":560,"language":561,"meta":562,"style":562},"language-sql shiki shiki-themes github-light github-dark","-- PostgreSQL example\nCREATE USER ai_readonly WITH PASSWORD 'change-me';\nGRANT CONNECT ON DATABASE mydb TO ai_readonly;\nGRANT USAGE ON SCHEMA public TO ai_readonly;\nGRANT SELECT ON ALL TABLES IN SCHEMA public TO ai_readonly;\nALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO ai_readonly;\n","sql","",[42,564,565,573,579,585,591,597],{"__ignoreMap":562},[566,567,570],"span",{"class":568,"line":569},"line",1,[566,571,572],{},"-- PostgreSQL example\n",[566,574,576],{"class":568,"line":575},2,[566,577,578],{},"CREATE USER ai_readonly WITH PASSWORD 'change-me';\n",[566,580,582],{"class":568,"line":581},3,[566,583,584],{},"GRANT CONNECT ON DATABASE mydb TO ai_readonly;\n",[566,586,588],{"class":568,"line":587},4,[566,589,590],{},"GRANT USAGE ON SCHEMA public TO ai_readonly;\n",[566,592,594],{"class":568,"line":593},5,[566,595,596],{},"GRANT SELECT ON ALL TABLES IN SCHEMA public TO ai_readonly;\n",[566,598,600],{"class":568,"line":599},6,[566,601,602],{},"ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO ai_readonly;\n",[14,604,605,606,609],{},"Then use ",[42,607,608],{},"ai_readonly"," as the connection user in DBConvert Streams.",[27,611,613],{"id":612},"summary","Summary",[35,615,616,623,629,636],{},[38,617,618,619,622],{},"The MCP server ",[18,620,621],{},"cannot modify"," your data, connections, or streams. It can only read and advise.",[38,624,625,626,628],{},"The MCP server runs on ",[18,627,24],{}," (local machine or your Docker host) and never sends data to DBConvert or an AI provider on its own. Your data only leaves your environment if your AI client sends it to its provider.",[38,630,631,632,635],{},"Sensitive values in logs are ",[18,633,634],{},"redacted"," across six categories (secrets plus email\u002FIP addresses) before any data reaches the AI.",[38,637,638,639,642],{},"For data that absolutely cannot leave your environment, keep it behind a ",[18,640,641],{},"read-only database user",", or out of any MCP-connected workspace.",[644,645,646],"style",{},"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);}",{"title":562,"searchDepth":575,"depth":575,"links":648},[649,650,651,652,653,654,655,656,657],{"id":29,"depth":575,"text":30},{"id":109,"depth":575,"text":110},{"id":160,"depth":575,"text":161},{"id":347,"depth":575,"text":348},{"id":370,"depth":575,"text":371},{"id":412,"depth":575,"text":413},{"id":449,"depth":575,"text":450},{"id":552,"depth":575,"text":484},{"id":612,"depth":575,"text":613},"What the AI can and cannot do through the DBConvert Streams MCP server, what it sees, how secrets are redacted, and what reaches your AI provider.","md",{},false,"\u002Fdocs\u002Fmcp\u002Fsafety-and-privacy",null,{"title":5,"description":658},"docs\u002Fmcp\u002Fsafety-and-privacy","V47-Wlgkb1eNAf9LOlqmwE5P28WjhG1g02Ea6m62RuY",1781271516576]