Approval MCP Server — multi-stage approval workflows (quorum, sequential, sign-off) for legal and media-content agents, with delegation, escalation, and an immutable audit trail
Approval MCP Server
A multi-stage approval workflow engine for ADK-Rust Enterprise legal and media-content agents. 17 MCP tools: configurable workflow templates, stage rules (all-of / any-of / quorum), decisions with delegation and escalation, SLA/expiry clocks, and an immutable audit trail on every action.
Yes — this is the approval-workflow server
An approval system is a workflow engine. One model — an ApprovalRequest moving through an ordered set of Stages, each with a decision rule and eligible approvers — serves every agent below. The variety is in the routing, not the mechanics.
| Domain | Agent | Typical workflow shape | |--------|-------|------------------------| | Legal | Board Consent Drafter | single stage, quorum (N-of-M directors) | | Legal | Contract Review Agent | sequential Legal → Finance → Exec | | Legal | Policy Compliance Reviewer | compliance sign-off gate | | Media | Brand Compliance Reviewer | brand any-of review | | Media | Content Localization Agent | linguistic QA → in-country review | | Media | Publishing QA Agent | editorial QA gate | | Media | Rights Clearance Assistant | rights review → legal clearance | | Media | Social Post Producer | fast content review before publish |
Architecture
Core Concepts
- Workflow template — a reusable, ordered list of stages for a request type. Eight defaults ship (one per agent above); create your own with
create_workflow. - Stage rule — how a stage resolves from its votes:
all_of— every eligible approver must approveany_of— one approval advancesquorum— at least N approvals (e.g. 3 of 5 directors)
- Decision —
approve·reject·request_changes·abstain. A reject fails the request; request-changes bounces it back to the requester for resubmission. - Delegation — an approver can delegate authority; the delegate's vote is recorded on behalf of the original (preserved in the audit trail).
- Escalation — reassign the active stage to new approvers (e.g. on SLA breach).
- Audit trail — every mutation appends an immutable entry (actor, action, timestamp). Essential for board consents and legal sign-offs.
Tools (17)
Agentic (2)
| Tool | What It Does |
|------|-------------|
| intake_and_route | Create and submit a request in one step, auto-selecting the default workflow for the type |
| request_status | Concise status: workflow position, approvals vs. needed, outstanding approvers, next step |
Workflow Templates (3)
| Tool | What It Does |
|------|-------------|
| list_workflows | List templates (optionally by domain) |
| get_workflow | Get a template's full stage definitions |
| create_workflow | Define a custom workflow (stages, rules, approvers, SLAs) |
Requests & Lifecycle (6)
| Tool | What It Does |
|------|-------------|
| create_request | Open a request bound to a workflow (optionally submit) |
| get_request | Full detail: stages, votes, comments, attachments, audit |
| search_requests | Filter by text, domain, type, status, approver |
| submit_request | Route a draft for review (activate first stage) |
| cancel_request | Withdraw a request (gated) |
| escalate | Reassign the active stage to new approvers (gated) |
Decisions & Collaboration (6)
| Tool | What It Does |
|------|-------------|
| decide | Record a decision on the active stage; evaluates the rule (gated) |
| my_queue | Requests awaiting a given approver |
| delegate | Delegate approval authority for a request (gated) |
| add_comment | Comment on the request thread |
| add_attachment | Attach a document/evidence reference (by URI) |
| get_audit_trail | Immutable record of who did what, when |
Example — board written consent (quorum 3 of 5)
> intake_and_route(domain: "legal", request_type: "board_consent",
title: "Approve 2026 budget", requester: "secretary", subject_ref: "consent:BUDGET-2026")
→ routed AR-1003 · active stage "Board Vote" (quorum)
> decide(id: "AR-1003", approver: "dir.1", decision: "approve") → in_review (1 of 3)
> decide(id: "AR-1003", approver: "dir.2", decision: "approve") → in_review (2 of 3)
> decide(id: "AR-1003", approver: "dir.3", decision: "approve") → approved (quorum met)
> get_audit_trail(id: "AR-1003")
→ created · submitted · decision ×3 · stage_approved · approved
Example — contract review (sequential, with delegation)
> create_request(request_type: "contract_review", title: "MSA with Acme",
requester: "legalops", subject_ref: "contract:MSA-ACME", submit: true)
→ AR-1010 · stage "Legal Review"
> delegate(id: "AR-1010", from: "legal.counsel", to: "legal.associate", reason: "OOO")
> decide(id: "AR-1010", approver: "legal.associate", decision: "approve")
→ advances to "Finance Review" (vote recorded on behalf of legal.counsel)
Installation
1. Build
git clone https://github.com/zavora-ai/mcp-approval
cd mcp-approval
cargo build --release
2. Add to your MCP client
Claude Desktop / Kiro / Cursor / Windsurf:
{
"mcpServers": {
"approval": {
"command": "/path/to/mcp-approval"
}
}
}
3. Use it
> list_workflows(domain: "media_content")
> intake_and_route(domain: "media_content", request_type: "social_post",
title: "Launch thread", requester: "social.producer", subject_ref: "post:LAUNCH-01")
Governance & Data Handling
- Gated writes —
decide,cancel_request,escalate, anddelegaterequire approval in production (requires_approval); reads areread_only. - Defensible audit — every state change is recorded immutably with actor and timestamp.
- No raw documents — items under approval and attachments are opaque references/URIs, never embedded content.
- Integration scaffold — the in-memory store is for development; back it with a durable store and bind
approver/actorto authenticated identities in production.
MCP Server Manifest
server_id = "mcp_approval"
display_name = "Approval Workflows"
version = "1.0.0"
domain = "governance"
risk_level = "high"
writes_allowed = "gated"
transports = ["stdio"]
Contributors
| 
James Karanja Maina |
|:---:|
License
Apache-2.0 — see LICENSE for details.
Part of the ADK-Rust Enterprise MCP server ecosystem.
Registry Compliance
This server implements the ADK MCP SDK contract:
- HealthCheck — async health probe for registry monitoring
- mcp-server.toml — manifest declaring tools, risk classes, and approval gates
- Structured tracing —
RUST_LOGenv-filter for observability