11 KiB
name, description
| name | description |
|---|---|
| dingtalk-approval | Use the protected DingTalk Approval MCP to list, inspect, summarize, approve, reject, return, or create the signed-in user's DingTalk OA and XFT approvals, including approvals the user handled or submitted. Trigger for approval todos or history, expense review, reimbursement details, explicit approval actions, or requests to start and submit a new approval. |
DingTalk Approval
Use only the dingtalk-approval MCP tools. DingTalk OA and XFT use the same gateway-authenticated DingTalk user. Never ask for AppKey, Secret, userId, employee ID, cookies, or raw access tokens.
Login and first run
After installation or update, handle the installer's postInstall result immediately instead of waiting for the user's first approval request. If it contains authChallenge.directUrl, copy that complete clickable URL into the current user-facing reply. After the user authorizes, call approval_login, then make one read-only approval_list_todos call with source=all to verify both DingTalk OA and XFT. If login preparation was temporarily unavailable, keep the installation and call approval_login after the MCP is loaded.
When a successful response contains onboarding.firstRun=true, show its short examples and write-safety note to the user once. Do not execute an example automatically. The same onboarding may be returned directly in postInstall when an existing login is reused.
On first use or expired authorization, call approval_login. The tool does not send or push the login link through another channel. Copy the clickable URL from content.text verbatim into the current user-facing reply; when available, authChallenge.directUrl and the resource_link contain the same URL. Never merely claim that a link was generated or pushed, never read bridge state files to recover it, and never render QR images as ASCII. One successful login covers both approval sources.
Review and process
- Call
approval_list_todosfirst. Use itsapprovalIdvalues for one or some items. When the user explicitly asks to process the entire returned result set andbatchPolicy.selectionAvailable=true, prefer itsselectionId; it is bound to that exact live set and the gateway refuses the write if the set changes. - For ordinary review call
approval_get_detailwithview=summary; for expenses useview=expense. Use filteredrawpaging only when a required field is missing. - Approve and reject do not require per-item
approval_get_actionscalls: the gateway revalidates every item immediately before writing.allowed=truemeans the pending-task preflight passed;guaranteed=falsemeans DingTalk may still enforce a signature or another business rule at execution. Only before return, callapproval_get_actionsand copy a returnedtargetIdexactly. - Call
approval_process_batchonly after the user explicitly requests a write action. One call accepts at most 20 items. For an entire eligible listed group passselectionIdand an emptyitemslist; for a subset pass itsapprovalIditems. Never combine both. If one confirmed list contains more than 20 requested items, split only those originalapprovalIdvalues into groups of at most 20; do not relist between groups or mix newly appeared todos into the authorization. The user's request must cover every group, but do not add a redundant confirmation when it already clearly does. - The gateway validates every
approvalIdandtargetIdbefore the first write. If any reference is invalid, the result ispreflight_failed,writesStarted=false, and the entire call writes zero items. Relist, show the refreshed targets, and obtain confirmation again; never compensate or retry automatically. - Report every item result from the compact tool text.
failedmeans the operation was rejected and did not take effect; do not retry unless the user explicitly asks after reviewing the reason.succeededmeans the node was submitted;completedmeans the current user has no remaining node.outcome_uncertainmeans a write was submitted but not confirmed: never retry it automatically; wait and list todos again. If follow-up is required, list todos again. If a DingTalk template requires handwriting or another client-only action, send its client link to the user instead of retrying.
Review history
Call approval_list_history with scope=handled for approvals the current user already processed, or scope=submitted for approvals the current user initiated. The default window is the most recent 30 days. Use optional startDate and endDate for a specific window of at most 120 days; YYYY-MM-DD is interpreted in Asia/Shanghai, the end date is inclusive, and timezone-aware ISO 8601 timestamps are also accepted. Use source, query, and limit to narrow the live result. Historical approvalId values are user-bound, short-lived, and read-only: use them only with approval_get_detail. Never pass them to approval_get_actions or approval_process_batch; the gateway rejects them before any write. Historical results intentionally have no selectionId or available actions.
Create an approval
Create only XFT approvals and these DingTalk templates: 出差申请单_北极大, 外出_北极大, 业务招待申请_北极大, 差旅费用报销_捷康, 业务招待费用报销_捷康, and 业务招待申请_捷康. Other templates remain unsupported even when they are in the same DingTalk category; never attempt to construct or reuse a hidden template reference.
- Call
approval_list_submission_templatesand use only its returnedtemplateId. - Call
approval_get_submission_schema. Compare every required field infieldsandinputContractwith information the user has already supplied. Never guess a missing value. IfsubmissionCapability.statusisclient_only, stop API construction and tell the user to start that template in its native client. All six current DingTalk candidates are client-only: five contain unsupported business suites, while live enterprise-API tests rejected the ordinary table form in业务招待申请_北极大. XFT whitelist templates use their formal create APIs and are verified against live status after submission. For an XFT department or city code, callapproval_get_submission_optionswith the sametemplateId; use only a returnedcode. Department results are restricted to the current signed-in user's member record. Never invent or request an internal code when the tool can resolve it. For DingTalk, do not ask for or fill applicant and top-level department controls markedserverManaged; keepdeptId=-1unless the user selected a department that the gateway can verify belongs to them. The gateway derives the default department from the authenticated user's live directory record. - While any required field is missing or ambiguous, ask the user for the missing information and repeat the check after each answer. Prefer one concise question at a time, grouping fields only when they naturally belong together. Do not call
approval_prepare_submissionuntil all required fields are complete. - Explicitly show the remaining optional fields with short explanations and ask whether the user wants to add any. The user may choose to skip all optional fields; record that choice instead of silently omitting them.
- Call
approval_prepare_submissionwithallowDuplicateInvoices=false. It automatically checks invoice identifiers and expense signatures against the signed-in user's submitted DingTalk and XFT history for the most recent 30 days. If it reports another missing, invalid, unsupported, or selection-required field, return to the collection loop and ask until validation succeeds. Never work around validation. - If preparation returns
duplicate_confirmation_requiredorduplicate_check_unavailable, no submit-capableconfirmationIdwas created. Show the duplicate check's masked invoice evidence, matching source/business number/status, and coverage warning. Ask whether the user still wants to submit. Never infer consent from the original creation request. Only after the user explicitly accepts that exact risk, call prepare again with the same content andallowDuplicateInvoices=true. A rejected, revoked, or void prior bill is still a warning; a pending, approved, or unknown prior bill is blocking by default. If another active preparation reserved the same invoice, wait for or finish that preparation rather than overriding it. - Show the successful returned preview, including
duplicateCheck, and obtain explicit final confirmation to create the approval. Do not treat answers to field questions, the choice to skip optional fields, or the duplicate-risk acknowledgement as this final submission confirmation. - After final confirmation, call
approval_submitonce with the sametemplateId,values, department, selections,allowDuplicateInvoices, and returnedconfirmationId. Never modify the content or retry automatically.
If the user explicitly asks to undo a DingTalk or XFT approval just created through this MCP, call approval_revoke_submission once with the returned revokeId. Never use revoke to reject another person's todo, never accept a raw user ID, employee ID, or bill ID, and never automatically retry failed or outcome_uncertain. XFT recall is experimental in this release candidate: the current enterprise has returned XFTSYS9999 for a real pending bill and no successful XFT recall has been observed. State this limitation when relevant and never report a recall as successful unless the tool returns revoked after live reconciliation.
For an XFT submission or recall result that needs reconciliation, call approval_get_submission_status with the businessId returned by approval_submit. It is read-only and revalidates that the bill belongs to the signed-in user's initiated bills. Report statusName and the compact flow history. completed means the workflow finished immediately under the enterprise's approval rules (for example, no other effective approver); do not retry it. A fresh short-lived revokeId is returned only while the live bill status is pending approval; it still requires the user's explicit authorization before one recall attempt. Never treat status lookup alone as permission to repeat a write, and never retry completed, upstream_state_mismatch, or outcome_uncertain.
Never ask for or pass an applicant user ID, employee number, owner, or approval status. The gateway derives them from the authenticated user. For XFT custom fields, use the live fieldNumber and its declared valueFormat; people use roster-number arrays, departments use organization-code arrays, and tables use sequence/columnValues/titleCode. If a required field type is unsupported or XFT reports a missing employee profile or permission, explain the requirement and stop.