Skip to content

keithyt06/quick-dingtalk-mcp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

99 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

quick-dingtalk-mcp

Talk to DingTalk as yourself — from Amazon Quick Desktop and any other MCP host.

An MCP server that wraps DingTalk's official CLI (dws) so an AI assistant can send and read DingTalk messages with your real user identity — your avatar, your name in the group — instead of posting as a bot.

License: MIT MCP

English · 中文

quick-dingtalk-mcp architecture: Local and Remote MCP, both from Amazon Quick Desktop to DingTalk


Why this exists

DingTalk's own MCP server (open-dingtalk/dingtalk-mcp) only speaks as a bot — your teammates see a robot talking in the group, not you. That's wrong for a personal assistant.

This project takes the opposite route. It wraps dws, DingTalk's official CLI, which authenticates over user-identity OAuth. So when you tell your assistant "post 'meeting moved to 3pm' in the project group", the message lands authored by you — exactly as if you'd typed it.

dws is itself a thin client to DingTalk's MCP gateway (mcp-gw.dingtalk.com), meaning DingTalk's backend is already MCP-native. This project exposes that capability in two ways:

Local MCP Remote MCP
Who it's for Just you, on your own machine A whole team, shared
Runs where dws on your laptop, stdio to the host AWS Bedrock AgentCore + Lambda, HTTPS
Setup npm install + dws auth login (~5 min) Admin deploys once; each teammate self-authorizes
Identity Your own logged-in dws session Per-user OAuth, isolated per teammate
Best when Personal use, fastest start Many users, central audit, no local install

Both expose the same 38 tools (see Tools) backed by the same shared command catalog.


Local MCP

Run it on your own machine and wire it into Amazon Quick Desktop (or Claude Desktop, Cursor) over stdio.

You type            Amazon Quick Desktop          quick-dingtalk-mcp              dws CLI                 DingTalk
"post in X group" ──→  (MCP host) ──stdio──→ node packages/local/server.mjs ──exec──→ dws chat ... ──HTTPS──→ mcp-gw.dingtalk.com

1. Install the DingTalk CLI

npm install -g dingtalk-workspace-cli

Your DingTalk org must have CLI access enabled. Admins: open-dev.dingtalk.com → "CLI 访问管理" → enable (once, org-wide). Members hitting a not-enabled wall get a one-click request prompt at login.

2. Get the project

git clone https://github.com/keithyt06/quick-dingtalk-mcp.git
cd quick-dingtalk-mcp
npm install

3. Log in to DingTalk (as you)

dws auth login --device      # device flow — works over SSH / headless too

Scan the code with your DingTalk app to authorize. This is the step that makes messages post as you.

4. Connect Amazon Quick Desktop

First grab two absolute paths (Quick Desktop's child process doesn't inherit your full PATH, so absolute paths are the reliable choice — and no spaces in the path):

which node                                  # e.g. /opt/homebrew/bin/node
echo "$(pwd)/packages/local/server.mjs"     # the server entrypoint

Then in Amazon Quick Desktop → Settings → Capabilities → MCP → + Add MCP:

Field Value
Connection type Local
ID quick-dingtalk-mcp
Name quick-dingtalk-mcp
Command the which node path
Arguments the server.mjs absolute path

Save. You should see quick-dingtalk-mcp · 38 tools · Connected ✅.

Once connected, asking it to look you up returns your real DingTalk identity — proof the chain works end to end:

Amazon Quick Desktop connected to quick-dingtalk-mcp, returning the user's own DingTalk profile

5. Try it

In a Quick Desktop chat:

List my recent DingTalk chats, then post a markdown message titled "test"
with body "hello from quick-dingtalk-mcp" to chat_id=cidXXXX.

Full walkthrough (incl. Claude Desktop / Cursor, troubleshooting, the "is it really me?" verification) → packages/local/docs/setup.md


Remote MCP

A shared, multi-user deployment on AWS Bedrock AgentCore. One deploy serves any number of teammates — onboarding a new person is self-service, with zero code changes and no redeploy.

Each teammate           Amazon Quick Desktop                 AWS
authorizes once  ──→  (MCP host, HTTPS + Bearer) ──→ CloudFront → API GW → mcp-middleware (Lambda)
                                                          │  verify HMAC token, load *this user's* DingTalk token
                                                          ▼
                                                   AgentCore Runtime (container running dws, per-user config)
                                                          │
                                                          ▼
                                                       DingTalk  (authored by that teammate)

Each teammate's DingTalk token is stored, KMS-encrypted, per userId in Secrets Manager; the container gives each user an isolated dws config. DingTalk tokens auto-refresh on a schedule, and your connection stays valid as long as you keep using it — the backend tracks a per-user activity window (90 days idle before re-auth is needed), so a one-time setup just keeps working.

Admin: deploy once

curl -fsSL https://raw.githubusercontent.com/keithyt06/quick-dingtalk-mcp/main/packages/remote/scripts/install.sh | bash
~/.quick-dingtalk-mcp/packages/remote/scripts/deploy.sh

deploy.sh provisions everything (CloudFront, API Gateway, Lambdas, DynamoDB, Secrets Manager, the AgentCore Runtime container) and prints:

  • the authorize URL to hand to teammates
  • the MCP endpoint (https://<domain>/mcp) they paste into Amazon Quick Desktop

Prereqs: a DingTalk app (AppKey/AppSecret) with <domain>/callback registered as its redirect URL, AWS credentials (pick any AgentCore-supported region via AWS_REGION, default us-east-1), Docker, and Node ≥ 22.6. Chicken-and-egg (you don't know the domain before deploying)? Run deploy.sh --only-oauth first — it deploys just the gateway, prints the CloudFront domain to register with DingTalk, then re-run the full deploy. Updating later? Just re-run deploy.sh — it's idempotent (the signing key and stored secrets are preserved). Full deployment guide (prereqs, two-phase first deploy, updates, smoke tests, teardown) → docs/remote-deploy.md · day-2 operations → docs/remote-operations.md.

Teammate: connect your MCP client

The gateway is a standard OAuth 2.1 Authorization Server, so your client can connect in one of two modes. They differ only in how your client obtains the credential — both reach the same backend (which runs dws under your DingTalk identity) and behave identically once connected. Pick by what your client supports:

Remote MCP two connection modes: Mode A OAuth wizard (client auto-handles auth) and Mode B manual Bearer (you copy-paste once), both converging on the same dws backend

Mode A — OAuth wizard (recommended) Mode B — manual Bearer (fallback)
Use when your client has an OAuth login (Amazon Quick does) your client only lets you set a fixed header
What you do fill a few URLs, click Approve once open a URL, copy a Bearer token into a header
Token upkeep client auto-refreshes — you never touch a token paste once; stays valid while in use (re-auth after 90 days idle)

Mode A — OAuth wizard (recommended)

In Amazon Quick: Connectors → Add connector → MCP (not Settings → MCP), choose User authentication, and fill:

Field Value
MCP endpoint https://<domain>/mcp
Authorization URL https://<domain>/authorize
Token URL https://<domain>/token
Client ID quick
Client Secret placeholder (any non-empty value)
Scope openid

Save → Quick pops a login button → approve with your DingTalk account → it wires up the token and shows 38 tools. You authorize once; Quick auto-refreshes the token from then on.

Client ID must be exactly quick — the gateway pre-registers this client (Quick's form requires an ID and doesn't self-register via DCR). The secret isn't checked (PKCE is). Make sure the domain is identical in all three URLs — one mistyped character breaks the login page.

Mode B — manual Bearer (fallback)

For clients without an OAuth wizard: open https://<domain>/authorize in a browser, approve with your DingTalk account, and copy the Bearer … it returns. In your client set Connection type: Remote / HTTP, transport: streamable-http, URL = https://<domain>/mcp, and header Authorization: Bearer <that value>.

Then verify (either mode): ask "use dingtalk to look up my own profile" — it returns your real org/department. You never touch the DingTalk developer console; the app is the admin's, you just authorize with your own account.

Step-by-step onboarding (recommended OAuth path, beginner-friendly) → docs/remote-新人首配-oauth.md · technical reference (transport, troubleshooting matrix, admin setup) → docs/remote-quick-desktop.md


Tools

38 tools, identical across Local and Remote, backed by a shared catalog that covers all 261 dws commands:

Group Count What
Named tools 30 The common ones, exposed directly: dingtalk_chat_message_send / _list / _search / _recall / _reply / _forward, dingtalk_contact_user_search / _get_self, dingtalk_calendar_event_create, dingtalk_doc_create / _read, dingtalk_todo_task_create, dingtalk_ding_message_send, …
Discover + invoke 2 dingtalk_discover (keyword-search the full catalog) + dingtalk_invoke (run anything it returns) — reaches all 261 commands without bloating the tool list
Aliases 6 Older names kept working, marked [deprecated, use …]

Covers IM, contacts, calendar, docs/drive, todo, DING, attendance, OA approval, AI table, minutes, mail, and more. Every DingTalk message requires a title (unlike Feishu) — the catalog enforces it.


Comparison

This project open-dingtalk/dingtalk-mcp Custom robot webhook
Posts as You (real user) A bot A robot
Auth User OAuth (dws) App credentials Webhook URL
Read history / search ❌ / limited
Group display Your avatar + name Bot Robot name

Want the assistant to be you? Use this. Want clearly-labelled automation? Use the bot/webhook routes.


Docs

Full index (by audience): docs/README.md

Contributing

Issues and pull requests are welcome — bug reports, new region availability notes, doc fixes, and tool-catalog improvements are all fair game. Before sending a PR:

npm run test:all     # 125 tests must stay green (Node ≥ 22.6)

A few house rules: packages/shared/catalog.json is generated (npm run build:catalog), never hand-edited; changes in packages/shared/ affect both Local and Remote, so run the full suite; never commit real AppKeys, tokens, account IDs, or live domains.

Acknowledgments

License

MIT © Keith Yu

About

User-identity DingTalk MCP server. Wraps the official dws CLI to expose your real DingTalk identity (not a bot) to Amazon Q Desktop / Claude Desktop / Cursor / any MCP host.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages