8.8 KiB
Create, submit, and revoke 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. UseinputContract.values.minimalExampleonly as the exact JSON shape forvalues. Replace every angle-bracket placeholder from the user's business answer or the selected live option; never submit a placeholder literally. Continue to enforce the recursivestandardFieldsconstraints even when the example omits optional fields. 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业务招待申请_北极大. Supported XFT templates use their formal create APIs and are verified against live status after submission. XFT use-car applications are outside the MCP scope: they must not appear in the candidate list, and an old reference must be treated as unsupported rather than reconstructed. Treat every XFT selection as a label-only user interaction. For a field withoptionSource, callapproval_get_submission_optionswith the sametemplateIdand show only returnedlabelvalues. After the user chooses a label, copy that exact item'scodeinto the correspondingvaluesfield for prepare/submit; never put the label itself into a code-valued field. Keep itscodeonly inside tool arguments and never repeat it in conversation. Apply the same rule to inlineoptions; for an inline enum show onlyenumLabelsvalues and internally use the matching enum key. Department results are restricted to the current signed-in user's member record. Never show, explain, or ask the user for a field code, city code, organization code, employee number, archive number, numeric cabin value,expenseNumber,expenseTypeNumber,expTypeCode, or other internal ID. IfselectionCapability.status=client_only, do not ask for the internal value or guess it: a required field stops MCP creation and requires the native client; an optional field may be skipped, or the user may choose native-client completion. If a required option source cannot return readable labels, stop and offer retry or native-client completion. 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 user-visible, API-supported optional business fields with short explanations and ask whether the user wants to add any. Do not present fields marked
userVisible=false,serverManaged,internallyDerived, orselectionCapability.status=client_onlyas ordinary questions. Briefly mention client-only optional capabilities only when they are relevant to the user's request. The user may choose to skip all optional fields; record that choice instead of silently omitting them. - Call
approval_prepare_submissionwithallowDuplicateInvoices=false. For an XFT field withattachmentCapability.status=supported, pass its user-selected local file in the Bridge-onlyattachmentsarray, not invalues; the Bridge validates the regular file and sends only field name, file name, size, and SHA-256 for the no-upload preview. It automatically checks invoice identifiers, attachment hashes, 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. The preview is already converted back to business labels; repeat those labels exactly and never replace them with values retained from Schema construction. If the gateway cannot map any selection back to a current label, it will refuse to create aconfirmationId; refresh the live options instead of exposing the unresolved value. 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, localattachments, department, selections,allowDuplicateInvoices, and returnedconfirmationId. The signed Bridge revalidates and uploads attachments only at this point; the gateway never receives local paths and does not persist file bytes. 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, keep live fieldNumber, option codes, table titleCode, and serialization details internal to the tool call. Departments must be selected by returned department names; person fields currently require the native client because the MCP has no safe name lookup. If a required field type is unsupported or XFT reports a missing employee profile or permission, explain the business requirement without exposing internal identifiers and stop.
Local file paths and file bytes are not valid values or customFieldValues. Use the signed Bridge attachments argument only when the live XFT Schema reports attachmentCapability.status=supported; prepare validates without uploading, and submit uploads only after final confirmation. If the host lacks the signed Bridge or the field does not advertise attachment support, preserve any local draft and direct the user to complete that form in the native client. Never pass base64 content or an invented attachment number.