pywrit 0.2.6__tar.gz → 0.2.8__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pywrit
3
- Version: 0.2.6
3
+ Version: 0.2.8
4
4
  Summary: Python client + CLI for Writ — the gate before the write
5
5
  License-Expression: MIT
6
- Project-URL: Homepage, https://github.com/AvenueDAdmin/pywrit
6
+ Project-URL: Homepage, https://github.com/withwrit/pywrit
7
7
  Project-URL: Documentation, https://withwrit.com/docs
8
8
  Requires-Python: >=3.9
9
9
  Description-Content-Type: text/markdown
@@ -27,7 +27,9 @@ client and `writ` CLI for [Writ](https://withwrit.com): an allow/deny gate that
27
27
  in front of your agent's consequential writes (database, HTTP, files, email, queues,
28
28
  AWS) and records a hash-chained receipt for every decision.
29
29
 
30
- ![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](https://raw.githubusercontent.com/AvenueDAdmin/pywrit/main/docs/assets/scan-python.gif)
30
+ [![Listed on mcpservers.org](https://mcpservers.org/badge.svg)](https://mcpservers.org/servers/avenuedadmin/pywrit)
31
+
32
+ ![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](https://raw.githubusercontent.com/withwrit/pywrit/main/docs/assets/scan-python.gif)
31
33
 
32
34
  `writ scan` is **local, deterministic, and free**: it parses your code with Python's
33
35
  `ast` module, makes no network calls, and needs no API key.
@@ -52,7 +54,7 @@ first run it installs `pywrit[polyglot]` from PyPI using your Python 3.9+
52
54
  environment overrides (`WRIT_PYTHON`, `WRIT_SCAN_NO_INSTALL`), and the
53
55
  install test.
54
56
 
55
- ## 60-second quickstart: scan → apply → gate
57
+ ## 60-second quickstart: scan → wrap → gate
56
58
 
57
59
  **1. Scan.** See which functions write, and how many of them are gated.
58
60
 
@@ -75,14 +77,17 @@ It also prints a **risk report** (0-100, weighted by risk tier), writes the disc
75
77
  verbs to `writ-policy.json`, and shows the instrumentation it would add as a unified
76
78
  diff. Nothing in your code changes yet. `writ scan . --score` prints just the risk report.
77
79
 
78
- **2. Apply.** Insert a gate at the top of each writing function.
80
+ **2. Wrap.** One command takes the repo from unwrapped to wrapped: scan, show the diff,
81
+ ask for explicit approval, apply the gates, and report before/after coverage.
79
82
 
80
83
  ```bash
81
- writ scan . --apply # shows the diff, then asks before writing
82
- writ scan . --apply --yes # no prompt (e.g. in CI)
84
+ writ wrap . # interactive approval
85
+ writ wrap . --yes # no prompt (e.g. in CI)
83
86
  ```
84
87
 
85
- Each gated function now asks Writ before it writes, and fails closed:
88
+ `--dry-run` previews the plan and exits before prompting; `--diff-only` prints the
89
+ unified diff for review tools. Each gated function now asks Writ before it writes, and
90
+ fails closed:
86
91
 
87
92
  ```python
88
93
  def issue_refund(charge_id, amount_cents):
@@ -91,7 +96,8 @@ def issue_refund(charge_id, amount_cents):
91
96
  ...
92
97
  ```
93
98
 
94
- Re-run `writ scan .` and you'll see `gated: 4/4 (100%)`.
99
+ `writ scan . --apply` is still available as the manual alternative. Re-run `writ scan .`
100
+ and you'll see `gated: 4/4 (100%)`.
95
101
 
96
102
  **3. Gate.** Get a free API key, load the discovered policy, and run your agent.
97
103
 
@@ -152,7 +158,7 @@ clients, Prisma writes, and JS SDK calls such as `stripe.refunds.create(...)`.
152
158
  (Still not covered: the *Python* SDK equivalents like `stripe.Refund.create(...)`
153
159
  — see "Not covered" above.)
154
160
 
155
- ![writ scan on a TypeScript agent finds 5 write sites, 1 of 5 gated](https://raw.githubusercontent.com/AvenueDAdmin/pywrit/main/docs/assets/scan-tsjs.gif)
161
+ ![writ scan on a TypeScript agent finds 5 write sites, 1 of 5 gated](https://raw.githubusercontent.com/withwrit/pywrit/main/docs/assets/scan-tsjs.gif)
156
162
 
157
163
  ## GitHub Action
158
164
 
@@ -163,7 +169,7 @@ job summary. The check fails when an ungated finding meets your
163
169
 
164
170
  ```yaml
165
171
  - uses: actions/checkout@v4
166
- - uses: AvenueDAdmin/pywrit@v1
172
+ - uses: withwrit/pywrit@v0
167
173
  with:
168
174
  fail-on-risk: high # high | medium | low | never
169
175
  ```
@@ -171,6 +177,39 @@ job summary. The check fails when an ungated finding meets your
171
177
  No API key needed. Full reference: [docs/github-action.md](docs/github-action.md) ·
172
178
  example workflow: [examples/github-action/writ-scan.yml](examples/github-action/writ-scan.yml)
173
179
 
180
+ ## MCP server (`writ-mcp`)
181
+
182
+ Give any MCP-compatible agent point-of-action policy checks. `writ-mcp` is a
183
+ [Model Context Protocol](https://modelcontextprotocol.io) server (stdio transport,
184
+ built on the MCP Python SDK) that exposes the Writ gate as **8 MCP tools**:
185
+ the agent calls `writ_check` before a consequential write and gets back `ALLOW`,
186
+ `DENY`, or `STEP_UP` — with a tamper-evident, hash-chained audit receipt for
187
+ every decision.
188
+
189
+ ```bash
190
+ uvx writ-mcp # no install — runs on demand
191
+ # or
192
+ pip install writ-mcp # then run `writ-mcp`
193
+ ```
194
+
195
+ | Tool | What it does |
196
+ |---|---|
197
+ | `writ_check` | The gate: `ALLOW` / `DENY` / `STEP_UP` for a proposed write |
198
+ | `writ_verify_token` | Validate an `ALLOW` auth token (catches purpose drift) |
199
+ | `writ_grant` | Human-sponsor approval for the `STEP_UP` path |
200
+ | `writ_revoke` / `writ_reinstate` | The kill switch |
201
+ | `writ_receipts` | Read the tenant's audit log |
202
+ | `writ_policy` | Manage the verb policy |
203
+ | `writ_sandbox` | Keyless 90-second demo grant — no API key needed |
204
+
205
+ The gate tools need a free Writ API key (`WRIT_API_KEY`): 10,000 receipts/month
206
+ free, no credit card. `writ_sandbox` works with no key at all.
207
+
208
+ The server implementation lives in [`mcp/`](mcp/) (MIT). Also published on the
209
+ official MCP Registry as `io.github.withwrit/writ`, on
210
+ [Smithery](https://smithery.ai/server/withwrit/writ-mcp), and listed on
211
+ [Glama](https://glama.ai/mcp/servers/withwrit/pywrit).
212
+
174
213
  ## Python client
175
214
 
176
215
  ```python
@@ -223,6 +262,9 @@ What's covered:
223
262
  ## CLI reference
224
263
 
225
264
  ```bash
265
+ writ wrap . # scan, diff, approve, apply, verify coverage
266
+ writ wrap . --dry-run # preview only
267
+ writ wrap . --yes # non-interactive CI mode
226
268
  writ check --key writ_... --sponsor acme --agent agent-7 \
227
269
  --verb db.write --target prod.customers --purpose "backfill region field"
228
270
  writ policy --key writ_... --set payments.refund require_grant
@@ -241,7 +283,7 @@ Show that your agent's writes are gated by Writ. Two flavors:
241
283
  **Static** (works today, no API key) — same design, no live count:
242
284
 
243
285
  ```md
244
- [![agent writes gated by Writ](https://cdn.jsdelivr.net/gh/AvenueDAdmin/pywrit@main/badge/writ-gated.svg)](https://withwrit.com)
286
+ [![agent writes gated by Writ](https://cdn.jsdelivr.net/gh/withwrit/pywrit@main/badge/writ-gated.svg)](https://withwrit.com)
245
287
  ```
246
288
 
247
289
  **Dynamic** (live 30-day gated-write count from your audit log) — mint a badge
@@ -5,7 +5,9 @@ client and `writ` CLI for [Writ](https://withwrit.com): an allow/deny gate that
5
5
  in front of your agent's consequential writes (database, HTTP, files, email, queues,
6
6
  AWS) and records a hash-chained receipt for every decision.
7
7
 
8
- ![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](https://raw.githubusercontent.com/AvenueDAdmin/pywrit/main/docs/assets/scan-python.gif)
8
+ [![Listed on mcpservers.org](https://mcpservers.org/badge.svg)](https://mcpservers.org/servers/avenuedadmin/pywrit)
9
+
10
+ ![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](https://raw.githubusercontent.com/withwrit/pywrit/main/docs/assets/scan-python.gif)
9
11
 
10
12
  `writ scan` is **local, deterministic, and free**: it parses your code with Python's
11
13
  `ast` module, makes no network calls, and needs no API key.
@@ -30,7 +32,7 @@ first run it installs `pywrit[polyglot]` from PyPI using your Python 3.9+
30
32
  environment overrides (`WRIT_PYTHON`, `WRIT_SCAN_NO_INSTALL`), and the
31
33
  install test.
32
34
 
33
- ## 60-second quickstart: scan → apply → gate
35
+ ## 60-second quickstart: scan → wrap → gate
34
36
 
35
37
  **1. Scan.** See which functions write, and how many of them are gated.
36
38
 
@@ -53,14 +55,17 @@ It also prints a **risk report** (0-100, weighted by risk tier), writes the disc
53
55
  verbs to `writ-policy.json`, and shows the instrumentation it would add as a unified
54
56
  diff. Nothing in your code changes yet. `writ scan . --score` prints just the risk report.
55
57
 
56
- **2. Apply.** Insert a gate at the top of each writing function.
58
+ **2. Wrap.** One command takes the repo from unwrapped to wrapped: scan, show the diff,
59
+ ask for explicit approval, apply the gates, and report before/after coverage.
57
60
 
58
61
  ```bash
59
- writ scan . --apply # shows the diff, then asks before writing
60
- writ scan . --apply --yes # no prompt (e.g. in CI)
62
+ writ wrap . # interactive approval
63
+ writ wrap . --yes # no prompt (e.g. in CI)
61
64
  ```
62
65
 
63
- Each gated function now asks Writ before it writes, and fails closed:
66
+ `--dry-run` previews the plan and exits before prompting; `--diff-only` prints the
67
+ unified diff for review tools. Each gated function now asks Writ before it writes, and
68
+ fails closed:
64
69
 
65
70
  ```python
66
71
  def issue_refund(charge_id, amount_cents):
@@ -69,7 +74,8 @@ def issue_refund(charge_id, amount_cents):
69
74
  ...
70
75
  ```
71
76
 
72
- Re-run `writ scan .` and you'll see `gated: 4/4 (100%)`.
77
+ `writ scan . --apply` is still available as the manual alternative. Re-run `writ scan .`
78
+ and you'll see `gated: 4/4 (100%)`.
73
79
 
74
80
  **3. Gate.** Get a free API key, load the discovered policy, and run your agent.
75
81
 
@@ -130,7 +136,7 @@ clients, Prisma writes, and JS SDK calls such as `stripe.refunds.create(...)`.
130
136
  (Still not covered: the *Python* SDK equivalents like `stripe.Refund.create(...)`
131
137
  — see "Not covered" above.)
132
138
 
133
- ![writ scan on a TypeScript agent finds 5 write sites, 1 of 5 gated](https://raw.githubusercontent.com/AvenueDAdmin/pywrit/main/docs/assets/scan-tsjs.gif)
139
+ ![writ scan on a TypeScript agent finds 5 write sites, 1 of 5 gated](https://raw.githubusercontent.com/withwrit/pywrit/main/docs/assets/scan-tsjs.gif)
134
140
 
135
141
  ## GitHub Action
136
142
 
@@ -141,7 +147,7 @@ job summary. The check fails when an ungated finding meets your
141
147
 
142
148
  ```yaml
143
149
  - uses: actions/checkout@v4
144
- - uses: AvenueDAdmin/pywrit@v1
150
+ - uses: withwrit/pywrit@v0
145
151
  with:
146
152
  fail-on-risk: high # high | medium | low | never
147
153
  ```
@@ -149,6 +155,39 @@ job summary. The check fails when an ungated finding meets your
149
155
  No API key needed. Full reference: [docs/github-action.md](docs/github-action.md) ·
150
156
  example workflow: [examples/github-action/writ-scan.yml](examples/github-action/writ-scan.yml)
151
157
 
158
+ ## MCP server (`writ-mcp`)
159
+
160
+ Give any MCP-compatible agent point-of-action policy checks. `writ-mcp` is a
161
+ [Model Context Protocol](https://modelcontextprotocol.io) server (stdio transport,
162
+ built on the MCP Python SDK) that exposes the Writ gate as **8 MCP tools**:
163
+ the agent calls `writ_check` before a consequential write and gets back `ALLOW`,
164
+ `DENY`, or `STEP_UP` — with a tamper-evident, hash-chained audit receipt for
165
+ every decision.
166
+
167
+ ```bash
168
+ uvx writ-mcp # no install — runs on demand
169
+ # or
170
+ pip install writ-mcp # then run `writ-mcp`
171
+ ```
172
+
173
+ | Tool | What it does |
174
+ |---|---|
175
+ | `writ_check` | The gate: `ALLOW` / `DENY` / `STEP_UP` for a proposed write |
176
+ | `writ_verify_token` | Validate an `ALLOW` auth token (catches purpose drift) |
177
+ | `writ_grant` | Human-sponsor approval for the `STEP_UP` path |
178
+ | `writ_revoke` / `writ_reinstate` | The kill switch |
179
+ | `writ_receipts` | Read the tenant's audit log |
180
+ | `writ_policy` | Manage the verb policy |
181
+ | `writ_sandbox` | Keyless 90-second demo grant — no API key needed |
182
+
183
+ The gate tools need a free Writ API key (`WRIT_API_KEY`): 10,000 receipts/month
184
+ free, no credit card. `writ_sandbox` works with no key at all.
185
+
186
+ The server implementation lives in [`mcp/`](mcp/) (MIT). Also published on the
187
+ official MCP Registry as `io.github.withwrit/writ`, on
188
+ [Smithery](https://smithery.ai/server/withwrit/writ-mcp), and listed on
189
+ [Glama](https://glama.ai/mcp/servers/withwrit/pywrit).
190
+
152
191
  ## Python client
153
192
 
154
193
  ```python
@@ -201,6 +240,9 @@ What's covered:
201
240
  ## CLI reference
202
241
 
203
242
  ```bash
243
+ writ wrap . # scan, diff, approve, apply, verify coverage
244
+ writ wrap . --dry-run # preview only
245
+ writ wrap . --yes # non-interactive CI mode
204
246
  writ check --key writ_... --sponsor acme --agent agent-7 \
205
247
  --verb db.write --target prod.customers --purpose "backfill region field"
206
248
  writ policy --key writ_... --set payments.refund require_grant
@@ -219,7 +261,7 @@ Show that your agent's writes are gated by Writ. Two flavors:
219
261
  **Static** (works today, no API key) — same design, no live count:
220
262
 
221
263
  ```md
222
- [![agent writes gated by Writ](https://cdn.jsdelivr.net/gh/AvenueDAdmin/pywrit@main/badge/writ-gated.svg)](https://withwrit.com)
264
+ [![agent writes gated by Writ](https://cdn.jsdelivr.net/gh/withwrit/pywrit@main/badge/writ-gated.svg)](https://withwrit.com)
223
265
  ```
224
266
 
225
267
  **Dynamic** (live 30-day gated-write count from your audit log) — mint a badge
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pywrit"
7
- version = "0.2.6"
7
+ version = "0.2.8"
8
8
  description = "Python client + CLI for Writ — the gate before the write"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -22,7 +22,7 @@ polyglot = [
22
22
  keywords = ["ai-agents", "policy", "audit-log", "guardrails"]
23
23
 
24
24
  [project.urls]
25
- Homepage = "https://github.com/AvenueDAdmin/pywrit"
25
+ Homepage = "https://github.com/withwrit/pywrit"
26
26
  Documentation = "https://withwrit.com/docs"
27
27
 
28
28
  [project.scripts]
@@ -27,7 +27,7 @@ from .errors import (
27
27
  WritError,
28
28
  )
29
29
 
30
- __version__ = "0.2.6"
30
+ __version__ = "0.2.8"
31
31
 
32
32
  __all__ = [
33
33
  "WritClient",