Cloudflare D1 数据库工具:d1_list/query/exec/schema/stats/health,通过 D1 HTTP API 访问,默认只读(SQLite 语义的词法级只读保护)、LIMIT 行数上限、CSV/JSON 查询输出与写审批门。
安装
# npm 包(预构建)
dsh plugin --profile web add dsh-d1
# GitHub 源码(首次需按提示配置 allowBuilds 构建授权后重试)
dsh plugin --profile web add github:cndn/dsh-d1
装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络,工具审批管不到它。GitHub 来源的插件还会在安装时执行构建脚本——pnpm 默认拦截,所以安装可能停在 ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED 或 ERR_PNPM_IGNORED_BUILDS;dsh 会打印出需要添加的确切键名,把它加进该 profile 的 pnpm-workspace.yaml 的 allowBuilds 下,重跑一次即可装上。放行构建本身就是一次信任判断:请只安装可信来源,并尽量锁定 commit(github:owner/repo#sha)。
README
该插件的 README 只有英文版本。
Cloudflare D1 (serverless SQLite over HTTP) tools for the DeepSeek Harness — read-only first.
D1 is Cloudflare's serverless SQLite. Unlike a normal database it has no TCP socket — it is reached only over the Cloudflare REST API. So the excellent dsh-sql plugin (which pools TCP connections to SQLite/MySQL/Postgres) can't talk to it. dsh-d1 fills that gap: it speaks the D1 HTTP API directly, giving a dsh agent six tools to introspect and query any D1 database you configure.
It is read-only by default. Writes require flipping readOnly:false and passing an interactive approval gate.
Tools
| Tool | Mode | What it does |
|---|---|---|
d1_list |
read | List configured databases and probe each (SELECT 1). |
d1_query |
read | Run one read-only statement (SELECT / VALUES / WITH … SELECT / introspection PRAGMA / EXPLAIN), with optional bound params. Row-capped. |
d1_exec |
write | Run a write/DDL statement. Denied under readOnly; needs interactive approval otherwise. |
d1_schema |
read | List user tables, or describe one table's columns (via PRAGMA table_info). |
d1_stats |
read | Table count, per-table row counts (batched), database size. |
d1_health |
read | Probe every database and print the safety config (and any config error). |
Every tool forwards the harness's cancellation signal to the D1 request, so a cancelled or timed-out call aborts the HTTP call instead of running to completion in the background. For d1_exec that only abandons the request: a statement D1 has already received may still be applied, so check with d1_query before retrying a cancelled write. The five read tools are marked concurrency-safe, so the harness may run them in parallel.
Install
From npm. The profile directory is a pnpm workspace root, so pnpm needs -w:
dsh plugin --profile web add -w dsh-d1
The npm tarball ships lib/ prebuilt, so there is no build step to approve. The
package is published from CI with provenance;
npm audit signatures verifies the attestation.
During development, from a local checkout:
cd dsh-d1 && npm install && npm run build
dsh plugin --profile web add -w /absolute/path/to/dsh-d1
Installing straight from git (github:cndn/dsh-d1) builds lib/ through the prepare script instead. pnpm 10 blocks that build until you allow it once: copy the onlyBuiltDependencies entry it prints (pinned to the git commit) into the profile's pnpm-workspace.yaml, then re-run the install.
Configure
The package already inserts a d1 row into your profile. Override its config from your profile's cordis.patch.yml with an id-targeted entry (not another insert, which would load the plugin twice). The API token is never part of this config — see below.
- id: d1
name: 'dsh-d1'
config:
accountId: 'your-32-hex-cloudflare-account-id' # or set CLOUDFLARE_ACCOUNT_ID in the env
databases:
- name: prod # the friendly name the agent uses
databaseId: 00000000-0000-0000-0000-000000000000
- name: analytics
databaseId: 11111111-1111-1111-1111-111111111111
accountId: 'another-32-hex-account-id' # optional per-db override
maxRows: 1000 # d1_query row cap (1–10000; larger values are clamped)
readOnly: true # default true — d1_exec denied; set false to allow writes
writeApproval: true # writes must be confirmed interactively (default true)
queryTimeoutMs: 60000 # 5 s – 10 min (clamped)
execTimeoutMs: 120000 # 5 s – 10 min (clamped)
With no databases the plugin still loads (all tools register, d1_health reports "no databases configured") so it is usable for diagnostics. If the config is invalid the plugin falls back to read-only with no databases and d1_health prints the config error.
The API token (env-only)
The Cloudflare API token is read from the environment at call time and is never stored in config, written to the patch, logged, rendered, or included in any error message.
# Global token used for every database:
export CLOUDFLARE_API_TOKEN='...'
# Optional per-database override: DSH_D1_TOKEN_<NAME>, where NAME is the database
# name uppercased with non-alphanumerics replaced by "_" (my-db → DSH_D1_TOKEN_MY_DB):
export DSH_D1_TOKEN_PROD='...'
Create a token in the Cloudflare dashboard with D1 → Read for a read-only agent (or D1 → Edit if you intend to enable writes). The account id (32 hex characters) can come from accountId in config or the CLOUDFLARE_ACCOUNT_ID env var.
Read-only, at two layers
d1_queryis lexically guarded. After stripping comments, string literals and quoted identifiers (with SQLite's own quoting rules — backslash is not an escape), exactly one statement is allowed and it must beSELECT/VALUES/WITH … SELECT/PRAGMA(introspection forms only — noPRAGMA x = y, noPRAGMA x(value)setters, noPRAGMA optimize) /EXPLAINof one of those. In SQLite none of these can modify data, so there is no interior keyword blacklist and column names such asreleaseorsetare fine.SELECTs are wrapped inSELECT * FROM (…) LIMIT maxRows+1so a runaway query never transfers more than the cap.d1_execis denied whilereadOnly:true— the pre-execute gate refuses it before any prompt. WithreadOnly:false,writeApproval:true(the default) routes every write through dsh's approval service: in the web UI you get a confirmation card showing the target database, statement count and the SQL. Where nobody can answer — a headless profile without an interactive answerer, a profile with no approval service at all, orDSH_PERMISSION_MODE=danger-full-access(dsh sets the approval policy tonever) — the ask is auto-rejected and the write is denied, so in those modesd1_execcannot run at all withwriteApproval:true.writeApproval:falseremoves the gate entirely — the plugin logs a warning at boot when both flags are off.
This is deliberately stricter than a general SQL plugin: the safe default is that an agent can read your production data but cannot change it until you opt in.
Security notes
- The token is env-only and must be printable ASCII; the bundled
cordis.patch.ymlcarries no secrets and no real database ids. - Errors are redacted: a failed request surfaces the reason (timeout, cancellation, HTTP status, D1 error message) but never the token or request headers, and request paths echoed by Cloudflare have the account and database ids removed.
- Table names are double-quote-escaped before use in
PRAGMA table_info/COUNT(*)(d1_schema,d1_stats) so a name can't break out into arbitrary SQL. - CSV output neutralises spreadsheet formula prefixes (
=,+,-,@) in string cells.
License
MIT
链接
同类插件
Tencent/WeKnora#dsh-weknora★ 34626
把 WeKnora 知识库接入 dsh 的四个只读工具:列出知识库、混合检索原文片段、按顺序还原单篇文档,以及直接取用 WeKnora 自己带引用的 RAG 或 ReAct agent 回答(含可续聊的 session id)。
superdesigndev/treg★ 5760
给 Agent 的工具目录:按「要做的事」检索约 2,600 个外部接口(SEO 与 SERP、外链、社交、人物与公司信息补全、广告库、抓取),查看参数与单次调用价格后直接调用,凭据由服务端注入。附带技能,MCP 行在未设置 TREG_TOKEN 前保持禁用。
T-Auto/dsh-ops★ 3102
为 Windows 的 DSH 提供 bash、PowerShell 7 及 Rust 高性能工具,减少 token 消耗。
TencentCloudBase/CloudBase-AI-Toolkit#dsh-plugin★ 1139
把腾讯云 CloudBase 后端接入 DeepSeek Harness——在对话里搭好并部署全栈应用,查询结果渲染为表格卡片(分页、排序、导出 CSV),部署后可预览真实域名,并提供 CloudBase MCP 工具集(`mcp__cloudbase__*`),登录走 device-code 流程。
sixtysevenlf/dsh-blender-plugin★ 599
让 DSH agent 通过直连 TCP 通道驱动本地 Blender,提供 16 个工具:视口帧、自定义视角渲染、Python 执行、无头与作业卸载、事务回滚,以及 28 个 family / 186 个 op 的规划层。
anysearch-team/anysearch-dsh★ 537
基于 AnySearch 的实时网页与垂直搜索插件,为 DeepSeek Harness 提供搜索工具。
社区评论
评论公开保存在 GitHub Discussions。加载评论会连接 GitHub 和 Giscus;发表内容需要 GitHub 账号。