Table of contents ›
Documentation
End-user documentation. Each section covers "when to use, how to use, a proper example". For the full parameter list, run mcs <cmd> --help.
[00]Concepts: profile, semantic package, business scenario
Learn these three terms before using mcs — every command revolves around them.
You configure profile → mcs produces semantic package → agent reads it to write SQL
- identity→AK / passwordless
- scenario→description
- tables→sources × N
- contents→tables / columns / JOINs / UDFs
- location→local directory
Business scenario = [A] + [B] + accumulated semantic annotations / memory
"Data warehouse A monthly analysis" = 12 tables from dwd / dws + GMV formula notes
- profile — a configuration that answers two questions: who am I (AK or passwordless, which RAM principal it resolves to) + which tables do I see (one or more sources, each source being a set of
project.schema.tables). A single machine can have any number of profiles. - semantic package —
mcs buildscans all tables covered by the profile, samples a few rows, infers JOIN relationships, discovers UDFs, and writes them to a local directory. The agent reads this package before writing SQL, so it does not need to query MaxCompute metadata every time. - business scenario — not an entity in mcs, but a usage convention: one business domain maps to one profile (one for data warehouse A, one for marketing B, another for cross-domain metrics). The semantic annotations (written via the proposal queue) and memory (verified SQL) accumulated under one profile all belong to that business line.
mcs build only covers the tables you can see; building with a different AK will produce a different package. This is why the wizard's first step asks about auth: it determines the scope of everything that follows.
[01]Quick Start
5 minutes, from zero to your first SQL.
1.Install mcs
Letting the agent install it is the fastest path — it will also set up the skill. Send this message to your agent:
agent> Install mcs for me, read this guide fully then follow step by step: curl -fsSL https://raw.githubusercontent.com/aliyun/maxcompute-semantic/main/scripts/install.md
Or install it yourself:
$ uv tool install maxcompute-semantic
After installation, run mcs --version to verify. If ~/.local/bin is not in your PATH, you need to add it (see README).
2.Create a profile
$ mcs profile create
The wizard will ask: profile name, target MaxCompute project, AK or passwordless auth, endpoint region. All fields can be changed later (mcs profile update).
For AK auth, prefer environment-variable references or ProcessAuth/ncs. For
non-interactive literal-AK setup, pass --ak-literal with
--ak-id and pipe one secret line with
--ak-secret-stdin; avoid --ak-secret unless
shell-history exposure is acceptable.
3.Bind the current directory to a profile
mcs commands in this directory will default to this profile — the agent will too — no need to pass --profile every time.$ cd ~/work/my-data-project $ mcs link bind <profile-name>
Check / unbind: mcs link status, mcs link unlink.
4.Run a build (generate the semantic package)
$ mcs build
After it finishes, run mcs status --tables to see the number of tables / columns / JOINs collected. If table schemas changed, mcs build --refresh only updates modified tables. Not a required step: you can skip it — without a semantic package the agent uses cold-start mode (mcs meta list-tables / describe-table) to query metadata live — it works but is slower each time.
5.Start asking
mcs sql cost for cost estimation and mcs sql execute for execution. mcs build is a one-time onboarding step and does not appear in the query flow.agent> Use mcs to query last month's GMV from the orders table
The agent will automatically call mcs sql cost for cost estimation, mcs sql execute for execution, and summarize the results in plain language. If you want to verify, you can run mcs sql execute "..." directly in the terminal.
[02]Profile: Identity, Organization, and Versioning
A profile is mcs's single abstraction for "who am I, where do I connect". One profile contains: a MaxCompute compute project, an endpoint, an auth method (AK / passwordless), a list of sources to scan (each source is a set of project.schema.tables), and cost thresholds.
profile ──build──▶ semantic package ──reads──▶ agent writes SQL │ └─ scopes a business scenario (a set of sources + an identity + associated annotations/memory)
2.1Resolution chain: which profile is active?
Every mcs command resolves the profile in this order, using the first match:
- Explicit
--profile Xflag - Environment variable
MCS_PROFILE - Current directory's
mcs link bindbinding - Standard ODPS environment variable quartet (
ALIBABA_CLOUD_ACCESS_KEY_ID, etc.) — constructs an in-memory temporary profile
To see which profile is currently active: mcs profile show.
2.2Create: wizard and multi-source DataSource
$ mcs profile create
The interactive wizard walks you through: name, compute project, endpoint, auth, and sources to include in the semantic package. A profile can have multiple sources (e.g., scanning both dwd and ads from the data warehouse, or spanning two projects) — mcs build processes all sources in a single pass. In the agent flow, the wizard first asks what scenario this semantic package should address (business questions, domain, metrics of interest) and stores it as the profile's description; when selecting tables, the agent recommends candidates from mcs meta list-tables results based on this scenario description — you add or remove from those candidates instead of picking blindly from hundreds of tables. mcs build writes this description into the semantic package's _overview.md.
For AK auth, prefer environment-variable references or ProcessAuth/ncs. For
non-interactive literal-AK setup, pass --ak-literal with
--ak-id and pipe one secret line with
--ak-secret-stdin; avoid --ak-secret unless
shell-history exposure is acceptable.
To reuse maxc / odpscmd configuration, run mcs profile import-creds. If the external
configuration uses a non-ncs ProcessAuth helper, the CLI will display the full command
and require explicit trust; after confirming the local command is safe, import with
--trust-process-command.
Already created a profile and want to change fields:
$ mcs profile update <name>
Opens a multi-level picker: compute_project / endpoint / auth / cost_thresholds / tags / sources — select a row to edit it.
2.3cwd binding: mcs link bind
Bind a directory to a profile so that mcs commands in that directory default to that profile:
$ cd ~/work/biz-A $ mcs link bind biz-A-prod # All mcs commands in this directory now default to the biz-A-prod profile
Check / unbind: mcs link status, mcs link unlink. The binding maps the current directory to a profile name, follows the working directory, and persists across shell restarts.
2.4Inspect and switch: show / whoami
| Command | What it shows |
|---|---|
mcs profile list | Names of all profiles on this machine |
mcs profile show [name] | Static config (compute project / sources / thresholds / version) — no network call |
mcs profile whoami [name] | Live ODPS query for "which RAM principal am I right now" — hits the server every time |
Use whoami to debug "which principal does my AK resolve to"; use show to just view the config.
2.5Versioning: log / diff / fork / reset
Each profile's data directory is an independent git repository. Every write from mcs build / package apply/reject / memory / udf / profile import is auto-committed.
$ mcs profile log -n 10 # last 10 writes $ mcs profile diff HEAD~1 HEAD # what changed in the last write $ mcs profile reset --to HEAD~1 # rollback a mistake $ mcs profile fork exp --from HEAD # branch off for A/B testing
To disable auto-versioning (e.g., in CI batch runs), set the environment variable MCS_NO_VERSIONING=1 — writes still happen but are not committed.
2.6Export and share: profile export
Package a profile's semantic package into a single file for sharing with colleagues or migrating machines. The default output is mcs's own tar.gz archive, which can be restored as-is with mcs profile import.
$ mcs profile export <name> # defaults to ./<name>.tar.gz $ mcs profile export <name> --osi # emit OSI YAML instead
With --osi, the same command emits
OSI
(Open Semantic Interchange) YAML instead of a tar.gz archive — useful for
feeding the profile's semantic model into external OSI-aware tooling.
Output conforms to OSI core schema v0.2.0.dev0. The mcs-native tar.gz
export is still the default; --osi opts into the YAML path.
[03]Core Queries: build · package · sql
The main workflow in mcs: first build a semantic package; semantic suggestions generated during build enter the package proposal queue for review then apply; finally use sql to execute, estimate costs, and view execution plans.
3.1mcs build: when to run, --refresh / --fresh / --parallel
Scans all tables covered by the profile's sources list, samples a few rows, infers JOIN relationships, discovers UDFs, and writes them to the local semantic package. The agent reads this package before writing SQL to avoid unnecessary detours.
$ mcs build # full build on first run; resumes from where it left off if interrupted $ mcs build --fresh # force a full rebuild from scratch, ignoring resume state $ mcs build --refresh # incremental: rebuild tables whose schema or data changed (also catches up interrupted tables) $ mcs build --refresh --refresh-min-age-hours 6 # throttle data-change resampling: only resample if last sample is older than N hours (default 24, 0 = no throttle) $ mcs build --parallel 8 # sample 8 tables concurrently (default auto = min(table_count, 32))
mcs build again to resume; run --refresh after upstream table schemas or data change (resamples tables with modified data; --refresh-min-age-hours controls resampling frequency); use --fresh to start a full rebuild from scratch ignoring resume state. mcs status --tables shows data_modified_at / last_sampled_at to see which tables lag behind their source. Day-to-day queries do not require repeated builds.
mcs build generates explainable semantic suggestions but does not directly modify the semantic layer by default. When the agent runs post-build enrichment, it first converts these suggestions into mcs package proposals for you to review the evidence before applying or rejecting.
3.2mcs package: review semantic suggestions from build
After build / refresh, the agent can place high-confidence suggestions derived from samples, historical SQL, and column distributions into the proposal queue. It can also submit reviewed ai_context, column descriptions, and column role corrections as YAML proposals. A proposal is a "pending patch": you can see the target columns, suggested content, evidence, and confidence; only after apply does it write to the semantic package, and reject records the decision too.
$ mcs package propose --from-suggestions $ mcs package propose --from-stdin # create ai_context / column_description / column_semantics proposals from YAML $ mcs package list-proposals $ mcs package show-proposal <id> $ mcs package apply <id> $ mcs package reject <id> --reason "not correct for this domain"
This is the default path for generative semantic suggestions: first propose --from-suggestions, then use propose --from-stdin to add agent-reviewed table semantics, column descriptions, or role corrections; if a previously rejected agent YAML proposal needs correcting in the same enrichment round, --from-stdin puts it back into the suggested queue. Then review each one with show-proposal to see the evidence, apply the correct ones, and reject those that do not match business definitions with a reason. The agent's enrich runtime skill also follows this path.
3.3Semantic annotations: all via the proposal queue
All semantic annotation writes go through mcs package propose → review → mcs package apply; there is no direct-write entry point. The business semantics you can annotate include:
ai_context— what this table is for (a natural language description)dimensions/measures/identifiers— role classification for columns- Per-column
semantic_description— what this column means (a semantic explanation, not a restatement of the column name)
$ mcs package propose --from-stdin # submit a semantic annotation proposal for review $ mcs package list-proposals # view the review queue $ mcs package apply <id> # write after approval
See which tables are annotated: mcs status --tables — the last column shows Annotated: yes/no/partial.
3.4mcs metric: top-down named business metrics
Explicitly register algorithms like "total paid order amount per user per month"
that have a business name and are used repeatedly,
so they can be reused directly next time without re-composing the SQL.
A metric is profile-global with UNIQUE(name) — even across sources
there can be only one total_revenue.
$ mcs metric add total_revenue --expression "SUM(orders.amount)" $ mcs metric list $ mcs metric show total_revenue $ mcs metric edit total_revenue --description "..." $ mcs metric remove total_revenue
--role measure is a column-level attribute ("this column can be SUMmed");
mcs metric add is a top-level entity ("this number has a business name").
The two do not conflict: measures are tagged on columns, metrics are registered at the profile level.
Bulk import is also supported: mcs package propose --from-stdin accepts a top-level metrics: list (alongside tables:) and writes them via the proposal queue after review.
OSI export (mcs profile export --osi) writes these metrics to semantic_model.metrics[], so downstream OSI tools can read them directly.
3.5mcs sql: review / execute / async / cost / explain
These verbs cover every "run SQL" scenario:
| Command | Purpose | When to use |
|---|---|---|
sql review | Local static SQL review (no MaxCompute round-trip) | Scan before execute to avoid wasting a round-trip on basic errors |
sql execute | Synchronous execution with results | Probes, small result sets, queries with clearly low cost |
sql submit/status/wait/result/cancel | Async submit and poll MaxCompute instances | Production analysis, large table JOINs/aggregations, queries that need cost confirmation or may time out |
sql cost | Cost estimate + pass/fail verdict | Check before running large-table queries |
sql explain | Execution plan | When optimizing SQL |
$ mcs sql review "SELECT IIF(x > 0, 1, 0) FROM orders" # → issues[0].rule = dialect.sqlite-iif · suggests rewriting to CASE WHEN $ mcs sql execute "SELECT COUNT(*) FROM orders WHERE ds = '20260520'" $ mcs sql submit -y "SELECT * FROM big_a JOIN big_b ON big_a.id = big_b.id" $ mcs sql wait <instance_id> # check lifecycle_state / successful $ mcs sql result <instance_id> # fetch rows after lifecycle_state == "success" $ mcs sql result --offset 10000 <instance_id> # fetch next page when has_more=true $ mcs sql cost "SELECT * FROM orders" # → verdict: confirm · cost 12.4 CNY · full scan on large table, consider adding partition filter $ mcs sql explain "SELECT ds, SUM(amount) FROM orders GROUP BY ds"
issues (error / warning — dialect incompatibilities, missing tables/columns, and other hard errors) and hints (info — undeclared JOINs, dimensions used in aggregations, and other "possible misuse" notes). The agent workflow is: first review and fix all issues, check hints to decide whether to proceed, then run execute; this step does not consume MaxCompute quota.
review_mode: syntax_only and semantic_checks_skipped: true, still checking SQLite dialect issues, unsupported functions, bare table names in 3-level projects, and other checks that do not depend on the semantic package; table/column existence, JOIN/aggregation, and other semantic checks are skipped. Do not run mcs build mid-query just to complete the review.
ok (below confirm_cny threshold, safe) / confirm (between confirm and blocked — the agent will ask the user to confirm) / blocked (above blocked_cny — the agent will not execute by default). Defaults: confirm=10 CNY, blocked=100 CNY; change thresholds via mcs profile update under cost_thresholds.
mcs sql execute and mcs sql submit reject DML/DDL, SET session mutations, and statements that cannot be identified as read queries by default; pass --allow-write only when the user explicitly requests a write, and the cost gate still applies.
blocked is not executed; for confirm, ask the user first, then prefer submit / wait / result after confirmation; for ok, also check the SQL shape — only use execute for probes, small results, explicit small LIMIT, or tight partition lookup/aggregation. Production analysis, large table scans/JOINs/aggregations, SQL without tight partitions or LIMIT, and previously timed-out SQL should use async even with ok. For async results, check lifecycle_state, successful, and task_statuses; confirm lifecycle_state == "success" before fetching rows.
sql execute and sql result do not rewrite the submitted SQL or automatically add LIMIT; they only paginate on the reader output side. JSON responses include result_max_rows, result_offset, has_more, truncated, and next_offset. Pass --offset <next_offset> for the next page, --max-rows N to adjust page size, or --max-rows 0 to disable the limit.
Note: mcs sql cost returns exit code 0 even when blocked — the verdict is in the verdict field of the JSON output. Scripts should read the field, not the exit code.
3.6--project / --schema / --profile usage
These three flags have completely different meanings and are easy to confuse:
| Flag | Meaning | When to pass |
|---|---|---|
--profile X | Which local profile config to use | When cwd is not bound / when you want to temporarily switch profiles |
--project P | Target MaxCompute project | When the profile spans multiple projects and you want to specify one |
--schema S | Schema name for 3-level projects | Almost never — mcs auto-detects and caches; only as a fallback when detection is wrong |
The difference between 2-level projects (no schema) and 3-level projects is handled automatically by mcs — you write orders and it becomes my_proj.orders or my_proj.default.orders as appropriate.
[04]Advanced: memory · udf · meta
This section is for users who have completed the main workflow and want mcs to get more accurate over time.
4.1memory: verify / fail / note / recall
Memory is the query experience store. Every question asked and every mistake made can be recorded, providing reference for similar questions next time. Three write verbs + one read verb:
| Verb | Purpose |
|---|---|
memory verify --question Q --sql S --tables T1,T2 | Record a "question → correct SQL" entry |
memory fail --question Q --sql S --error-msg M | Record a "this SQL failed + error message" entry — the agent will avoid similar patterns next time |
memory note '<TEXT>' | Record free-form domain knowledge (not necessarily SQL) |
memory recall '<keyword>' | BM25 + vector hybrid search across all three entry types |
$ mcs memory verify \ --question "last month's GMV" \ --sql "SELECT SUM(amount) FROM orders WHERE ds BETWEEN '20260401' AND '20260430'" \ --tables orders $ mcs memory recall "GMV"
Management: memory list to view all, memory show <id> to view one, memory remove <id> to delete one, memory clear to clear all (by default only clears user-written entries, not auto-generated ones).
MCS_NO_HISTORY=1 to prevent historical experience from leaking answers — mcs build's history miner phase will be skipped.
4.2udf: list / show / search / create / test / remove
Read side (anyone can run):
$ mcs udf list $ mcs udf show parse_user_agent $ mcs udf search "json"
Write side (requires confirmation / write permissions):
$ mcs udf create my_fn --inline-python my_fn.py --description "parse order number prefix" $ mcs udf test my_fn --args '1, "abc"' $ mcs udf remove my_fn --delete-resources
udf test --args only accepts literals: numbers, NULL, TRUE/FALSE, and quoted strings; it will not splice bare identifiers, expressions, or semicolon fragments into SQL. Currently create only supports inline Python; for jar / resource-based UDFs, use mcs sql execute --allow-write 'CREATE FUNCTION ...', which still requires user confirmation and goes through the cost gate.
4.3meta: list-tables / describe-table
A "raw" interface that queries MaxCompute metadata directly without depending on the semantic package. Use during cold start (no build yet) or to inspect tables not in the sources list:
$ mcs meta list-tables --project my_proj $ mcs meta describe-table --project my_proj orders
For tables that have already been built, mcs show --table orders is better — it includes sample SQL, JOIN relationships, and annotations, representing the "crystallized" version from the semantic package.
[05]Operations and Troubleshooting
Refer to this section when something goes wrong, when setting up on a new machine, or when you need to check the environment state.
5.1mcs doctor: one-command diagnostics + JSON output
A single command that checks everything — profile / auth / network / semantic package / skill installation:
$ mcs doctor # full check, including network $ mcs doctor --offline # skip ODPS probe, check local config / package / skill only $ mcs -f json doctor # JSON output for agent parsing, includes per-check remediation
Typical usage: run mcs doctor after installation to see all green; when something breaks, run mcs -f json doctor first to see which check is red. The agent will use the remediation field in the JSON to guide you through the fix step by step.
5.2skill install: 55 platforms, --all / --detect
Symlinks SKILL.md into your agent tool's skills directory. A symlink rather than a copy, so when mcs is upgraded the skill auto-syncs with no version drift.
$ mcs skill install # default: project-level .agents/skills/ $ mcs skill install -g # global (~/.agents/skills/) $ mcs skill install -p claude-code -g # Claude Code global $ mcs skill install --all # install to all 55+ platforms $ mcs skill install --detect # install only to detected agents on this machine
Common platform mappings:
| Agent | -p name |
|---|---|
| Universal | agents (default) |
| Claude Code | claude-code |
| Cursor | cursor |
| OpenAI Codex | codex |
| Gemini CLI | gemini-cli |
| Qwen Code | qwen-code |
| OpenCode | opencode |
| Windsurf | windsurf |
| Trae | trae |
Full 55+ platform list: mcs skill list. Other operations: mcs skill update / uninstall / path / diff.
SKILL.md installed to the agent is now a thin discovery stub; the actual workflow is output by mcs skill get query / build / enrich commands matching the current mcs version. When answering data questions, only the query skill is loaded; the build skill is only loaded when explicitly building or refreshing the semantic package, to prevent the query flow from mistakenly running mcs build.
$ mcs skill catalog $ mcs skill get query $ mcs skill get query --full $ mcs skill get build
5.32-level vs 3-level tier auto-detection
MaxCompute projects have two addressing modes: 2-level (project.table) and 3-level (project.schema.table). The first time mcs accesses a project, it auto-detects the tier and caches the result in tier_cache/<project> — no need for SET odps.namespace.schema or --schema afterwards.
If detection was wrong and you want to force re-detection: delete the one-byte file at ~/.local/share/maxcompute-semantic/data/<profile>/tier_cache/<project>. As an extreme fallback: all mcs commands accept --schema S for explicit override.
5.4Common environment variables
| Variable | Purpose |
|---|---|
MCS_PROFILE | Resolution chain tier 2: specifies a profile when cwd is not bound and --profile is not passed |
MCS_NO_HISTORY=1 | Skip mcs build's history mining — required when running benchmarks |
MCS_NO_VERSIONING=1 | Disable profile auto git commit — useful for CI batch runs |
MCS_DATA_DIR | Override the local data directory (default ~/.local/share/maxcompute-semantic/) |
ALIBABA_CLOUD_ACCESS_KEY_ID and the other three | Resolution chain tier 4: fallback when not using profiles at all |
Truthy values are case-insensitive: 1 / true / yes / on.
[06]Agent Conversation Scripts
Once mcs has the skill installed, talking to your agent is all you need — the agent will automatically invoke mcs commands. This section provides templates for "what to say".
6.1Triggering the skill
Most agents auto-load the maxcompute-semantic skill when they see keywords like these:
- Mention the brand name: "use mcs", "use maxcompute", "use ODPS"
- Explicitly invoke the skill: "/maxcompute-semantic ..." (agents that support slash commands like Claude Code / Codex)
- Verb triggers: "query", "create table", "calculate", "get stats on" + one of your MaxCompute table names
If the agent does not load the skill (and generates non-runnable SQL instead), the most reliable fallback is to say explicitly: "Please load the maxcompute-semantic skill and then answer."
6.2Common task examples
agent> Use mcs to query last month's GMV from the orders table agent> What is the products table on ODPS for? What do the fields mean? agent> Do you remember the DAU formula I asked about last time? Re-run that SQL agent> Estimate how much this SQL will cost: <paste SQL> agent> Save the SQL that just worked to mcs memory, with the question "monthly active users"
The agent will call sql cost for cost estimation, use sql execute for probes and small-result queries, or use sql submit / sql wait / sql result for production analysis, cost confirmation, and queries that may time out; it will also use show --table to inspect structure, memory recall to find history, and memory verify to save new experience.
6.3Have the agent report bugs / run diagnostics
agent> Report an mcs bug for me: <describe the symptom> agent> Run an mcs environment check
When reporting a bug, the skill follows the Aone work-item convention — it auto-adds the [maxcompute-semantic] prefix, sets the related project to 2155299, and attaches the version number and doctor output. An environment check runs mcs -f json doctor and explains any red items in plain language.