Skip to main content
Glama

pywrit

Find the dangerous writes in your Python agent's code, then gate it. pywrit is the Python client and writ CLI for Writ: an allow/deny gate that sits in front of your agent's consequential writes (database, HTTP, files, email, queues, AWS) and records a hash-chained receipt for every decision.

Listed on mcpservers.org

writ scan finds 4 write sites in a Python agent (0/4 gated); writ scan --apply inserts gates; a re-scan shows 4/4 gated

writ scan is local, deterministic, and free: it parses your code with Python's ast module, makes no network calls, and needs no API key.

Install

pip install pywrit

Requires Python 3.9+. Installs the writ command and the pywrit Python client.

JavaScript/TypeScript devs: run the scanner with no Python setup via npm:

npx writ-scan .

The writ-scan package wraps the same scanner (including TS/JS support). On first run it installs pywrit[polyglot] from PyPI using your Python 3.9+ (one-time); afterwards it starts instantly. See npm/ for details, environment overrides (WRIT_PYTHON, WRIT_SCAN_NO_INSTALL), and the install test.

Related MCP server: Vorim AI — Agent Identity & Trust

60-second quickstart: scan → apply → gate

1. Scan. See which functions write, and how many of them are gated.

writ scan .
writ scan: /path/to/support-agent
  files scanned: 4  skipped: 0
  write sites: 4 in 3 function(s)
  gated: 0/4 (0%)
  verbs discovered: 3
    crm.update
    payments.refund
    tickets.close

It also prints a risk report (0-100, weighted by risk tier), writes the discovered verbs to writ-policy.json, and shows the instrumentation it would add as a unified diff. Nothing in your code changes yet. writ scan . --score prints just the risk report.

2. Apply. Insert a gate at the top of each writing function.

writ scan . --apply        # shows the diff, then asks before writing
writ scan . --apply --yes  # no prompt (e.g. in CI)

Each gated function now asks Writ before it writes, and fails closed:

def issue_refund(charge_id, amount_cents):
    if _writ_check("payments.refund") != "ALLOW":
        raise PermissionError("writ denied payments.refund")
    ...

Re-run writ scan . and you'll see gated: 4/4 (100%).

3. Gate. Get a free API key, load the discovered policy, and run your agent.

writ key --email you@example.com                  # free API key + tenant
export WRIT_API_KEY=writ_...                      # read by the inserted gate
export WRIT_SPONSOR=acme WRIT_AGENT=support-agent # optional: who is acting
writ scan . --push-policy --key "$WRIT_API_KEY"   # upload the discovered verb policy

Every gated write now gets ALLOW, DENY, or STEP_UP (a human sponsor must approve), and every decision is written to your tenant's tamper-evident audit log:

writ receipts --key "$WRIT_API_KEY"       # latest receipts
writ verify-chain --key "$WRIT_API_KEY"   # verify the receipt hash chain
writ stream --key "$WRIT_API_KEY"         # tail decisions live
writ report --key "$WRIT_API_KEY"         # Agent Action Report

What writ scan detects

Python (.py) files, parsed with the stdlib ast (no extra dependencies):

Category

Examples

Database

cursor.execute(...) / executemany / executescript (write SQL only; SELECT/WITH/... skipped), session.add / commit / delete / merge / flush

HTTP

requests.post / put / patch, client.delete(...), session.request(...)

Files

open(..., "w"/"a"/"x"/"+"), Path.write_text / write_bytes / unlink / rename, os.remove / rename / makedirs, shutil.rmtree / move / copy

Email

sendmail, send_message, send_email

Queues

publish, produce, enqueue, queue.send(...)

AWS SDK

put_object, put_item, delete_item, upload_file, send_message, start_execution, ...

  • Each write is mapped to a verb such as payments.refund or crm.update, inferred from the file path and function name.

  • A function that already calls writ_check(...) / _writ_check(...) counts as gated.

  • Skipped: tests, hidden directories, virtualenvs, node_modules, dist, build. Use --exclude SUBSTR (repeatable) to skip more.

  • Not covered (review by hand): writes behind dynamically built SQL, third-party SDK calls such as stripe.Refund.create(...), deferred task queues, or shared clients several layers down. The risk report lists these gaps every time.

TypeScript / JavaScript (scan-only)

writ scan also finds write sites in TypeScript and JavaScript. It needs the optional extra (tree-sitter based):

pip install 'pywrit[polyglot]'
writ scan .

Without the extra, the scanner prints a one-line hint and keeps going — Python scanning never needs it.

TS/JS is scan-only: findings are listed with verbs for your policy file, but writ scan --apply never rewrites TS/JS files — gate those by hand. Covered patterns: fetch/axios writes, fs writes, SQL through knex-style clients, Prisma writes, and JS SDK calls such as stripe.refunds.create(...). (Still not covered: the Python SDK equivalents like stripe.Refund.create(...) — see "Not covered" above.)

writ scan on a TypeScript agent finds 5 write sites, 1 of 5 gated

GitHub Action

Scan every pull request for ungated write sites. Findings land as check annotations on the exact file and line, plus a Markdown risk report in the job summary. The check fails when an ungated finding meets your fail-on-risk threshold (default: high).

- uses: actions/checkout@v4
- uses: withwrit/pywrit@v0
  with:
    fail-on-risk: high   # high | medium | low | never

No API key needed. Full reference: docs/github-action.md · example workflow: examples/github-action/writ-scan.yml

MCP server (writ-mcp)

Give any MCP-compatible agent commit-time policy checks. writ-mcp is a Model Context Protocol server (stdio transport, built on the MCP Python SDK) that exposes the Writ gate as 8 MCP tools: the agent calls writ_check before a consequential write and gets back ALLOW, DENY, or STEP_UP — with a tamper-evident, hash-chained audit receipt for every decision.

uvx writ-mcp            # no install — runs on demand
# or
pip install writ-mcp   # then run `writ-mcp`

Tool

What it does

writ_check

The gate: ALLOW / DENY / STEP_UP for a proposed write

writ_verify_token

Validate an ALLOW auth token (catches purpose drift)

writ_grant

Human-sponsor approval for the STEP_UP path

writ_revoke / writ_reinstate

The kill switch

writ_receipts

Read the tenant's audit log

writ_policy

Manage the verb policy

writ_sandbox

Keyless 90-second demo grant — no API key needed

The gate tools need a free Writ API key (WRIT_API_KEY): 10,000 receipts/month free, no credit card. writ_sandbox works with no key at all.

The server implementation lives in mcp/ (MIT). Also published on the official MCP Registry as io.github.withwrit/writ and on Smithery.

Python client

from pywrit import WritClient

client = WritClient(api_key="writ_...")

result = client.check(
    sponsor_id="acme",
    agent_id="agent-7",
    verb="db.write",
    target="prod.customers",
    purpose="backfill region field",
)

if result.decision == "ALLOW":
    # result.auth_token is a short-lived token bound to this exact write
    perform_write(...)
elif result.decision == "STEP_UP":
    # a human sponsor must approve first: client.grant(...), then re-check
    ...
else:
    # DENY
    ...

No API key yet? Try the keyless sandbox:

client = WritClient()
client.sandbox({
    "sponsorId": "acme",
    "agentId": "agent-7",
    "verb": "demo_write",       # sandbox only allows demo_write ...
    "target": "demo-customers", # ... on targets starting with demo-
    "purpose": "trying the gate",
})

What's covered:

  • check(...): the gate. ALLOW / DENY / STEP_UP, plus a receipt every time

  • verify_token(...): validate an ALLOW auth token (catches purpose drift)

  • grant(...): human-sponsor approval for the STEP_UP path

  • get_policy() / set_policy(...): manage the tenant policy

  • revoke(...) / reinstate(...) / revoked(): the kill switch

  • receipts() / receipt(id) / verify_chain() / stream_receipts(): the audit log

  • sandbox(...): keyless trial, no API key required

CLI reference

writ check --key writ_... --sponsor acme --agent agent-7 \
  --verb db.write --target prod.customers --purpose "backfill region field"
writ policy --key writ_... --set payments.refund require_grant
writ revoke --sponsor acme --agent agent-7 --reason "runaway loop"   # kill switch (sponsor token)
writ grant --sponsor acme --agent agent-7 --verb payments.refund \
  --target ch_123 --purpose "approved refund"                        # STEP_UP approval (sponsor token)

Sponsor-token commands (revoke, reinstate, revoked, grant) read --sponsor-token or WRIT_SPONSOR_TOKEN. Run writ --help for the full command list.

README badge

Show that your agent's writes are gated by Writ. Two flavors:

Static (works today, no API key) — same design, no live count:

[![agent writes gated by Writ](https://cdn.jsdelivr.net/gh/withwrit/pywrit@main/badge/writ-gated.svg)](https://withwrit.com)

Dynamic (live 30-day gated-write count from your audit log) — mint a badge token, then embed the snippet the API returns:

curl -s https://api.withwrit.com/v1/badge/tokens \
  -H "Authorization: Bearer writ_..." \
  -H "Content-Type: application/json" \
  -d '{}'

The dynamic endpoint ships with the gate — until it's live, POST /v1/badge/tokens returns 404 and the static badge above is the one to use.

See badge/ for embed docs and the verification model (what the badge proves — and what it doesn't).

Docs

Full docs: docs.withwrit.com · Quickstart: docs.withwrit.com/quickstart · Site: withwrit.com

License

MIT

Available Tools

8 tools
writ_checkA

Ask Writ whether an action may proceed. CALL THIS BEFORE any consequential write.

A consequential write is anything hard to undo: sending money or messages, changing access or identity records, deleting data, calling an external API that acts in the world.

Args: sponsor_id: The human sponsor accountable for this action (e.g. a user id or email). agent_id: The agent or workflow performing the action. verb: What is being done (e.g. "verify_human", "send_payment"). target: What it acts on (e.g. "benefit-case-123"). purpose: Why, in plain words. Be specific — the approval is bound to this purpose.

Returns a decision: ALLOW — proceed. You get an authToken valid 90 seconds, bound to this exact sponsor/agent/verb/target/purpose. Call writ_verify_token against the intended write immediately before executing it. DENY — do NOT perform the action. Explain the receipt reason to the user. STEP_UP — a human sponsor must approve first. Tell the user what needs approval; they can approve via writ_grant (or the dashboard), then call writ_check again. Every outcome creates an audit receipt with a receiptId.

ParametersJSON Schema
NameRequiredDescriptionDefault
verbYes
targetYes
purposeYes
agent_idYes
sponsor_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden and does so richly: it enumerates all three decision outcomes (ALLOW/DENY/STEP_UP), discloses the 90-second authToken TTL and its binding scope, the required immediate follow-up via writ_verify_token, and the audit receipt side effect with receiptId.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the most critical instruction ('CALL THIS BEFORE any consequential write') before the Args list, and every section earns its place. It runs long, but the length is justified by the decision-state and token-lifecycle content; only minor trimming is possible.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite an output schema existing, the description still explains the decision semantics, token lifetime, and next-step routing an agent needs to act correctly. For a high-stakes gate tool with no annotations, nothing essential is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% and all five parameters are required, so the description must compensate — and it does, defining each parameter with role plus concrete examples ('verify_human', 'send_payment', 'benefit-case-123') and the binding constraint that approval is tied to purpose. This adds substantial meaning beyond bare string types.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource ('Ask Writ whether an action may proceed') and immediately distinguishes its role as the pre-write gate. An agent can tell it apart from writ_verify_token, writ_grant, and writ_receipts without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to call ('BEFORE any consequential write') and defines the trigger condition with concrete examples (money, messages, access/identity, deletion, external APIs). It names the alternatives and when to use them: writ_grant for STEP_UP, writ_verify_token after ALLOW.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

writ_grantA

SPONSOR ONLY. Mint a one-time grant approving a specific action.

Use this when writ_check returned STEP_UP and the human sponsor approves. The grant is single-use: the next writ_check consumes it and returns ALLOW. The grant is scoped to your tenant. Requires WRIT_SPONSOR_TOKEN.

ParametersJSON Schema
NameRequiredDescriptionDefault
verbYes
targetYes
purposeYes
agent_idYes
sponsor_idYes
ttl_secondsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does well: it discloses single-use consumption semantics ('the next writ_check consumes it and returns ALLOW'), tenant scoping, and the required WRIT_SPONSOR_TOKEN. It does not explain grant expiry behavior (ttl_seconds) or failure/error modes, which leaves a small gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four short sentences, front-loaded with the sponsorship constraint and purpose, then the trigger condition, then the consumption behavior. Every sentence adds distinct information with no repetition of the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The output schema exists so return values are covered, and the workflow context is strong, but for a 6-parameter, 0%-coverage security-sensitive tool the parameter and expiry semantics are under-specified. Adequate for routing, thin for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% and there are 6 parameters, so the description must compensate. It only vaguely gestures at 'verb', 'target', 'purpose' via 'a specific action', plus sponsor and token, while ttl_seconds, agent_id, and sponsor_id are never explained in a way that adds meaning beyond the bare property names.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Mint a one-time grant approving a specific action', with a hard scope qualifier ('SPONSOR ONLY'). It implies its role relative to writ_check, but does not explicitly contrast itself with the other siblings (writ_revoke, writ_verify_token, etc.).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit trigger condition: 'Use this when writ_check returned STEP_UP and the human sponsor approves.' This names the prerequisite tool and the human-approval gate, so the agent knows exactly when this tool is applicable rather than inferring it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

writ_policyA

Read the tenant's verb policy: which verbs allow, deny, require a grant, or step up.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It does convey that this is a read ('Read ...') and that the result describes allow/deny/grant/step-up rules, which is useful behavioral context. However, it says nothing about auth/tenant scoping requirements or whether the policy is cached or tenant-specific beyond the word 'tenant'.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One front-loaded sentence with no filler; the resource and its contents are stated up front and the sentence ends exactly where it should.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter read tool with an output schema already covering return values, the description is essentially complete: it states what is read and what the policy encodes. The only minor gap is the absence of any routing hint versus the sibling verbs.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so per the rubric the baseline is 4. There is nothing for the description to clarify beyond what an empty schema already communicates.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb ('Read') and resource ('the tenant's verb policy') and even enumerates the policy's contents (allow, deny, require a grant, step up). That is far more than a tautology. It stops short of explicitly differentiating itself from siblings like writ_check, which an agent could plausibly confuse with reading a policy.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: 'Read the tenant's verb policy' suggests a lookup use case, but there is no statement of when to call this versus writ_check or writ_grant, nor any prerequisite (e.g., tenant context or auth). Adequate but with a clear gap.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

writ_receiptsB

List recent decision receipts (audit trail). Newest first.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. 'List' safely implies a read-only operation and 'Newest first' discloses result ordering, which is useful behavioral context. However, it says nothing about pagination, whether the trail is complete or filtered by caller, or any access restrictions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with the resource named first and ordering front-loaded at the end. No wasted words, though it is arguably under-specified rather than maximally efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, and the tool is simple (1 optional param). Still, the absence of any usage context or access requirements leaves the definition marginally complete for an audit-trail tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There is one parameter (limit) with a default of 10 and 0% schema description coverage, and the description adds no meaning about what limit bounds or its maximum. The parameter name is self-explanatory but the description does nothing to compensate for the coverage gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (List) and resource (decision receipts / audit trail), and 'Newest first' clarifies ordering. It is reasonably distinguishable from the action-oriented siblings like writ_revoke or writ_grant, though it does not explicitly contrast with a potential alternative read tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description never states when to use this tool versus alternatives, nor any preconditions (e.g., which auth/role is required to view the audit trail). Usage is only implied by the word 'List'.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

writ_reinstateA

SPONSOR ONLY. Undo writ_revoke: the principal is evaluated by policy again.

Scoped to your tenant. Requires WRIT_SPONSOR_TOKEN.

ParametersJSON Schema
NameRequiredDescriptionDefault
agent_idYes
sponsor_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden and discloses key behavioral facts: sponsor-only restriction, tenant scoping, required token, and that the principal is re-evaluated by policy. It does not detail idempotency, error conditions, or side effects beyond the re-evaluation, but the core auth and effect context is present.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two short, front-loaded sentences with no filler. The most important constraint ('SPONSOR ONLY') is placed first, and every sentence contributes necessary information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The output schema exists, so return values need not be explained, and the description covers auth, scope, and effect. However, with 0% schema description coverage, the parameters remain unexplained in both schema and description, leaving a clear completeness gap for invoking the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% and the description does not mention or explain either required parameter (sponsor_id, agent_id). It does not compensate for the missing schema descriptions, leaving the meaning of both parameters undocumented.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Undo writ_revoke') and states the resulting effect ('the principal is evaluated by policy again'). It explicitly names the sibling operation it reverses, allowing an agent to distinguish it from writ_revoke and other writ_* tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It provides clear prerequisites and context: 'SPONSOR ONLY', 'Scoped to your tenant', and 'Requires WRIT_SPONSOR_TOKEN'. The use case is implied by 'Undo writ_revoke', but there is no explicit statement of when-not to use it or a named alternative for granting new access.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

writ_revokeA

SPONSOR ONLY. Kill switch: immediately deny all future checks for this principal.

Revocation overrides live grants and tenant policy. Use when a principal is compromised, misbehaving, or its task is done. Scoped to your tenant. Requires WRIT_SPONSOR_TOKEN.

ParametersJSON Schema
NameRequiredDescriptionDefault
agent_idYes
sponsor_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does well: it discloses the immediate effect, that revocation overrides live grants and tenant policy, that it requires a sponsor token, and that it is tenant-scoped. It omits whether the action is reversible or how to undo it (cf. writ_reinstate), which leaves a meaningful behavioral gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four short lines, front-loaded with the access restriction and the core effect, then rationale, then scope, then auth requirement. No filler sentences.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be described, and the safety/destructive profile plus auth requirements are covered. The residual gap is parameter meaning at 0% schema coverage, which is the one thing an agent still cannot infer.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% with two required parameters (sponsor_id, agent_id), and the description never explains what either identifier is or how sponsor_id relates to the authenticated WRIT_SPONSOR_TOKEN. The word 'principal' gestures at agent_id but adds no real semantic content beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a precise verb+resource+effect: 'Kill switch: immediately deny all future checks for this principal.' The scope ('Scoped to your tenant') and the contrast with siblings writ_check/writ_grant are clear enough that an agent can distinguish it from writ_reinstate and writ_grant without opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit triggering conditions ('compromised, misbehaving, or its task is done') and an access precondition ('SPONSOR ONLY', 'Requires WRIT_SPONSOR_TOKEN'). It stops short of naming the recovery alternative (writ_reinstate) or stating when not to revoke, so it is strong but not fully alternative-aware.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

writ_sandboxB

Get a free 90-second sandbox grant for a demo write. No API key needed.

Issues a live grant for verb "demo_write" on a target starting with "demo-", then runs writ_check so you get back an ALLOW decision plus auth token to practice the verify-before-write flow end to end.

ParametersJSON Schema
NameRequiredDescriptionDefault
targetYes
purposeYes
agent_idYes
sponsor_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the behavioral burden well: it discloses the 90-second lifetime, that no API key is required, the exact verb restricted to it, the target prefix constraint, and that it auto-runs writ_check returning an ALLOW decision plus auth token. Only minor gaps remain around failure modes (e.g., what happens with a non-'demo-' target).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core value is front-loaded ('Get a free 90-second sandbox grant'), with supporting detail after. It is compact and every sentence adds information, though the second sentence packs several nested clauses.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return contents need not be explained (the description still does, helpfully). However, for a 4-required-parameter tool at 0% schema coverage, three parameters have no semantics anywhere, leaving the agent unable to populate the call correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must define all four parameters. It only adds meaning for 'target' (must start with 'demo-'); sponsor_id, agent_id, and purpose are entirely unexplained in both schema and description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: issue a 90-second sandbox grant for a 'demo_write' on a 'demo-' target. It implicitly separates itself from writ_grant by being the free, no-key practice path, though it never names that sibling explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage context is implied: 'for a demo write' and 'to practice the verify-before-write flow end to end' suggest a sandbox/practice scenario. There is no explicit when-to-use versus the very similar writ_grant, and no when-not-to-use or prerequisites beyond the free/keyless note.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

writ_verify_tokenA

Verify a Writ auth token against the write you are about to execute.

Call this IMMEDIATELY before executing an ALLOWed write, with the exact verb/target/purpose you intend. If valid is false — expired, tampered, or bound to a different purpose — do NOT execute the write; call writ_check again.

This is the commit-time enforcement: the check authorizes, the token proves the authorization still matches what you are actually doing.

ParametersJSON Schema
NameRequiredDescriptionDefault
verbYes
targetYes
purposeYes
auth_tokenYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations exist, so the description carries the full burden, and it does disclose failure semantics (expired, tampered, purpose-bound mismatch) and the commit-time enforcement model. It stops short of stating that the call is side-effect free, whether it consumes or rotates the token, or any rate limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded imperative with the imperative instruction first, then the failure branch. The closing sentence ('the check authorizes, the token proves...') is a useful mental model rather than filler, though it is slightly repetitive of the opening.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value explanation is not required, and the description still explains what 'valid: false' means. For a four-required-param verification tool it is close to complete, missing only token format and whether verification has any side effects on the token's state.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% across four required params, so the description must compensate. It does clarify that verb/target/purpose must match the actual intended write exactly and that auth_token is a Writ auth token, but it gives no format guidance for the token, target identifiers, or purpose strings.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (verify) and resource (Writ auth token) scoped against a concrete action ('the write you are about to execute'). It also separates itself from the sibling writ_check by naming the check/verify division of labor: the check authorizes, the token proves it.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit timing ('Call this IMMEDIATELY before executing an ALLOWed write'), explicit input expectation (exact verb/target/purpose), and an explicit negative branch ('If valid is false ... do NOT execute the write; call writ_check again'). No inference required.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 8 tool updatesv0.1.0
    • First observedwrit_check
    • First observedwrit_grant
    • First observedwrit_policy
    • First observedwrit_receipts
    • First observedwrit_reinstate
    • First observedwrit_revoke
    • First observedwrit_sandbox
    • First observedwrit_verify_token

TDQS

A3.9/5.0

Scored across 8 tools

Disambiguation5/5

Each tool has a distinct role in the authorization lifecycle: check, verify token, grant, revoke, reinstate, receipts, policy, and sandbox. Descriptions clearly separate the stages, especially writ_check vs writ_verify_token and writ_grant vs writ_sandbox.

Naming Consistency5/5

All tools use the writ_ prefix with snake_case and descriptive verb or noun suffixes, forming a predictable and consistent pattern across the entire set.

Tool Count5/5

8 tools is well-scoped for an authorization and audit server, covering the core actions without redundancy or bloat.

Completeness4/5

The set covers the core check-grant-verify-revoke lifecycle plus audit receipts and policy read. A minor gap is the absence of a tool to update policy or manage tenant settings via MCP, but covered workflows can proceed.

Maintenance

ActivityNo data
ResponsivenessUnresponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    AI agent identity, permissions, trust scores, and tamper-evident audit trails. 17 MCP tools: register agents (Ed25519 keypairs), check permissions (sub-5ms), emit audit events, verify trust scores (0-100), delegate credentials, ephemeral agents. IETF Internet-Draft filed. Works with LangChain, OpenAI, CrewAI, Stripe ACP. npx @vorim/mcp-server
    17
    257 npm
    66
    MIT
  • A
    license
    B
    quality
    A
    maintenance
    A governance proxy for AI tools — every MCP/agent tool call is policy-gated, secret-redacted, and written to a hash-chained, offline-verifiable audit trail.
    13
    MIT
  • A
    license
    B
    quality
    A
    maintenance
    Commit-time audit engine for AI coding agents. Scans git diffs with 24 audit rules, writes HMAC-signed tamper-evident audit history, and ships MCP tools for governance aggregation.
    104
    51
    MIT