dsh-maxcompute
MaxCompute (ODPS) data analysis plugin for DSH (DeepSeek Harness): metadata browsing, cost-gated SQL execution, background jobs and result export — all backed by the maxc CLI.
Architecture
┌─────────────────────────────────────────────────────┐
│ maxcompute-tools (consumer) │
│ 9 model-facing tools + readonly guard + cost gate │
├─────────────────────────────────────────────────────┤
│ maxcompute-maxc (provider) │
│ Implements MaxComputeService via maxc subprocess │
├─────────────────────────────────────────────────────┤
│ maxcompute-core (contract) │
│ Pure types — zero runtime registration │
└─────────────────────────────────────────────────────┘
↓ execFile
maxc <args> --json
Auth lives in maxc's own config — this plugin never sees credentials.
Prerequisites
# 1. Install maxc (Python CLI for MaxCompute)
pip install aliyun-odps-console
# 2. Authenticate once — OAuth (recommended), AK, or STS
maxc auth login --oauth # browser-based, auto-refresh
maxc auth login --from-env # or from ODPS_ACCESS_ID / ODPS_ACCESS_KEY
Install
npm install dsh-maxcompute
DSH reads the dsh.bundle.patch field in package.json and loads cordis.patch.yml, which wires the three layers. Each row can be replaced by id from a later patch layer (profile / home / --patch overlay).
Configuration
| Layer | Key | Type | Default | Description |
|---|---|---|---|---|
maxcompute-maxc |
maxcBin |
string | maxc |
Path to the maxc binary |
maxcompute-maxc |
project |
string | — | Default project override (--project) |
maxcompute-maxc |
timeoutMs |
number | 600000 |
Kill a foreground maxc process after this many ms |
maxcompute-tools |
readonly |
boolean | true |
Deny DDL/DML/SET/TUNNEL at the guard layer |
maxcompute-tools |
dryRunScanGBThreshold |
number | 10 |
Refuse mc_run_sql when estimated scan exceeds this |
maxcompute-tools |
maxPreviewRows |
number | 50 |
Default row cap for previews returned to the model |
The readonly guard is monotonic: once enabled it cannot be re-allowed by later listeners.
Tools
| Tool | Description |
|---|---|
mc_list_tables |
List tables in a project, optional prefix filter |
mc_describe_table |
Column schema, partition columns, size, comment |
mc_list_partitions |
List partition values for a partitioned table |
mc_sample_table |
Row-limited preview (always safe) |
mc_explain_sql |
Dry-run cost estimate — call before expensive queries |
mc_run_sql |
Execute SQL (readonly guard + cost gate) |
mc_job_status |
Poll an async job's state / progress / logview |
mc_job_result |
Fetch results, optionally export to file |
mc_job_cancel |
Cancel a running job |
Example session
User: 帮我看看 odps_demo 项目里有哪些表
Model: → mc_list_tables(project="odps_demo")
found 42 tables: dwd_trade_detail, dws_user_profile, ...
User: 查一下 dwd_trade_detail 昨天的成交额
Model: → mc_explain_sql(sql="SELECT ... WHERE dt='20260819'")
estimated scan: 2.3 GB — under the 10 GB threshold
→ mc_run_sql(sql="SELECT ...", maxRows=50)
total GMV: ¥1,234,567.89
Development
git clone https://github.com/dingxin-tech/dsh-maxcompute.git
cd dsh-maxcompute
npm install
npm run build # tsc
npm run typecheck # tsc --noEmit
npm test # vitest
Replacing the provider
To swap maxc for an in-house gateway, create a patch layer that re-inserts row id maxcompute-maxc with your own module providing the same maxcompute service. The tools layer depends only on the service contract from maxcompute-core.
No comments yet. Be the first to write one.