Metadata-Version: 2.4
Name: mcp-alicloud
Version: 0.1.5
Summary: MCP server for high-fidelity, read-only Alibaba Cloud DMS web workflows
Keywords: alibaba-cloud,alicloud,dms,mcp,model-context-protocol
Author: yangqy01
Author-email: yangqy01 <yangqy01@rabyte.cn>
License-Expression: MIT
License-File: LICENSE
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.13
Requires-Dist: anyio>=4.5
Requires-Dist: cryptography>=50.0.0
Requires-Dist: httpx>=0.28.1
Requires-Dist: mcp[cli]>=1.28.1,<2
Requires-Dist: websockets>=16.0
Requires-Python: >=3.13
Project-URL: Homepage, https://pypi.org/project/mcp-alicloud/
Project-URL: Repository, https://github.com/ArtiPyHeart/mcp-alicloud
Project-URL: Issues, https://github.com/ArtiPyHeart/mcp-alicloud/issues
Description-Content-Type: text/markdown

# mcp-alicloud

[![Python 3.13](https://img.shields.io/badge/Python-3.13-3776AB?logo=python&logoColor=white)](https://www.python.org/)
[![PyPI](https://img.shields.io/pypi/v/mcp-alicloud.svg)](https://pypi.org/project/mcp-alicloud/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/license/mit)

`mcp-alicloud` is a Model Context Protocol server for high-fidelity, read-only
Alibaba Cloud Data Management Service (DMS) workflows. It gives MCP clients a
structured way to discover passwordless DMS instances and databases, inspect
table metadata, run bounded read-only SQL, and handle CSV results.

The implementation follows observed DMS web-console request flows while keeping
credentials local and redacting sensitive transport details from tool output.

> **Important:** Version 0.1.5 is an alpha release. It supports a deliberately
> narrow, read-only subset of DMS. Review the [security model](#security-model)
> before using it with a real cloud account.

This is an independent project and is not an Alibaba Cloud product.

## Features

- Lists DMS instances and databases that are already eligible for passwordless
  access.
- Selects a database for subsequent metadata and SQL operations.
- Searches tables and returns redacted column and index metadata.
- Executes `SELECT`, `SHOW`, `DESCRIBE`, `DESC`, and `EXPLAIN` through
  the DMS precheck, credential, paging, and WebSocket flow.
- Limits interactive result retrieval to 101 rows, including one overflow row
  used to report truncation.
- Replays the observed DMS front-end CSV conversion locally and can archive a
  completed CSV downloaded by Chrome.
- Opens the AliCloud login in normal Chrome, then attaches Chrome DevTools MCP
  only after the user confirms that DMS has loaded.
- Keeps manual private-file and standard-input auth imports as a recovery path.
- Never reads Chrome profiles, cookie stores, local storage, or browser history.
- Keeps MCP responses structured and removes cookies, tokens, CSRF values,
  request IDs, raw SQL transport data, and other sensitive fields.

## Supported scope

The current release supports:

- Passwordless DMS instances.
- Passwordless databases with the observed `COMMON` control mode and trusted
  access flag.
- Read-only table discovery and schema inspection.
- Bounded read-only SQL.
- Local CSV reconstruction that matches the observed DMS front-end conversion.
- Finalization of a CSV file already downloaded through the DMS page in Chrome.

The current release does not support:

- Instance login or database login.
- Permission applications.
- Logged-in or login-required instances and databases.
- DDL, DML, transactions, stored procedure calls, or administrative SQL.
- Direct password submission, SMS-code submission, or private sign-in API replay.
- The “remember this machine for seven days” login option.
- Forged or bulk-replayed telemetry and risk-control requests.

## Requirements

- Python 3.13 or newer.
- [uv](https://docs.astral.sh/uv/getting-started/installation/) with `uvx`.
- Node.js 20.19 or newer with `npx`. The login command runs the pinned
  `chrome-devtools-mcp@1.8.0` package.
- Google Chrome 144 or newer for the AliCloud login, post-login DevTools
  attachment, and DMS console session.
- An Alibaba Cloud RAM account that can access DMS.
- An MCP client with STDIO server support.

The shell examples below use POSIX syntax. Use absolute paths in persistent MCP
configuration.

## Quick start

### 1. Create private local directories

Use one session directory for the login CLI, the DMS auth CLI, and the MCP
server:

```bash
export MCP_ALICLOUD_SESSION_DIR="$HOME/.local/share/mcp-alicloud/session"
export MCP_ALICLOUD_EXPORT_DIR="$HOME/.local/share/mcp-alicloud/exports"

mkdir -p "$MCP_ALICLOUD_SESSION_DIR" "$MCP_ALICLOUD_EXPORT_DIR"
chmod 700 "$MCP_ALICLOUD_SESSION_DIR" "$MCP_ALICLOUD_EXPORT_DIR"
```

### 2. Sign in and capture DMS authentication

```bash
export MCP_ALICLOUD_RAM_DOMAIN="your-account.onaliyun.com"
uvx --from mcp-alicloud@0.1.5 mcp-alicloud-login start --ram-domain "$MCP_ALICLOUD_RAM_DOMAIN" --capture-dms-auth
```

The command first opens the AliCloud login in normal Chrome, with Chrome
DevTools inactive. Complete the password and MFA steps only in the AliCloud
page, leave the seven-day trusted-device option unchecked, and wait for DMS to
load. Return to the terminal and type `yes` only after DMS is open.
The CLI explicitly targets Google Chrome, so an Arc, Safari, or Firefox default
browser does not change this step.

The command then starts the pinned Chrome DevTools MCP provider with
`--auto-connect`. Approve Chrome's debugging request for the existing browser.
The provider must complete a real browser readiness probe within 30 seconds
before the CLI reports `chrome_devtools_attached`. This attachment limit is
separate from the overall capture timeout. Only the post-login DMS capture runs
under DevTools control. It automatically:

- Captures and validates the main DMS passwordless-instance request.
- Opens one eligible passwordless database in the DMS SQL Console.
- Captures and validates the DMSNext request context.
- Writes `dms-auth-context.json` with mode `0600`.
- Marks the local login state ready only after the complete auth context passes
  validation.

The capture process attaches to the normal Chrome profile that the user just
authenticated and detaches when the command finishes. The Python process never
opens the Chrome profile database, decrypts its cookie store, or controls the
password and MFA phase.

The default capture timeout is ten minutes and the generated DMS auth context
expires after eight hours. Override them only when needed:

```bash
uvx --from mcp-alicloud@0.1.5 mcp-alicloud-login start --ram-domain "$MCP_ALICLOUD_RAM_DOMAIN" --capture-dms-auth --capture-timeout-seconds 900 --auth-ttl-hours 12
```

### 3. Verify local readiness

```bash
uvx --from mcp-alicloud@0.1.5 mcp-alicloud-login doctor

uvx --from mcp-alicloud@0.1.5 mcp-alicloud-dms-auth status --require-dms-web
```

Both commands return redacted JSON. They report field presence, expiry, file
permissions, and readiness without printing secret values.

### 4. Configure an MCP client

Use one of the configurations below, then restart or reload the MCP client.

## Manual auth import fallback

The post-login capture path is the default. Manual import remains available
when Chrome DevTools MCP cannot capture a request after an upstream DMS page
change.

The DMS APIs use two related browser contexts:

- `dms_web` for the main DMS site and passwordless instance listing.
- `dmsnext` for database metadata, SQL precheck, paging, and execution.

Collect both requests in Chrome DevTools:

1. Open DevTools in the authenticated DMS tab and select the **Network** panel.
2. Find a successful request to
   `https://dms.aliyun.com/dms/metastore/instances/list`.
3. Use **Copy as cURL** and save the command to a private local file.
4. Open the DMS SQL Console.
5. Find a successful request to
   `https://dmsnext.console.aliyun.com/data/api.json`.
6. Use **Copy as cURL** and save that command to a second private local file.

Treat both cURL files as credentials. Keep them outside the repository, do not
paste them into chat, and do not pass their contents as command-line arguments.

Import the files:

```bash
umask 077

uvx --from mcp-alicloud@0.1.5 mcp-alicloud-dms-auth import-dms-web-curl --input "$HOME/.local/share/mcp-alicloud/dms-web.curl" --delete-source

uvx --from mcp-alicloud@0.1.5 mcp-alicloud-dms-auth import-dmsnext-curl --input "$HOME/.local/share/mcp-alicloud/dmsnext.curl" --merge-existing --delete-source
```

The generated auth-context file is written with mode `0600`. Import from
standard input by passing `--input -` when a private file is inconvenient.

## Codex setup

Codex CLI and the Codex IDE extension share the MCP configuration managed by
Codex.

### Add the server with Codex CLI

```bash
codex mcp add alicloud --env MCP_ALICLOUD_SESSION_DIR="$HOME/.local/share/mcp-alicloud/session" --env MCP_ALICLOUD_EXPORT_DIR="$HOME/.local/share/mcp-alicloud/exports" -- uvx --from mcp-alicloud@0.1.5 mcp-alicloud

codex mcp list
```

Remove the registration with:

```bash
codex mcp remove alicloud
```

### Configure Codex with TOML

Add the following entry to `~/.codex/config.toml`. TOML does not expand
`$HOME`, so use absolute paths:

```toml
[mcp_servers.alicloud]
command = "uvx"
args = ["--from", "mcp-alicloud@0.1.5", "mcp-alicloud"]
env = { MCP_ALICLOUD_SESSION_DIR = "/Users/you/.local/share/mcp-alicloud/session", MCP_ALICLOUD_EXPORT_DIR = "/Users/you/.local/share/mcp-alicloud/exports" }
startup_timeout_sec = 30
tool_timeout_sec = 120
```

See the official [Codex MCP documentation](https://developers.openai.com/codex/mcp/)
for current client configuration details.

## Generic MCP client setup

Clients that use JSON-based MCP configuration can start the published package
with `uvx`:

```json
{
  "mcpServers": {
    "alicloud": {
      "command": "uvx",
      "args": [
        "--from",
        "mcp-alicloud@0.1.5",
        "mcp-alicloud"
      ],
      "env": {
        "MCP_ALICLOUD_SESSION_DIR": "/Users/you/.local/share/mcp-alicloud/session",
        "MCP_ALICLOUD_EXPORT_DIR": "/Users/you/.local/share/mcp-alicloud/exports"
      }
    }
  }
}
```

The exact configuration file location depends on the client. Keep the package
version pinned for reproducible startup.

## Run from source

Use the repository environment for local development:

```bash
git clone git@github.com:ArtiPyHeart/mcp-alicloud.git
cd mcp-alicloud
uv sync --locked
uv run mcp-alicloud --self-test
```

Point an MCP client at the checkout:

```json
{
  "mcpServers": {
    "alicloud-dev": {
      "command": "uv",
      "args": [
        "--directory",
        "/absolute/path/to/mcp-alicloud",
        "run",
        "mcp-alicloud"
      ],
      "env": {
        "MCP_ALICLOUD_SESSION_DIR": "/Users/you/.local/share/mcp-alicloud/session",
        "MCP_ALICLOUD_EXPORT_DIR": "/Users/you/.local/share/mcp-alicloud/exports"
      }
    }
  }
}
```

`--self-test` is only a local smoke test. Do not include it in a real MCP
server configuration.

## Recommended tool workflow

An MCP client should use the operational tools in this order:

1. `get_alicloud_login_status`
2. `get_dms_auth_context_status`
3. `list_dms_passwordless_instances`
4. `list_dms_passwordless_databases`
5. `select_dms_passwordless_database`
6. `search_dms_passwordless_tables`
7. `describe_dms_passwordless_table`
8. `validate_dms_readonly_sql`
9. `query_dms_passwordless_sql`
10. `export_dms_passwordless_sql_csv` when a local export is explicitly needed

The selection tool updates the private auth context with the selected database
and the matching SQL Console referer. Database-dependent tools validate that
selection before making requests.

## SQL safety policy

The SQL tools use a conservative read-only policy:

- Allowed first commands: `SELECT`, `SHOW`, `DESCRIBE`, `DESC`, and
  `EXPLAIN`.
- Exactly one statement is accepted.
- SQL comments are rejected.
- DDL, DML, transaction control, permission changes, stored procedure calls,
  and administrative commands are rejected.
- Side-effecting or high-risk constructs such as delays, file access, advisory
  locks, sequence mutation, cross-database links, and session-variable
  assignment are rejected.
- A terminal numeric `LIMIT` on `SELECT` must not exceed 101.
- A `SELECT` without a supported terminal `LIMIT` is sent through the
  observed DMS paging endpoint to produce a bounded first-page statement.
- The SQL returned by DMS precheck and paging is validated again before the
  WebSocket query is sent.
- The WebSocket client stops if more than 101 result rows arrive.
- Tool output defaults to 20 preview rows and allows at most 100 preview rows.

The validator is intentionally strict. It is an application safety layer, not
a replacement for least-privilege database credentials or DMS authorization.

## CSV handling

There are two distinct CSV paths.

### Local DMS-compatible export

`export_dms_passwordless_sql_csv` executes a bounded read-only query and
replays the observed DMS front-end CSV conversion into a local file. When the
required DMS web context is available, it also attempts the observed export
history request and reports its result separately.

This path is a local reconstruction. It is never reported as a Chrome download.
The tool requires an explicitly bounded `SELECT` with a terminal numeric
`LIMIT` of 101 or less.

### Completed Chrome download finalization

`finalize_dms_official_csv_download` handles a CSV that the DMS page has
already downloaded through Chrome into the current user's default Downloads
directory. It waits for the file to finish, reads only file metadata, moves it
into the configured export directory, and assigns a safe tracking name that
contains no SQL, table name, token, account identifier, or result value.

CSV files contain query results and must be protected as sensitive data.

## Tool reference

### Operational tools

| Tool | Purpose |
| --- | --- |
| `get_alicloud_login_status` | Returns the redacted local login-state summary. |
| `get_dms_auth_context_status` | Checks the explicit DMS auth context without exposing secrets. |
| `list_dms_passwordless_instances` | Lists currently eligible passwordless DMS instances. |
| `list_dms_passwordless_databases` | Lists eligible databases for one passwordless instance. |
| `select_dms_passwordless_database` | Validates and stores the current database selection. |
| `search_dms_passwordless_tables` | Searches table metadata in the selected database. |
| `describe_dms_passwordless_table` | Returns redacted column and index metadata. |
| `validate_dms_readonly_sql` | Validates SQL against the local read-only policy. |
| `query_dms_passwordless_sql` | Runs one bounded read-only query through DMS. |
| `export_dms_passwordless_sql_csv` | Creates a local DMS-compatible CSV export. |
| `finalize_dms_official_csv_download` | Archives a completed DMS CSV downloaded by Chrome. |
| `get_dms_ram_domain_realm` | Probes the public RAM-domain realm endpoint. |
| `summarize_dms_sql_websocket_frames` | Produces a bounded summary from explicitly supplied DMS result frames. |
| `export_dms_sql_websocket_frames_csv` | Returns the policy rejection for generic CSV synthesis from frames. |
| `explain_alicloud_login_required` | Returns the standard login-required error contract. |

### Contract and observation tools

| Tool | Purpose |
| --- | --- |
| `describe_dms_signin_observation` | Describes the observed DMS RAM sign-in bootstrap flow. |
| `describe_dms_passwordless_instances_contract` | Describes the passwordless instance request and redaction contract. |
| `describe_dms_passwordless_databases_contract` | Describes database discovery and selection. |
| `describe_dms_passwordless_table_search_contract` | Describes table search behavior and boundaries. |
| `describe_dms_passwordless_table_structure_contract` | Describes column and index inspection. |
| `describe_dms_passwordless_sql_query_contract` | Describes SQL validation, paging, precheck, and execution. |
| `describe_dms_passwordless_sql_export_contract` | Describes local conversion, browser download, and history handling. |

## Command-line reference

### Login CLI

```bash
uvx --from mcp-alicloud@0.1.5 mcp-alicloud-login start --ram-domain "$MCP_ALICLOUD_RAM_DOMAIN" --capture-dms-auth
uvx --from mcp-alicloud@0.1.5 mcp-alicloud-login complete
uvx --from mcp-alicloud@0.1.5 mcp-alicloud-login status
uvx --from mcp-alicloud@0.1.5 mcp-alicloud-login doctor
uvx --from mcp-alicloud@0.1.5 mcp-alicloud-login check
uvx --from mcp-alicloud@0.1.5 mcp-alicloud-login clear
```

Append `--help` to any listed command for command-specific options.

### DMS auth CLI

```bash
uvx --from mcp-alicloud@0.1.5 mcp-alicloud-dms-auth template
uvx --from mcp-alicloud@0.1.5 mcp-alicloud-dms-auth import --input "$HOME/.local/share/mcp-alicloud/dms-auth-context.json"
uvx --from mcp-alicloud@0.1.5 mcp-alicloud-dms-auth import-dms-web-curl --input "$HOME/.local/share/mcp-alicloud/dms-web.curl" --delete-source
uvx --from mcp-alicloud@0.1.5 mcp-alicloud-dms-auth import-dmsnext-curl --input "$HOME/.local/share/mcp-alicloud/dmsnext.curl" --merge-existing --delete-source
uvx --from mcp-alicloud@0.1.5 mcp-alicloud-dms-auth status --require-dms-web
uvx --from mcp-alicloud@0.1.5 mcp-alicloud-dms-auth doctor --require-dms-web
uvx --from mcp-alicloud@0.1.5 mcp-alicloud-dms-auth check --require-dms-web
uvx --from mcp-alicloud@0.1.5 mcp-alicloud-dms-auth clear
```

Append `--help` to any listed command for command-specific options.

## Environment variables

| Variable | Purpose |
| --- | --- |
| `MCP_ALICLOUD_SESSION_DIR` | Shared directory for the local login assertion and default DMS auth-context file. Set an absolute path for MCP clients. |
| `MCP_ALICLOUD_DMS_AUTH_CONTEXT_FILE` | Optional absolute override for the DMS auth-context file. |
| `MCP_ALICLOUD_EXPORT_DIR` | Destination for local and finalized CSV artifacts. The system temporary directory is used when unset. |
| `MCP_ALICLOUD_RAM_DOMAIN` | Default RAM account domain for the login CLI. |
| `MCP_ALICLOUD_EXPECTED_RAIDHO_CONFIG_VERSION` | Optional expected public login configuration version for drift warnings. |
| `MCP_ALICLOUD_EXPECTED_RAM_SIGNIN_VERSION` | Optional expected public sign-in asset version for drift warnings. |

## Troubleshooting

### The MCP client cannot find the login state

The login command and MCP server are using different working directories or
session paths. Set the same absolute `MCP_ALICLOUD_SESSION_DIR` for every
command and in the MCP client configuration.

### The auth context is expired

Run the login command again. Normal Chrome can reuse its existing AliCloud
session when that session remains valid. The command replaces the expired auth
context only after both DMS capabilities pass validation:

```bash
uvx --from mcp-alicloud@0.1.5 mcp-alicloud-login start --ram-domain "$MCP_ALICLOUD_RAM_DOMAIN" --capture-dms-auth
```

The CLI fails closed when required fields are missing, expired, malformed, or
stored with unsafe file permissions.

### Chrome DevTools cannot attach after login

Confirm that Chrome 144 or newer, Node.js, and `npx` are available. Keep the
authenticated DMS tab open and approve Chrome's remote-debugging request after
typing `yes` in the terminal. If Chrome does not offer the approval, open
`chrome://inspect/#remote-debugging`, enable remote debugging for the current
browser, fully quit and reopen Chrome, and retry once. An attachment that does
not complete within 30 seconds returns `CHROME_DEVTOOLS_ATTACH_TIMEOUT` instead
of consuming the full DMS capture timeout.

The first run may need network access so `npx` can install the pinned
`chrome-devtools-mcp@1.8.0` package into its local cache.

### Login reports public asset drift

The login CLI compares public AliCloud page assets with the observed baseline.
A drift warning is non-blocking, but it indicates that the browser flow should
be reviewed before changing login automation.

### A safe query is rejected

Run `validate_dms_readonly_sql` first and inspect its structured reason. Add a
terminal numeric `LIMIT` when exporting. Interactive queries may omit it
because the query tool uses the bounded DMS paging flow.

### The MCP server exits or emits protocol errors

Run the local smoke test:

```bash
uvx --refresh --from mcp-alicloud@0.1.5 mcp-alicloud --self-test
```

The normal MCP server uses STDIO. Its standard output is reserved for JSON-RPC;
diagnostics are written to standard error.

## Upgrading

Update the pinned version in the MCP client configuration, then force an
isolated refresh:

```bash
uvx --refresh --from mcp-alicloud@0.1.5 mcp-alicloud --self-test
```

Patch releases use the next `0.1.x` version. Keep the server and companion
CLI commands on the same package version.

## Development

```bash
uv sync
uv run python --version
uv run python -m unittest discover -s tests
uv run mcp-alicloud --self-test
uv run pip-audit --local --skip-editable
uv build
uv run twine check dist/*
```

Runtime code lives in `src/mcp_alicloud/`; tests use the standard-library
`unittest` runner.

## Security model

- The login command keeps password and MFA entry in normal Chrome. It starts an
  ephemeral Chrome DevTools MCP process only after explicit terminal
  confirmation, attaches to the existing browser with user approval, captures
  DMS authentication, and then detaches. Manual file and stdin imports remain
  explicit recovery paths.
- The auth-context file must have mode `0600`; its parent directory should
  have mode `0700`.
- The Python code never opens Chrome profile databases or decrypts browser
  cookies. It consumes only the explicitly approved post-login DevTools session.
- Cookies, CSRF values, risk-control fields, login tokens, SQL Console
  credentials, raw WebSocket frames, and raw transport responses are treated as
  secrets.
- MCP tools return redacted status and bounded business results rather than raw
  browser state.
- SQL and CSV result data are sensitive even when transport metadata is
  redacted.
- Authentication failures stop the operation. The implementation avoids blind
  retries and does not fabricate browser risk-control values.
- Sensitive network-request details are parsed through short-lived private
  files and deleted immediately. Successful output reports that no raw capture
  files were retained.
- The project targets real DMS read-only operations. Use a least-privilege RAM
  account and verify the selected database before running a query.

Never commit `.local/`, auth-context files, copied cURL commands, exported
data, credentials, or browser captures.

Report security issues through the repository's private maintainer channel
rather than a public issue.

## License

Released under the [MIT License](https://opensource.org/license/mit).
