Enforces policy checks for AI agent writes with ALLOW, DENY, or STEP_UP decisions and a tamper-evident audit log.
Also known as withwrit/pywrit, writ-mcp
- Stars
- 2
- Tools
- 17
- Downloads, 30 days
- —
- Latest version
- 0.2.2
- Last commit
- Nov 13, 2026
- License
- MIT
What is Writ MCP?
Writ is an MCP server. Enforces policy checks for AI agent writes with ALLOW, DENY, or STEP_UP decisions and a tamper-evident audit log. It exposes 17 tools, such as writ_check, writ_verify_token, writ_lease.
Summary generated from the project's README
About Writ MCP server
Controlling consequential actions by AI agents through a policy gate is what this server enables. It provides a mechanism for agents to request permission before performing writes, receiving decisions like ALLOW, DENY, or STEP_UP. This process ensures that every action is backed by a tamper-evident audit receipt for security and accountability.
Developers can integrate this into Claude Desktop, Claude Code, or generic MCP clients using a stdio transport. Setting up the server requires a WRIT_API_KEY and optionally a WRIT_SPONSOR_TOKEN for managing grants or revocations. The workflow uses specific tools like writ_check to obtain a 90-second authToken and writ_execute to perform the gated request using a single-use lease.
Beyond simple permission checks, the server includes administrative tools for managing GitHub App installations, setting thresholds, and viewing tenant principals. It offers a sandbox mode for testing without an API key, allowing anyone to try the writ_check tool with a demo write verb.
What you can do with it
- 1Enforce gated write permissionsAsk the agent to check for permission before modifying a sensitive file or database entry.
- 2Require human approval for risky tasksInstruct the agent to trigger a manual review when it encounters a STEP_UP decision.
- 3Audit agent decision historyRequest a summary of all previous authorization decisions and outcomes.
- 4Securely execute gated API requestsHave the agent convert an authorization token into a single-use lease to perform a specific upstream request.
Written from the project's README. Every use case is checked against a quote from it.
How to install Writ MCP
Formats verified 10 Nov 2026Install Writ MCP in Claude Code
$ claude mcp add --env WRIT_API_KEY=<YOUR_WRIT_API_KEY> --env WRIT_SPONSOR_TOKEN=<YOUR_WRIT_SPONSOR_TOKEN> writ -- uvx writ-mcpInstall Writ MCP in Cursor
~/.cursor/mcp.json
{
"mcpServers": {
"writ": {
"command": "uvx",
"args": [
"writ-mcp"
],
"env": {
"WRIT_API_KEY": "<YOUR_WRIT_API_KEY>",
"WRIT_SPONSOR_TOKEN": "<YOUR_WRIT_SPONSOR_TOKEN>"
}
}
}
}Install Writ MCP in VS Code
.vscode/mcp.json
{
"servers": {
"writ": {
"type": "stdio",
"command": "uvx",
"args": [
"writ-mcp"
],
"env": {
"WRIT_API_KEY": "<YOUR_WRIT_API_KEY>",
"WRIT_SPONSOR_TOKEN": "<YOUR_WRIT_SPONSOR_TOKEN>"
}
}
}
}Install Writ MCP in Claude Desktop
claude_desktop_config.json
{
"mcpServers": {
"writ": {
"command": "uvx",
"args": [
"writ-mcp"
],
"env": {
"WRIT_API_KEY": "<YOUR_WRIT_API_KEY>",
"WRIT_SPONSOR_TOKEN": "<YOUR_WRIT_SPONSOR_TOKEN>"
}
}
}
}Install Writ MCP in Codex
~/.codex/config.toml
[mcp_servers.writ] command = "uvx" args = ["writ-mcp"] [mcp_servers.writ.env] WRIT_API_KEY = "<YOUR_WRIT_API_KEY>" WRIT_SPONSOR_TOKEN = "<YOUR_WRIT_SPONSOR_TOKEN>"
Install Writ MCP in Gemini CLI
~/.gemini/settings.json
{
"mcpServers": {
"writ": {
"command": "uvx",
"args": [
"writ-mcp"
],
"env": {
"WRIT_API_KEY": "<YOUR_WRIT_API_KEY>",
"WRIT_SPONSOR_TOKEN": "<YOUR_WRIT_SPONSOR_TOKEN>"
}
}
}
}Writ MCP tools 17
Detected from the READMEwrit_checkwrit_verify_tokenwrit_leasewrit_executewrit_grantwrit_receiptswrit_policywrit_sandboxwrit_github_installationswrit_github_set_thresholdwrit_github_toggle_pr_commentswrit_manifests
| writ_check | — | |
| writ_verify_token | — | |
| writ_lease | — | |
| writ_execute | — | |
| writ_grant | — | |
| writ_receipts | — | |
| writ_policy | — | |
| writ_sandbox | — | |
| writ_github_installations | — | |
| writ_github_set_threshold | — | |
| writ_github_toggle_pr_comments | — | |
| writ_manifests | — |
Show all 17 toolsShow fewer tools
writ_explain_receiptwrit_tenant_notifywrit_principalswrit_verbswrit_keys
| writ_explain_receipt | — | |
| writ_tenant_notify | — | |
| writ_principals | — | |
| writ_verbs | — | |
| writ_keys | — |
Configuration
WRIT_API_KEYRequiredSecretWrit API key (get one free at https://withwrit.com)
WRIT_SPONSOR_TOKENSecretWrit sponsor token, only required for sponsor tools (grant, revoke, reinstate)
WRIT_BASE_URLOptional custom Writ API base URL (default: https://api.withwrit.com)
| Name | Description | |
|---|---|---|
| WRIT_API_KEY | Writ API key (get one free at https://withwrit.com) | RequiredSecret |
| WRIT_SPONSOR_TOKEN | Writ sponsor token, only required for sponsor tools (grant, revoke, reinstate) | Secret |
| WRIT_BASE_URL | Optional custom Writ API base URL (default: https://api.withwrit.com) |
Automated checks
Ran Nov 13, 2026Full report →Passed our automated checks. That is not a security audit: read the code and give the server the narrowest access it needs. How checks work
- Source repository linked and reachablePass
- Open source license (OSI)Pass
- Commit or release in the last yearPass
- Package name not close to a popular packagePass
- Remote endpoint uses HTTPSNot checked
- Destructive tools are labelledPass
- No hidden instructions to the modelPass
- No critical advisory in the package or its dependenciesPass
README
View on GitHubwrit-mcp
The Writ gate as an MCP server. Give any MCP-compatible
agent point-of-action control: the agent calls Writ before a consequential
write, gets back ALLOW, DENY, or STEP_UP, and every outcome creates an
audit receipt.
Install
pip install writ-mcp
Requires Python 3.9+. Installs the writ-mcp command (stdio transport).
Configure
export WRIT_API_KEY="writ_..." # required; get one free: POST /v1/keys with an email
export WRIT_SPONSOR_TOKEN="..." # only for sponsor tools (grant, revoke, reinstate)
# export WRIT_BASE_URL="..." # default: https://api.withwrit.com
Add to your agent
Claude Code:
claude mcp add writ --env WRIT_API_KEY="$WRIT_API_KEY" -- writ-mcp
Claude Desktop (claude_desktop_config.json):
{
"mcpServers": {
"writ": {
"command": "writ-mcp",
"env": { "WRIT_API_KEY": "writ_..." }
}
}
}
Any MCP client (generic stdio config):
{
"command": "writ-mcp",
"env": {
"WRIT_API_KEY": "writ_...",
"WRIT_SPONSOR_TOKEN": "writ_sp_..."
}
}
Hermes (NousResearch/hermes-agent) catalog entry — once published, this
package is installable from the optional-mcps catalog:
hermes mcp install writ
The check-before-write loop
The tool descriptions teach the agent this flow, but the short version:
writ_check(sponsor_id, agent_id, verb, target, purpose)— before the write.ALLOW→ you get a 90-secondauthTokenbound to that exact write.writ_verify_token(auth_token, verb, target, purpose)— immediately before executing, to prove the authorization still matches what you're doing.DENY→ do not proceed.STEP_UP→ a human sponsor approves (viawrit_grantor the dashboard), then check again.writ_lease(auth_token, system_id, method, path, body)- convert the ALLOW token into a single-use lease bound to the exact upstream request.writ_execute(lease_id, method, path, body)- run the gated write with the same method/path/body; the gate forwards it with the vaulted credential and returns the upstream response verbatim.
Tools
| Tool | Who | What |
|---|---|---|
writ_check |
agent | Decision + 90s purpose-bound token |
writ_verify_token |
agent | Point-of-action token verification |
writ_lease |
agent | Convert an ALLOW token into a single-use gated-execution lease |
writ_execute |
agent | Run one gated upstream request with a lease or ALLOW token |
writ_grant |
sponsor | Approve a STEP_UP (one-time grant) |
writ_revoke / writ_reinstate |
sponsor | Kill switch on/off for a principal |
writ_receipts |
agent | Audit trail of decisions |
writ_policy |
agent | Tenant verb policy |
writ_sandbox |
anyone | Free 90-second demo grant, no key needed |
writ_github_installations |
admin | List connected GitHub App installations |
writ_github_set_threshold |
admin | Set the check-run fail threshold per install |
writ_github_toggle_pr_comments |
admin | Enable/disable the PR-comment bot |
writ_manifests |
agent | List repos with risk profiles or fetch one manifest |
writ_explain_receipt |
agent | Explain a receipt in plain language |
writ_tenant_notify |
admin | Get or update step-up notification settings |
writ_principals |
admin | List the tenant's principals |
writ_verbs |
admin | List the tenant's verb vocabulary |
writ_keys |
admin | List API key metadata |
Try it with no key: writ_sandbox → writ_check with verb="demo_write".
Source
Public repo: withwrit/pywrit (mcp/
directory). License: MIT.
Directory listings: Glama ·
MCP Registry io.github.withwrit/writ.
Writ MCP questions
How do I add Writ MCP to Claude Code?
Run claude mcp add --env WRIT_API_KEY=<YOUR_WRIT_API_KEY> --env WRIT_SPONSOR_TOKEN=<YOUR_WRIT_SPONSOR_TOKEN> writ -- uvx writ-mcp in your terminal. Add --scope user to make it available in every project.
How do I add Writ MCP to Cursor?
Open ~/.cursor/mcp.json and add the server under mcpServers, using the Cursor config shown in the install section above.
What tools does Writ MCP provide?
It exposes 17 tools, including writ_check, writ_verify_token, writ_lease, writ_execute, writ_grant.
What are the possible outcomes of a write check?
The agent receives an ALLOW, DENY, or STEP_UP decision.
How can I test Writ without an API key?
You can use the writ_sandbox tool for a free 90-second demo grant.
What happens during a STEP_UP decision?
A human sponsor must approve the action via writ_grant or the dashboard before the agent can proceed.