You ask your coding agent to write a project handoff note. It produces a draft, checks the required sections, fixes a missing detail, and returns: “Ready for your review.” You approve that version. When you ask it to resume, it creates the file and checks that the saved bytes match what you approved.
That is the workflow this starter implements. The result is a real Markdown file you can use for a runbook, release note or article draft. It does not publish a website or send a message.
Download the MCP starter (.tar) · Read the setup instructions (.md)
What we tested: a real MCP SDK client communicating with a separate stdio adapter, HTTP approval service, SQLite database, reviewer command and filesystem. We tested on macOS with Node 24.15.0. The Codex and Claude Code setup commands follow their official documentation and installed CLI help; a full model-driven conversation in either host has not been tested. This is a single-owner starter, not an audited production approval system.
Let the agent reason; let code check the result
Writing a useful handoff note requires judgment. Whether that note has a title, whether its approval expired, and whether an exported file matches the reviewed version can be checked with explicit rules.
- The agent drafts and revisesChoose wording, explain evidence, address the task.
- Code checks the structureReturn specific failures the agent can fix.
- You review the exact versionApprove or reject outside the agent’s tools.
- Code exports and verifiesWrite the approved bytes and compare the saved file.
The agent can work autonomously between these boundaries. It can fix a missing section and check again without asking you about every edit. It must stop when a proposal needs review. After approval, you tell it to resume; this package does not automatically wake a paused chat.
| Step | Who does it? | What it establishes |
|---|---|---|
| Draft and assess the explanation | Agent | A proposed answer that still needs judgment |
| Check headings, size and placeholders | Code | The named structural rules pass |
| Review accuracy and approve export | You | Permission for one version |
| Recheck approval and write the file | Code | The stored approved version passed this export route |
| Read back and compare the file | Code, called by the agent | The saved bytes match the approved bytes |
The checker does not browse sources, execute code blocks or detect every secret. A well-structured false statement still needs to be caught by review.
What you get in the download
The package contains five MCP tools:
check_markdown: return individual structural checks.request_approval: save a proposal and return its identifier, digest and expiry.approval_status: read whether it is pending, approved, blocked or exported.export_approved_markdown: create a file from the stored approved version.verify_export: read that file and compare its hash with the approved content.
It also includes AGENT-INSTRUCTIONS.md, which you can merge into your project instructions, and IMPLEMENT.md, which tells a coding agent how to integrate or extend the starter. Those files guide the agent. The service enforces the checks on requests it receives.
The exporter accepts only a proposal ID. It does not accept a new document or a destination path at execution time. Changing the draft means submitting a new version for review.
Try it with one document
Extract the archive and open a terminal in approval-mcp/. Use Node 24.15.0 for the tested runtime:
npm ci --ignore-scripts
npm test
Follow the included README to initialize the service and register its MCP adapter with one host. Both Codex and Claude Code document stdio MCP connections. The supplied setup uses that mechanism; it does not replace the host’s native permission controls.
Then give your agent this task:
Draft a short project handoff note with a title and Summary, Details and Verification sections. Use the AgentApprovals tools to check it, fix structural failures, and request approval. Show me the proposal ID and digest, then stop for review.
The required sections make the first task predictable. For example, a missing ## Verification section produces a failed check the agent can repair. Passing that check does not establish that the verification described in the note happened.
In your own terminal, inspect the proposal with review.mjs show, read the full document, and approve its displayed digest. The complete commands are in the setup file. Approval is not an MCP tool, and a chat message saying “approved” does not modify the service’s stored decision.
Tell the agent to resume, check the status, export and verify. The service creates:
AA_SERVICE_DIR/approved/PROPOSAL_ID.md
Open the file in your editor. You now have an approved document, plus a recorded decision and a comparison of the actual file with the reviewed content. Connecting it to Git, a website or another external destination requires a separately authorized integration.
Where the approval boundary actually lives
The quickstart runs under your own OS account. That is a cooperative workflow, not isolation from an unrestricted agent using that same account. Such an agent could bypass the service by changing the database, calling the reviewer command or writing the output directly. Putting the files in a different folder does not prevent that.
For an enforced boundary, the service, database, reviewer access and output directory must live outside the agent’s accessible environment. The agent gets only the request token and a protected connection. It must not also have an owner shell, filesystem access or another tool that can perform the protected action. The README describes this deployment boundary; the package does not provision or test it for you.
This first version has one shared owner workspace and one agent token. It has no tenant separation, reviewer accounts, quotas or public-hosting hardening. Do not expose its development HTTP service directly to the Internet.
What happens after a restart or a repeated request?
Proposals and decisions live in SQLite. An atomic claim precedes file creation, and the exporter uses exclusive creation at a generated filename. A repeated successful export returns a verification result without rewriting the file. Approval expires one hour after proposal submission; expiry is checked before claiming execution.
If execution is interrupted after claiming, the state can remain running. A reported write error becomes unknown. The service blocks automatic retries in either case. The owner can reconcile an existing file only when its bytes exactly match the stored content. A missing or different file stays blocked for investigation.
Those choices are specific to file export. They are not a recipe for exactly-once email, payments or deployment. Each new action needs its own result verification and recovery design. The earlier approval lifecycle guide explains why a timeout and a confirmed failure require different responses.
Use the pattern in your own workflow
Start by changing the document rules to fit one real task. Keep semantic judgments separate from mechanical results: the agent can explain why a draft is useful, while code checks named requirements and the person decides whether to approve it.
Then give the agent a bounded repair loop, a clear point where it must wait, and a way to inspect the actual result. Autonomy becomes useful when the agent can make progress, detect specific mistakes, and report what really happened. It should not have to invent its own evidence or permission.
The downloadable starter is an original implementation. The official MCP SDK supplies the protocol transport, and Node’s SQLite API supplies persistence. Our tests establish the recorded local behavior; they are not a security audit or a claim that the integration has run in every supported host.