wecom-docs-mcp-server
# wecom-docs-mcp-server
> ## ⚠️ Archived 2026-08-18 — read this first
>
> **Unmaintained, and never published to PyPI.** The `pip install wecom-docs-mcp-server` line further down does not work and never did — install from source if you still want to run it.
>
> ### Why it's archived
>
> This server is a stdio proxy over WeCom's **robot-doc MCP** backend. Tencent's investment has visibly moved to a different surface: the official [`WecomTeam/wecom-cli`](https://github.com/WecomTeam/wecom-cli) (Rust; rewritten for v1.1.0 on 2026-08-17, 14 service domains) plus the official [`WecomTeam/wecom-unified`](https://github.com/WecomTeam/wecom-unified) agent skill. The robot-doc MCP backend has had no public update since 2026-04-22.
>
> ### What the official CLI now covers
>
> Verified against `@wecom/cli` v1.1.0 on 2026-08-18:
>
> | This project's selling point | Status in v1.1.0 |
> |---|---|
> | stdio transport | **Obsolete** — the CLI *is* a local process. Any agent that can run a shell needs no MCP layer at all. |
> | ms-epoch → ISO 8601 | **Obsolete** — the CLI returns `2026-08-17 12:17:25` directly. |
> | Chinese error hints | **Obsolete** — the CLI returns `help_message` + `help_instruction`, including a clickable authorization-repair link. |
> | Schema passthrough | **Obsolete** — every subcommand accepts `--schema` (full JSON Schema with field descriptions) and `--doc`. |
> | **Smartsheet cell unwrap** | **Still unsolved.** v1.1.0 still returns `values[field] = [{"type":"text","text":...}]`, and long rich-text cells fragment into dozens of segments. |
>
> ### If you came here to give an agent access to WeCom documents
>
> Use the official CLI, not this:
>
> ```bash
> npm install -g @wecom/cli
> npx skills add WecomTeam/wecom-unified -y -g
> wecom-cli auth init
> ```
>
> ### The one part still worth copying
>
> [`wecom_doc_mcp/transforms.py`](wecom_doc_mcp/transforms.py) — the cell-unwrap transform. ~120 lines, no MCP dependency. Lift it as a post-processing filter on CLI output rather than running this server.
>
> ### Two empirical findings worth keeping
>
> Observed 2026-07 against the robot-doc backend:
>
> - **`get_doc_content` and `smartsheet_get_*` use independent permission scopes.** The same bot can read a smartsheet via `smartsheet_get_records` (errcode 0) and still get `851003 no authority` from `get_doc_content` on that same document. Route reads by document type; one working scope proves nothing about the other.
> - **Pass the full document `url` including `?scode=`** rather than reconstructing `docid`. The backend resolves the URL; stripping prefixes by hand yields `301085 invalid docid`.
---
[](https://modelcontextprotocol.io)
[](https://python.org)
[](LICENSE)
[](#tests)
An ergonomic **stdio MCP facade** over WeCom's official **robot-doc MCP** backend. It proxies all 25 backend tools verbatim and adds a transform layer that makes the raw output usable by LLM agents:
- **Schema passthrough** — the tool list is fetched from the backend at startup, so it auto-tracks official updates. Zero schema maintenance.
- **Cell unwrap** — smartsheet `values[field] = [{"type":"text","text":...}]` cells become plain scalars (in a `_rows` view).
- **ms → ISO** — 13-digit ms-epoch timestamps (`create_time`, `update_time`) convert to ISO 8601.
- **Chinese error hints** — `errcode` 851003 etc. get `_error_summary` + `_error_hint` so the agent learns the fix, not just the code.
> **Relationship to the backend**: This server *requires* the official robot-doc MCP backend (an apikey from WeCom admin → 智能文档机器人 → API). It is a thin proxy + ergonomics layer, **not** a replacement.
---
## Why this exists
The official robot-doc backend is an **HTTP (StreamableHttp) MCP server**. Two friction points: (1) many MCP clients and dev workflows prefer **stdio**; (2) its raw output is agent-hostile — nested cell format, ms-epoch strings, opaque error codes. This server bridges both:
| | official robot-doc | this server |
|---|---|---|
| Transport | HTTP (StreamableHttp) | **stdio** |
| Tool schema | raw 25 tools | same 25, passthrough |
| Cell format | `[{"type":"text",...}]` | unwrapped scalars (`_rows`) |
| Timestamps | ms-epoch strings | ISO 8601 |
| Error codes | `851003` only | + Chinese summary + fix hint |
| apikey | required | required (proxied) |
---
## Requirements
- Python 3.9+
- A WeCom **智能文档机器人** (Smart Doc Bot) with its API key — available to enterprises (≥10 members) via WeCom admin → 应用管理 → 智能文档机器人 → API.
---
## Install
> ⚠️ **Never published to PyPI.** `pip install wecom-docs-mcp-server` returns 404. Source install is the only path.
Clone + editable:
```bash
git clone https://github.com/Beltran12138/wecom-docs-mcp-server
cd wecom-docs-mcp-server
pip install -e .
```
---
## Configuration
| Variable | Required | Description |
|---|---|---|
| `WECOM_MCP_APIKEY` | **yes** | robot-doc apikey |
| `WECOM_MCP_BASE_URL` | no | override backend URL (default `https://qyapi.weixin.qq.com/mcp/robot-doc`) |
### Claude Desktop (`claude_desktop_config.json`)
```json
{
"mcpServers": {
"wecom-doc": {
"command": "wecom-docs-mcp-server",
"env": { "WECOM_MCP_APIKEY": "your_apikey_here" }
}
}
}
```
---
## Tools
All 25 backend tools are exposed verbatim (fetched live at startup). By domain:
| Domain | Read | Write |
|---|---|---|
| **doc** | get_doc_content | create_doc, edit_doc_content, upload_doc_image, upload_doc_file |
| **smartsheet** (智能表) | get_sheet, get_fields, get_records | add/update/delete × sheet/fields/records |
| **sheet** (电子表格) | get_info | add_sub, delete_sub, update_range_data, append_data |
| **smartpage** (智能页面) | get_export_result | create, export_task |
> **Permission model (empirically observed 2026-07)**: `get_doc_content` and `smartsheet_get_*` use **independent permission scopes**. A bot may read a smartsheet via `smartsheet_get_records` (errcode 0) yet get `851003 no authority` from `get_doc_content` on the same doc. Route reads by doc type.
---
## Transforms (the value-add)
Applied automatically on every `tools/call` response:
1. **`_rows`** on `smartsheet_get_records` — a flattened view where cells are unwrapped to scalars and top-level record fields (`record_id`, `create_time`, …) are preserved. The original `records` array is kept intact.
2. **ms → ISO** on all successful dict payloads — 13-digit ms-epoch strings → ISO 8601. Alphanumeric IDs (`q979lj`) are untouched.
3. **`_error_summary` + `_error_hint`** on any non-zero errcode — Chinese explanation + concrete fix.
---
## Usage
Read a smartsheet end-to-end:
```
User: read https://doc.weixin.qq.com/smartsheet/s3_xxx?scode=yyy
Agent:
1. smartsheet_get_sheet(url=...) → sheet_id (e.g. "q979lj")
2. smartsheet_get_fields(sheet_id, url) → field schema (types, IDs)
3. smartsheet_get_records(sheet_id, url) → records + _rows (cells unwrapped, timestamps ISO)
```
> Pass the full `url` (with `?scode=`) rather than guessing `docid` — the backend resolves it. Manually extracting docid by stripping prefixes is error-prone (empirically: `301085 invalid docid`).
---
## Troubleshooting
| errcode | meaning | fix |
|---|---|---|
| 851000 | 文档链接有误 | check url + scode, or use docid |
| 851002 | 文档类型与工具不兼容 | smartsheet → use `smartsheet_get_*` |
| 851003 | 无文档权限 | smartsheet 用 `smartsheet_get_*`;普通文档查后台权限 |
| 851008 | 缺文档内容读取权限 | 企微后台 → 机器人 → API 权限 |
| 301085 | 无效 docid | 用完整 url 含 scode |
| 40058 | 参数缺失 | smartsheet 需 sheet_id(先 get_sheet)|
---
## Related
| Project | Focus |
|---|---|
| official robot-doc MCP | backend (HTTP, ≥10 人企业) |
| [wecom-bot-mcp-server](https://github.com/loonghao/wecom-bot-mcp-server) | bot messaging via webhook |
| **this server** | **robot-doc stdio proxy + ergonomics** |
---
## Tests
```bash
pip install -e ".[dev]" # or: pip install pytest httpx
pytest
```
25 unit tests cover SSE/JSON parsing, ms-timestamp normalization, cell unwrap, error humanizing, and server routing/post-processing — all offline (httpx mocked).
---
## License
MIT
TDQS
Scored across 9 tools
Tools are mostly distinct: docs (create, edit, get, read) vs smartsheets (add_records, get_fields, get_records, get_sheet, setup_fields). However, wecom_get_doc_content and wecom_read_doc overlap in purpose (both fetch content), though read auto-detects smartsheets, creating slight ambiguity.
All tools follow wecom_verb_noun pattern, but verbs vary (create, edit, get, read, add, setup). Consistent snake_case and prefix, but 'get' vs 'read' for similar operations is a minor inconsistency.
With 9 tools covering document and smartsheet operations, the count is well-scoped. Each tool serves a clear purpose without redundancy, appropriate for the domain.
Covers core CRUD for docs (create, edit, read) and smartsheets (schema, records, sheets). Missing delete/update for smartsheets or document deletion, but essential workflows are complete, so minor gaps.