@synapsor/runner 0.1.12 → 0.1.13
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.
- package/AGENTS.md +133 -0
- package/CHANGELOG.md +13 -0
- package/CONTRIBUTING.md +53 -0
- package/README.md +96 -1312
- package/THREAT_MODEL.md +79 -0
- package/dist/runner.mjs +4 -1
- package/docs/README.md +29 -4
- package/docs/getting-started-own-database.md +5 -14
- package/docs/mcp-audit.md +26 -0
- package/docs/oss-vs-cloud.md +50 -0
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -4,614 +4,92 @@
|
|
|
4
4
|
[](LICENSE)
|
|
5
5
|
[](https://github.com/Synapsor/Synapsor-Runner/actions/workflows/ci.yml?query=branch%3Amain)
|
|
6
6
|
|
|
7
|
-
Stop giving AI agents `execute_sql
|
|
7
|
+
Stop giving AI agents `execute_sql`. Give them reviewed business actions.
|
|
8
8
|
|
|
9
|
-
Synapsor Runner is an open-source, local-first MCP
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
Synapsor Runner is an open-source, local-first MCP runtime for Postgres and
|
|
10
|
+
MySQL. It exposes semantic tools such as `billing.inspect_invoice` and
|
|
11
|
+
`billing.propose_late_fee_waiver`, saves risky changes as proposals, and keeps
|
|
12
|
+
database credentials, approval, and writeback outside the model-facing tool
|
|
13
|
+
surface.
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
## Prove It In 60 Seconds
|
|
16
|
+
|
|
17
|
+
First, inspect the risk in a typical raw-SQL database MCP server. This works
|
|
18
|
+
even if you never adopt Runner:
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
# proposal only
|
|
23
|
-
human approves -> guarded writeback applies exactly one change
|
|
20
|
+
```bash
|
|
21
|
+
npx -y @synapsor/runner audit --example dangerous-db-mcp
|
|
24
22
|
```
|
|
25
23
|
|
|
26
|
-
|
|
24
|
+
Then see the proposal, approval boundary, evidence, and replay loop. It needs no
|
|
25
|
+
database, Docker, config file, MCP client, or Synapsor account:
|
|
27
26
|
|
|
28
27
|
```bash
|
|
29
28
|
npx -y @synapsor/runner demo --quick
|
|
30
29
|
```
|
|
31
30
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
## The Five-Line Model
|
|
31
|
+
The quick demo creates a fixture ledger at `./.synapsor/quick-demo.db`. It
|
|
32
|
+
teaches the boundary; it does not claim to test your database connection.
|
|
36
33
|
|
|
37
|
-
|
|
38
|
-
It can look: scoped reads through reviewed tools.
|
|
39
|
-
It can suggest: saved proposals with evidence and exact diffs.
|
|
40
|
-
It cannot commit: approval and writeback happen outside the model-facing tool.
|
|
41
|
-
After writeback, Runner keeps receipts and replay so you can inspect what happened.
|
|
34
|
+
## Safety Model
|
|
42
35
|
|
|
43
36
|
```text
|
|
44
37
|
AI agent or MCP client
|
|
45
|
-
(Claude, Cursor, OpenAI Agents SDK, LangGraph)
|
|
46
38
|
|
|
|
47
|
-
|
|
|
39
|
+
| reviewed semantic tool
|
|
48
40
|
v
|
|
49
41
|
+--------------------------------+
|
|
50
42
|
| Synapsor Runner MCP |
|
|
51
|
-
|
|
|
52
|
-
| trusted tenant/principal ctx |
|
|
43
|
+
| trusted tenant/principal scope |
|
|
53
44
|
| evidence + query audit |
|
|
45
|
+
| proposals, not direct writes |
|
|
54
46
|
+--------------------------------+
|
|
55
47
|
|
|
|
56
|
-
| scoped read / guarded
|
|
48
|
+
| scoped read / approved guarded writeback
|
|
57
49
|
v
|
|
58
50
|
+--------------------------------+
|
|
59
51
|
| Your Postgres or MySQL |
|
|
60
52
|
| source of truth |
|
|
61
53
|
+--------------------------------+
|
|
62
54
|
|
|
63
|
-
Local
|
|
64
|
-
evidence
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
Your database stays the source of truth. Synapsor Runner owns the
|
|
68
|
-
model-facing boundary: what the agent can read, what it can propose, what
|
|
69
|
-
evidence is saved, and what can later be reviewed or replayed.
|
|
70
|
-
|
|
71
|
-
## Start Here
|
|
72
|
-
|
|
73
|
-
Run the guided quick demo first. It does not require Docker, a database, a
|
|
74
|
-
config file, an MCP client, or a Synapsor Cloud account.
|
|
75
|
-
|
|
76
|
-
```bash
|
|
77
|
-
npx -y @synapsor/runner demo --quick
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
In a terminal, it walks through the safety model step by step. In CI, piped
|
|
81
|
-
output, or other non-interactive mode, it prints a short summary and exits
|
|
82
|
-
without waiting for Enter.
|
|
83
|
-
|
|
84
|
-
That command creates a local ledger fixture at `./.synapsor/quick-demo.db`.
|
|
85
|
-
It does not prove database connectivity. It shows the proposal, evidence, and
|
|
86
|
-
replay flow without giving the runner a database URL.
|
|
87
|
-
|
|
88
|
-
```bash
|
|
89
|
-
npx -y @synapsor/runner demo inspect
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
Then choose one path:
|
|
93
|
-
|
|
94
|
-
```text
|
|
95
|
-
Full disposable proof -> npx -y -p @synapsor/runner synapsor-runner demo
|
|
96
|
-
Inspect MCP risk -> npx -y -p @synapsor/runner synapsor-runner audit --example dangerous-db-mcp
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
Flagship example: [`examples/support-plan-credit`](examples/support-plan-credit)
|
|
100
|
-
shows the contract policy path end to end: `$25` auto-approved by policy,
|
|
101
|
-
`$100` held for local review, and `$1000` rejected by the reviewed bound before
|
|
102
|
-
any proposal row exists.
|
|
103
|
-
|
|
104
|
-
## Why Not Just Build This Yourself?
|
|
105
|
-
|
|
106
|
-
You can build the outline in an afternoon:
|
|
107
|
-
|
|
108
|
-
```text
|
|
109
|
-
model calls a function
|
|
110
|
-
-> app stores a pending change
|
|
111
|
-
-> human approves
|
|
112
|
-
-> app runs SQL
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
That is useful, but it is not the safety layer. The repeated hard parts are
|
|
116
|
-
tenant scope, no raw SQL exposure, evidence, query audit, exact diffs,
|
|
117
|
-
approval outside the model-facing tool surface, idempotency, stale-row conflict
|
|
118
|
-
checks, affected-row checks, receipts, and replay.
|
|
119
|
-
|
|
120
|
-
Synapsor Runner gives you those pieces as a local runtime:
|
|
121
|
-
|
|
122
|
-
- reviewed semantic capabilities instead of `execute_sql`;
|
|
123
|
-
- trusted tenant/principal/object bindings from your server-side context;
|
|
124
|
-
- scoped reads with evidence handles and query audit;
|
|
125
|
-
- saved proposals with exact before/after changes;
|
|
126
|
-
- approval and writeback commands that are not exposed to the model;
|
|
127
|
-
- guarded direct writeback for one-row updates;
|
|
128
|
-
- app-owned executors for richer writes;
|
|
129
|
-
- idempotency receipts and replay so you can inspect what happened later.
|
|
130
|
-
|
|
131
|
-
If all you need is restricted reads, a read-only database user and safe views
|
|
132
|
-
are a good start. Use Runner when you need the agent-facing boundary around
|
|
133
|
-
those reads, or when database-backed actions must become proposals before any
|
|
134
|
-
durable write happens.
|
|
135
|
-
|
|
136
|
-
## More Than A Tool Proxy
|
|
137
|
-
|
|
138
|
-
Synapsor is intentionally more than an MCP wrapper. The public packages include
|
|
139
|
-
a versioned contract, DSL compiler, schema validation, conformance fixtures,
|
|
140
|
-
Runner enforcement, proposal/evidence/replay artifacts, Cloud registry push,
|
|
141
|
-
and C++/Cloud round-trip verification.
|
|
142
|
-
|
|
143
|
-
## Connect Your Postgres Or MySQL
|
|
144
|
-
|
|
145
|
-
Use a staging or disposable database first:
|
|
146
|
-
|
|
147
|
-
```bash
|
|
148
|
-
export DATABASE_URL="postgres://readonly:...@localhost:5432/app"
|
|
149
|
-
npx -y -p @synapsor/runner synapsor-runner start --from-env DATABASE_URL
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
The first-run path is:
|
|
153
|
-
|
|
154
|
-
```text
|
|
155
|
-
1. Inspect schema and generate a reviewed config with start/init/onboard.
|
|
156
|
-
2. Run tools preview to confirm no raw SQL or write credentials are exposed.
|
|
157
|
-
3. Run smoke call against one generated inspect tool.
|
|
158
|
-
4. Start review mode with up --serve or mcp serve.
|
|
159
|
-
5. Inspect, propose, approve, apply, and replay from the local ledger.
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
Useful commands after setup:
|
|
163
|
-
|
|
164
|
-
```bash
|
|
165
|
-
synapsor-runner tools preview --config ./synapsor.runner.json --store ./.synapsor/local.db
|
|
166
|
-
synapsor-runner smoke call --config ./synapsor.runner.json --store ./.synapsor/local.db
|
|
167
|
-
synapsor-runner up --serve --config ./synapsor.runner.json --store ./.synapsor/local.db
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
If you already have a canonical `synapsor.contract.json` from the DSL, Cloud,
|
|
171
|
-
or the C++ exporter, keep it as the source of truth and reference it from local
|
|
172
|
-
runner wiring:
|
|
173
|
-
|
|
174
|
-
```json
|
|
175
|
-
{
|
|
176
|
-
"version": 1,
|
|
177
|
-
"mode": "review",
|
|
178
|
-
"contracts": ["./synapsor.contract.json"],
|
|
179
|
-
"sources": {
|
|
180
|
-
"local_postgres": {
|
|
181
|
-
"engine": "postgres",
|
|
182
|
-
"read_url_env": "DATABASE_URL"
|
|
183
|
-
}
|
|
184
|
-
},
|
|
185
|
-
"storage": {
|
|
186
|
-
"sqlite_path": "./.synapsor/local.db"
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
Preview the model-facing tool surface before connecting an MCP client:
|
|
192
|
-
|
|
193
|
-
```bash
|
|
194
|
-
synapsor-runner contract validate ./synapsor.contract.json
|
|
195
|
-
synapsor-runner tools preview --config ./synapsor.runner.json --store ./.synapsor/local.db
|
|
55
|
+
Local SQLite ledger:
|
|
56
|
+
evidence -> proposal -> approval -> receipt -> replay
|
|
196
57
|
```
|
|
197
58
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
59
|
+
The model can inspect scoped data and propose an exact change. It cannot call
|
|
60
|
+
approval or apply tools. A human or trusted operator approves outside MCP, then
|
|
61
|
+
Runner either performs one guarded row update or routes the approved proposal
|
|
62
|
+
to an app-owned executor.
|
|
201
63
|
|
|
202
|
-
|
|
203
|
-
- reads produce evidence handles and query audit;
|
|
204
|
-
- writes become proposals, not direct mutations;
|
|
205
|
-
- approval and writeback happen outside the model-facing MCP surface;
|
|
206
|
-
- replay shows what the agent saw, proposed, and what was applied or blocked.
|
|
207
|
-
|
|
208
|
-
## Four Terms
|
|
209
|
-
|
|
210
|
-
- Capability: a tool you define in config, such as `billing.inspect_invoice`
|
|
211
|
-
or `billing.propose_late_fee_waiver`. The agent only sees capabilities.
|
|
212
|
-
- Proposal: the agent's suggested database-backed change. It is saved, not
|
|
213
|
-
applied.
|
|
214
|
-
- Writeback: the moment an approved proposal actually changes the database.
|
|
215
|
-
- Executor: your app's writeback handler for anything richer than a guarded
|
|
216
|
-
one-row update.
|
|
217
|
-
|
|
218
|
-
You install only `@synapsor/runner`. There is no separate handler package to
|
|
219
|
-
install. A handler is your app's endpoint or script for rich approved writes;
|
|
220
|
-
Runner includes templates and examples to help you build one.
|
|
221
|
-
|
|
222
|
-
## Packages
|
|
223
|
-
|
|
224
|
-
| Package | What it is |
|
|
225
|
-
| --- | --- |
|
|
226
|
-
| `@synapsor/runner` | The local runtime: CLI, MCP server, local store, evidence, proposals, approval, writeback, replay, and audit tools. |
|
|
227
|
-
| `@synapsor/spec` | The canonical portable contract package for contexts, resources, capabilities, workflows, evidence, proposals, receipts, and replay. |
|
|
228
|
-
| `@synapsor/dsl` | A SQL-like authoring layer that compiles `CREATE AGENT CONTEXT`, `CREATE CAPABILITY`, and `CREATE AGENT WORKFLOW` into `@synapsor/spec` JSON. |
|
|
229
|
-
|
|
230
|
-
Use the runner when you want something to execute locally. Use the spec when
|
|
231
|
-
you want a portable contract that Runner, Cloud, and the C++ engine can agree
|
|
232
|
-
on. Use the DSL when you want to author that contract in a reviewable,
|
|
233
|
-
database-style format.
|
|
234
|
-
|
|
235
|
-
## Author Your Contract
|
|
236
|
-
|
|
237
|
-
For new capabilities, prefer the portable contract path:
|
|
238
|
-
|
|
239
|
-
```text
|
|
240
|
-
contract.synapsor -> synapsor.contract.json -> synapsor.runner.json
|
|
241
|
-
```
|
|
64
|
+
## Connect A Staging Database
|
|
242
65
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
```sql
|
|
246
|
-
CREATE AGENT CONTEXT local_operator
|
|
247
|
-
BIND tenant_id FROM ENVIRONMENT SYNAPSOR_TENANT_ID REQUIRED
|
|
248
|
-
BIND principal FROM ENVIRONMENT SYNAPSOR_PRINCIPAL REQUIRED
|
|
249
|
-
TENANT BINDING tenant_id
|
|
250
|
-
PRINCIPAL BINDING principal
|
|
251
|
-
END
|
|
252
|
-
|
|
253
|
-
CREATE CAPABILITY billing.inspect_invoice
|
|
254
|
-
DESCRIPTION 'Inspect one invoice in the trusted tenant before proposing a waiver.'
|
|
255
|
-
RETURNS HINT 'Returns reviewed invoice fields plus evidence/query-audit handles.'
|
|
256
|
-
USING CONTEXT local_operator
|
|
257
|
-
SOURCE local_postgres
|
|
258
|
-
ON public.invoices
|
|
259
|
-
PRIMARY KEY id
|
|
260
|
-
TENANT KEY tenant_id
|
|
261
|
-
CONFLICT GUARD updated_at
|
|
262
|
-
LOOKUP invoice_id BY id
|
|
263
|
-
ARG invoice_id STRING REQUIRED MAX LENGTH 128 DESCRIPTION 'Invoice id such as INV-3001.'
|
|
264
|
-
ALLOW READ id, tenant_id, status, late_fee_cents, updated_at
|
|
265
|
-
REQUIRE EVIDENCE
|
|
266
|
-
MAX ROWS 1
|
|
267
|
-
END
|
|
268
|
-
|
|
269
|
-
CREATE CAPABILITY billing.propose_late_fee_waiver
|
|
270
|
-
DESCRIPTION 'Propose waiving one invoice late fee after inspecting invoice and policy evidence.'
|
|
271
|
-
RETURNS HINT 'Returns a review-required proposal id, exact diff, evidence handle, and source_database_changed:false.'
|
|
272
|
-
USING CONTEXT local_operator
|
|
273
|
-
SOURCE local_postgres
|
|
274
|
-
ON public.invoices
|
|
275
|
-
PRIMARY KEY id
|
|
276
|
-
TENANT KEY tenant_id
|
|
277
|
-
CONFLICT GUARD updated_at
|
|
278
|
-
LOOKUP invoice_id BY id
|
|
279
|
-
ARG invoice_id STRING REQUIRED MAX LENGTH 128 DESCRIPTION 'Invoice id such as INV-3001.'
|
|
280
|
-
ARG reason TEXT REQUIRED MAX LENGTH 500 DESCRIPTION 'Business reason for the proposed waiver.'
|
|
281
|
-
ALLOW READ id, tenant_id, status, late_fee_cents, waiver_reason, updated_at
|
|
282
|
-
REQUIRE EVIDENCE
|
|
283
|
-
MAX ROWS 1
|
|
284
|
-
PROPOSE ACTION waive_late_fee
|
|
285
|
-
ALLOW WRITE late_fee_cents, waiver_reason
|
|
286
|
-
PATCH late_fee_cents = 0
|
|
287
|
-
PATCH waiver_reason = ARG reason
|
|
288
|
-
BOUND late_fee_cents 0..10000
|
|
289
|
-
APPROVAL ROLE billing_lead
|
|
290
|
-
WRITEBACK DIRECT SQL
|
|
291
|
-
END
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
Compile, validate, and serve it:
|
|
295
|
-
|
|
296
|
-
```bash
|
|
297
|
-
synapsor-runner dsl compile ./contract.synapsor --out ./synapsor.contract.json --strict
|
|
298
|
-
synapsor-runner contract validate ./synapsor.contract.json
|
|
299
|
-
synapsor-runner contract bundle ./synapsor.contract.json --out ./synapsor-runner-bundle
|
|
300
|
-
synapsor-runner cloud push ./synapsor.contract.json --dry-run
|
|
301
|
-
synapsor-runner cloud push ./synapsor.contract.json \
|
|
302
|
-
--api-url "$SYNAPSOR_CLOUD_BASE_URL" \
|
|
303
|
-
--token "$SYNAPSOR_CLOUD_TOKEN" \
|
|
304
|
-
--workspace "$SYNAPSOR_PROJECT_ID" \
|
|
305
|
-
--name billing-late-fee
|
|
306
|
-
cd ./synapsor-runner-bundle
|
|
307
|
-
cp .env.example .env # fill in and export your read-only database values
|
|
308
|
-
synapsor-runner mcp serve --config ./synapsor.runner.json --store ./.synapsor/local.db
|
|
309
|
-
```
|
|
310
|
-
|
|
311
|
-
`--strict` treats DSL safety warnings as errors, so CI catches proposal
|
|
312
|
-
capabilities that are missing descriptions, returns hints, or numeric patch
|
|
313
|
-
bounds.
|
|
314
|
-
|
|
315
|
-
The `contract bundle` step generates `synapsor.runner.json` (with env-var
|
|
316
|
-
placeholders) inside the bundle directory, which is why `mcp serve` runs from
|
|
317
|
-
there. The server keeps stdout clean for MCP protocol frames and prints its
|
|
318
|
-
ready line on stderr.
|
|
319
|
-
|
|
320
|
-
See [`docs/dsl-json-parity.md`](docs/dsl-json-parity.md) for the current
|
|
321
|
-
field-by-field support matrix across JSON spec, DSL, runner enforcement,
|
|
322
|
-
C++/Cloud compatibility, and Cloud push.
|
|
323
|
-
|
|
324
|
-
After a real push, open **Contract registry** in Synapsor Cloud to inspect the
|
|
325
|
-
immutable version, semantic capabilities, workflows, visible and kept-out
|
|
326
|
-
fields, policy references, warnings, and registry audit events. Downloading a
|
|
327
|
-
runner bundle returns the same normalized contract with placeholder local
|
|
328
|
-
wiring and ready-to-copy MCP configs.
|
|
329
|
-
|
|
330
|
-
- [Cloud push](docs/cloud-push.md)
|
|
331
|
-
- [Runner bundles](docs/runner-bundles.md)
|
|
332
|
-
- [MCP client configs](docs/mcp-clients.md)
|
|
333
|
-
|
|
334
|
-
Your `synapsor.runner.json` supplies local wiring: database env var names,
|
|
335
|
-
SQLite store path, MCP transport settings, and local debug options. The
|
|
336
|
-
contract supplies the portable meaning: contexts, capabilities, evidence,
|
|
337
|
-
proposal shape, and writeback intent.
|
|
338
|
-
|
|
339
|
-
## Who Does What
|
|
340
|
-
|
|
341
|
-
You write the config: sources, trusted context, capabilities, visible fields,
|
|
342
|
-
proposal fields, and guards. For rich writes, you also write a small handler.
|
|
343
|
-
|
|
344
|
-
Synapsor Runner serves the MCP tools, stores evidence/proposals/receipts,
|
|
345
|
-
enforces tenant, column, version, and idempotency guards, routes writeback, and
|
|
346
|
-
keeps the replay log. You do not rebuild the safety loop yourself.
|
|
347
|
-
|
|
348
|
-
## The Writeback Rule
|
|
349
|
-
|
|
350
|
-
One-row update to an existing row: Runner can do guarded direct writeback.
|
|
351
|
-
Anything else, such as inserting a row, touching two tables, or emitting an
|
|
352
|
-
event: your app-owned executor does it after approval.
|
|
353
|
-
|
|
354
|
-
## How An External Handler Works
|
|
355
|
-
|
|
356
|
-
Some changes are too rich for Runner's one-row writeback: insert a credit row,
|
|
357
|
-
touch two tables, or emit an event. For those, you run a small endpoint. The
|
|
358
|
-
flow is:
|
|
359
|
-
|
|
360
|
-
```text
|
|
361
|
-
agent proposes
|
|
362
|
-
-> human approves outside MCP
|
|
363
|
-
-> Runner POSTs the approved change to your endpoint
|
|
364
|
-
-> your code writes it in its own transaction and returns a receipt
|
|
365
|
-
```
|
|
366
|
-
|
|
367
|
-
The model never touches this code. You are the last line of defense: Runner
|
|
368
|
-
hands you the tenant, expected row version, and idempotency key, and your
|
|
369
|
-
handler must re-check all three. Skipping those checks reintroduces
|
|
370
|
-
cross-tenant writes, lost updates, or duplicate writes. Start from
|
|
371
|
-
`synapsor-runner handler template ...` instead of hand-rolling the safety checks.
|
|
372
|
-
|
|
373
|
-
## Deliberate Limits
|
|
374
|
-
|
|
375
|
-
Runner does not expose raw SQL, write credentials, approval tools, or commit
|
|
376
|
-
tools to the model. Direct Runner writeback does not do generic `INSERT`,
|
|
377
|
-
`DELETE`, `UPSERT`, DDL, or multi-row SQL. Those are app-owned executor jobs.
|
|
378
|
-
|
|
379
|
-
## Command Name
|
|
66
|
+
Start with a staging or disposable database and a read-only credential. Keep
|
|
67
|
+
database permissions, restricted views, and row-level security in place.
|
|
380
68
|
|
|
381
69
|
```bash
|
|
382
70
|
npm install -g @synapsor/runner
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
`synapsor-runner` is the public command for this OSS runner. `synapsor` is
|
|
387
|
-
reserved for the Synapsor Cloud CLI. If you install the package globally, you
|
|
388
|
-
can drop the `npx -y -p @synapsor/runner` prefix.
|
|
389
|
-
|
|
390
|
-
Contributor note: during development, test local changes with
|
|
391
|
-
`./bin/synapsor-runner ...` or a packed tarball. `npx -p @synapsor/runner ...`
|
|
392
|
-
only tests the currently published package, not unpublished local source
|
|
393
|
-
changes.
|
|
394
|
-
|
|
395
|
-
Authoring reference:
|
|
396
|
-
|
|
397
|
-
- [Migrating To `@synapsor/spec`](docs/migrating-to-synapsor-spec.md):
|
|
398
|
-
split portable contract semantics from local runner wiring.
|
|
399
|
-
- [Conformance Fixtures](docs/conformance.md): how the shared fixture suite
|
|
400
|
-
keeps Runner and Cloud/C++ contract semantics from drifting.
|
|
401
|
-
- [Capability Authoring](docs/capability-authoring.md): read/proposal tools,
|
|
402
|
-
model-facing descriptions, result envelope v2, trusted context, and writeback
|
|
403
|
-
guards.
|
|
404
|
-
- [Result Envelope v2](docs/result-envelope-v2.md): stable
|
|
405
|
-
`ok`/`summary`/`data`/`proposal`/`error` MCP tool results.
|
|
406
|
-
- [JSON Schema](schemas/synapsor.runner.schema.json): editor validation for
|
|
407
|
-
`synapsor.runner.json`.
|
|
408
|
-
|
|
409
|
-
## Operational Details
|
|
410
|
-
|
|
411
|
-
These are current alpha requirements, not hidden behavior:
|
|
412
|
-
|
|
413
|
-
- Writeback with `--config ./synapsor.runner.json` reads the trusted writer
|
|
414
|
-
connection from the source `write_url_env`, for example
|
|
415
|
-
`SYNAPSOR_DATABASE_WRITE_URL`. `SYNAPSOR_DATABASE_URL` is only the legacy
|
|
416
|
-
fallback when you run direct worker/apply flows without a local config.
|
|
417
|
-
- `synapsor-runner mcp serve` is standard stdio MCP for local clients that can
|
|
418
|
-
launch Runner.
|
|
419
|
-
- `synapsor-runner mcp serve-streamable-http` is standard MCP Streamable HTTP
|
|
420
|
-
with `initialize` and in-memory session behavior for SDK/client HTTP MCP
|
|
421
|
-
integrations.
|
|
422
|
-
- OpenAI Agents SDK rejects dotted function/tool names. Use
|
|
423
|
-
`--alias-mode openai` or `--openai-tool-aliases` for OpenAI-facing MCP
|
|
424
|
-
transports. Runner exposes aliases such as `billing__inspect_invoice` and
|
|
425
|
-
keeps the canonical Synapsor capability name in tool metadata.
|
|
426
|
-
- `synapsor-runner mcp serve-http` is a small authenticated JSON-RPC bridge for
|
|
427
|
-
`tools/list`, `tools/call`, and `resources/read`. Use it only when you want a
|
|
428
|
-
simple app/server wrapper instead of full HTTP MCP.
|
|
429
|
-
- Direct SQL writeback creates or writes `synapsor_writeback_receipts` for
|
|
430
|
-
idempotency and replay. The trusted writer needs permission for that table,
|
|
431
|
-
or an administrator must pre-create it and grant access. Use an app-owned
|
|
432
|
-
`http_handler` or `command_handler` if Runner should not create receipt
|
|
433
|
-
tables in your application schema.
|
|
434
|
-
- Run `synapsor-runner doctor --config synapsor.runner.json --check-writeback`
|
|
435
|
-
after reviewing receipt-table DDL/grants to verify writer connectivity,
|
|
436
|
-
receipt-table permissions, and rollback-only target-table access. The probe
|
|
437
|
-
never mutates business rows, but it can create the receipt table if the
|
|
438
|
-
writer has permission.
|
|
439
|
-
- For app-owned `http_handler` executors, configure `signing_secret_env` to
|
|
440
|
-
have Runner sign writeback requests with `X-Synapsor-Signature`. Run
|
|
441
|
-
`synapsor-runner doctor --config synapsor.runner.json --check-handlers` to
|
|
442
|
-
check handler env vars and network reachability without applying a proposal.
|
|
443
|
-
|
|
444
|
-
## Run The Full Disposable Demo
|
|
445
|
-
|
|
446
|
-
The full demo requires Docker. It starts a disposable local Postgres-backed app
|
|
447
|
-
and proves the proposal-first write path:
|
|
448
|
-
|
|
449
|
-
```bash
|
|
450
|
-
npx -y -p @synapsor/runner synapsor-runner demo
|
|
451
|
-
```
|
|
452
|
-
|
|
453
|
-
For contributor/release verification from a checkout, the live apply smoke uses
|
|
454
|
-
four disposable Postgres/MySQL scenarios and the official MCP stdio client
|
|
455
|
-
transport:
|
|
456
|
-
|
|
457
|
-
```bash
|
|
458
|
-
corepack pnpm test:live-apply
|
|
459
|
-
```
|
|
460
|
-
|
|
461
|
-
It verifies semantic tool listing, proposal diffs, source rows unchanged before
|
|
462
|
-
approval, guarded writeback, idempotent retry, stale-row conflict, receipts,
|
|
463
|
-
replay, and the support-plan-credit policy tiers. See
|
|
464
|
-
[`docs/local-mode.md`](docs/local-mode.md#local-mcp-smoke) for prerequisites and
|
|
465
|
-
expected output.
|
|
466
|
-
|
|
467
|
-
After the demo prints its generated config and store path, run the happy path it
|
|
468
|
-
prints. The shape is:
|
|
469
|
-
|
|
470
|
-
```bash
|
|
471
|
-
synapsor-runner propose billing.propose_late_fee_waiver --sample
|
|
472
|
-
synapsor-runner proposals show latest
|
|
473
|
-
synapsor-runner proposals approve latest --yes
|
|
474
|
-
synapsor-runner apply latest
|
|
475
|
-
synapsor-runner replay show latest
|
|
476
|
-
synapsor-runner replay show latest --details
|
|
477
|
-
```
|
|
478
|
-
|
|
479
|
-
What you should see:
|
|
480
|
-
|
|
481
|
-
```text
|
|
482
|
-
Agent called:
|
|
483
|
-
billing.propose_late_fee_waiver
|
|
484
|
-
|
|
485
|
-
Proposal created:
|
|
486
|
-
invoice.late_fee_cents
|
|
487
|
-
5500 -> 0
|
|
488
|
-
|
|
489
|
-
Source DB changed:
|
|
490
|
-
no
|
|
491
|
-
|
|
492
|
-
Approval:
|
|
493
|
-
required outside MCP
|
|
494
|
-
|
|
495
|
-
After approval:
|
|
496
|
-
guarded writeback applied
|
|
497
|
-
|
|
498
|
-
Replay:
|
|
499
|
-
saved
|
|
500
|
-
```
|
|
501
|
-
|
|
502
|
-
That is the core point: the model can ask for a database-backed business
|
|
503
|
-
change, but durable state changes only after reviewed approval and guarded
|
|
504
|
-
writeback.
|
|
505
|
-
|
|
506
|
-
## Connect Your Own Staging Database
|
|
507
|
-
|
|
508
|
-
Use this after the quick demo makes sense. Start with staging, a disposable
|
|
509
|
-
database, or a least-privilege view. Do not start with your most sensitive
|
|
510
|
-
production database.
|
|
511
|
-
|
|
512
|
-
Put the read-only connection string in an environment variable:
|
|
513
|
-
|
|
514
|
-
```bash
|
|
515
|
-
export DATABASE_URL="postgresql://readonly_user:password@host:5432/app?sslmode=require"
|
|
516
|
-
```
|
|
517
|
-
|
|
518
|
-
For disposable dev RDS fixtures only, use `sslmode=no-verify` if your local
|
|
519
|
-
Node/Postgres TLS stack cannot verify the test certificate chain. For real
|
|
520
|
-
staging or production-like databases, keep certificate verification enabled.
|
|
521
|
-
|
|
522
|
-
Run the guided own-database path:
|
|
523
|
-
|
|
524
|
-
```bash
|
|
525
|
-
npx -y -p @synapsor/runner synapsor-runner start \
|
|
526
|
-
--from-env DATABASE_URL \
|
|
527
|
-
--schema public
|
|
528
|
-
```
|
|
529
|
-
|
|
530
|
-
`start --from-env` is the low-friction alias for `onboard db --from-env`. That
|
|
531
|
-
path inspects metadata, helps you choose one table/view, creates trusted
|
|
532
|
-
context bindings, generates semantic MCP tools, validates the tool boundary,
|
|
533
|
-
and prints the exact MCP/UI next commands. It does not require hand-authored
|
|
534
|
-
JSON. If you provide an optional real object id during the wizard, it also
|
|
535
|
-
writes `./.synapsor/smoke-input.json` so the first tool call can use an actual
|
|
536
|
-
row instead of guessed sample data. When the read URL env var and trusted
|
|
537
|
-
tenant/principal env vars are already set, onboarding also attempts that smoke
|
|
538
|
-
call immediately and stores the evidence/query audit in the local ledger. If
|
|
539
|
-
those env vars are missing, it prints the exact command to run after you set
|
|
540
|
-
them from `.env.example`.
|
|
541
|
-
|
|
542
|
-
Bring the generated review-mode workspace up with one command:
|
|
543
|
-
|
|
544
|
-
```bash
|
|
545
|
-
npx -y -p @synapsor/runner synapsor-runner up \
|
|
546
|
-
--serve \
|
|
547
|
-
--config ./synapsor.runner.json \
|
|
548
|
-
--store ./.synapsor/local.db
|
|
71
|
+
export DATABASE_URL="postgresql://runner_reader:REPLACE_ME@db.example.com:5432/app?sslmode=require"
|
|
72
|
+
synapsor-runner start --from-env DATABASE_URL --schema public
|
|
549
73
|
```
|
|
550
74
|
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
standard Streamable HTTP MCP server after the checklist; use `--dry-run` to
|
|
556
|
-
rehearse without starting it. For app-owned executor configs, add
|
|
557
|
-
`--with-handler` to run the handler doctor before serving.
|
|
75
|
+
The guided command inspects metadata, asks you to choose one table or view,
|
|
76
|
+
creates trusted context, generates reviewed capabilities, previews the MCP tool
|
|
77
|
+
surface, and prints the next smoke and serve commands. It stores environment
|
|
78
|
+
variable names, not connection strings.
|
|
558
79
|
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
```bash
|
|
562
|
-
npx -y -p @synapsor/runner synapsor-runner onboard db \
|
|
563
|
-
--from-env DATABASE_URL \
|
|
564
|
-
--schema public \
|
|
565
|
-
--table invoices \
|
|
566
|
-
--mode review \
|
|
567
|
-
--tenant-column tenant_id \
|
|
568
|
-
--primary-key id \
|
|
569
|
-
--conflict-column updated_at \
|
|
570
|
-
--namespace billing \
|
|
571
|
-
--object-name invoice \
|
|
572
|
-
--id-arg invoice_id \
|
|
573
|
-
--visible-columns id,tenant_id,late_fee_cents,waiver_reason,updated_at \
|
|
574
|
-
--patch late_fee_cents=fixed:0,waiver_reason=arg:reason \
|
|
575
|
-
--patch-bounds late_fee_cents=0:5500 \
|
|
576
|
-
--write-url-env SYNAPSOR_DATABASE_WRITE_URL \
|
|
577
|
-
--yes
|
|
578
|
-
```
|
|
579
|
-
|
|
580
|
-
If `--namespace` is omitted, Runner derives a namespace from the table name
|
|
581
|
-
instead of creating `source.*` tools. Use `--read-tool` and `--proposal-tool`
|
|
582
|
-
when you need exact model-facing names.
|
|
583
|
-
|
|
584
|
-
For app-owned writeback, replace `--write-url-env ...` with
|
|
585
|
-
`--writeback http_handler --handler-url-env APP_WRITEBACK_URL --emit-handler`.
|
|
586
|
-
Runner marks that source as read-only unless you explicitly pass a writer env,
|
|
587
|
-
so `config validate` does not warn that direct SQL writeback is disabled.
|
|
588
|
-
You can also pass `--answers ./answers.json --yes` for a fully declarative
|
|
589
|
-
setup file.
|
|
590
|
-
|
|
591
|
-
The end-to-end shape is:
|
|
592
|
-
|
|
593
|
-
```text
|
|
594
|
-
1. Put your read-only DB URL in DATABASE_URL.
|
|
595
|
-
2. Run start --from-env DATABASE_URL.
|
|
596
|
-
3. Choose one table/view and the safe fields agents may see.
|
|
597
|
-
4. Preview the generated capabilities.
|
|
598
|
-
5. Serve them over MCP to Claude, Cursor, OpenAI Agents SDK, or your app.
|
|
599
|
-
6. For writes, approve a proposal outside MCP before writeback.
|
|
600
|
-
```
|
|
601
|
-
|
|
602
|
-
The generated config is just the safety contract. A small reviewed version
|
|
603
|
-
looks like this:
|
|
80
|
+
A minimal generated read-only configuration looks like this:
|
|
604
81
|
|
|
605
82
|
```json
|
|
606
83
|
{
|
|
607
84
|
"version": 1,
|
|
608
|
-
"mode": "
|
|
85
|
+
"mode": "read_only",
|
|
609
86
|
"result_format": 2,
|
|
87
|
+
"storage": { "sqlite_path": "./.synapsor/local.db" },
|
|
610
88
|
"sources": {
|
|
611
89
|
"app_postgres": {
|
|
612
90
|
"engine": "postgres",
|
|
613
91
|
"read_url_env": "DATABASE_URL",
|
|
614
|
-
"
|
|
92
|
+
"statement_timeout_ms": 3000
|
|
615
93
|
}
|
|
616
94
|
},
|
|
617
95
|
"trusted_context": {
|
|
@@ -633,783 +111,89 @@ looks like this:
|
|
|
633
111
|
"tenant_key": "tenant_id"
|
|
634
112
|
},
|
|
635
113
|
"args": {
|
|
636
|
-
"invoice_id": { "type": "string", "required": true }
|
|
114
|
+
"invoice_id": { "type": "string", "required": true, "max_length": 128 }
|
|
637
115
|
},
|
|
638
116
|
"lookup": { "id_from_arg": "invoice_id" },
|
|
639
|
-
"visible_columns": ["id", "status", "late_fee_cents", "updated_at"],
|
|
117
|
+
"visible_columns": ["id", "tenant_id", "status", "late_fee_cents", "updated_at"],
|
|
640
118
|
"evidence": "required",
|
|
641
119
|
"max_rows": 1
|
|
642
|
-
},
|
|
643
|
-
{
|
|
644
|
-
"name": "billing.propose_late_fee_waiver",
|
|
645
|
-
"kind": "proposal",
|
|
646
|
-
"source": "app_postgres",
|
|
647
|
-
"target": {
|
|
648
|
-
"schema": "public",
|
|
649
|
-
"table": "invoices",
|
|
650
|
-
"primary_key": "id",
|
|
651
|
-
"tenant_key": "tenant_id"
|
|
652
|
-
},
|
|
653
|
-
"args": {
|
|
654
|
-
"invoice_id": { "type": "string", "required": true },
|
|
655
|
-
"reason": { "type": "string", "required": true }
|
|
656
|
-
},
|
|
657
|
-
"lookup": { "id_from_arg": "invoice_id" },
|
|
658
|
-
"visible_columns": ["id", "status", "late_fee_cents", "updated_at"],
|
|
659
|
-
"patch": {
|
|
660
|
-
"late_fee_cents": { "fixed": 0 },
|
|
661
|
-
"waiver_reason": { "from_arg": "reason" }
|
|
662
|
-
},
|
|
663
|
-
"allowed_columns": ["late_fee_cents", "waiver_reason"],
|
|
664
|
-
"conflict_guard": { "column": "updated_at" },
|
|
665
|
-
"approval": { "mode": "human", "required_role": "billing_lead" }
|
|
666
120
|
}
|
|
667
121
|
]
|
|
668
122
|
}
|
|
669
123
|
```
|
|
670
124
|
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
credential, raw SQL, approval command, or commit command.
|
|
674
|
-
|
|
675
|
-
Prefer the step-by-step commands if you want to inspect each stage manually:
|
|
676
|
-
|
|
677
|
-
```bash
|
|
678
|
-
npx -y -p @synapsor/runner synapsor-runner inspect \
|
|
679
|
-
--engine auto \
|
|
680
|
-
--from-env DATABASE_URL \
|
|
681
|
-
--schema public
|
|
682
|
-
|
|
683
|
-
npx -y -p @synapsor/runner synapsor-runner init --wizard --from-env DATABASE_URL --mode read_only
|
|
684
|
-
```
|
|
685
|
-
|
|
686
|
-
The wizard creates this local flow:
|
|
687
|
-
|
|
688
|
-
```text
|
|
689
|
-
trusted context -> capability -> MCP tool
|
|
690
|
-
```
|
|
691
|
-
|
|
692
|
-
It asks which table/view backs the context, which tenant/scope column and
|
|
693
|
-
backend session env vars are trusted, which fields are visible, and what
|
|
694
|
-
semantic capability name to expose. Before writing files, it shows a final
|
|
695
|
-
preview and lets you revise visible fields or capability names. It writes
|
|
696
|
-
`synapsor.runner.json`, `.env.example`, and MCP client snippets. It does not put
|
|
697
|
-
your database URL in the MCP client config.
|
|
698
|
-
|
|
699
|
-
Preview the tools:
|
|
700
|
-
|
|
701
|
-
```bash
|
|
702
|
-
npx -y -p @synapsor/runner synapsor-runner tools preview \
|
|
703
|
-
--config ./synapsor.runner.json \
|
|
704
|
-
--store ./.synapsor/local.db
|
|
705
|
-
```
|
|
706
|
-
|
|
707
|
-
Call one generated tool locally before wiring an MCP client:
|
|
708
|
-
|
|
709
|
-
```bash
|
|
710
|
-
npx -y -p @synapsor/runner synapsor-runner smoke call \
|
|
711
|
-
<generated.inspect_tool_name> \
|
|
712
|
-
--input ./.synapsor/smoke-input.json \
|
|
713
|
-
--config ./synapsor.runner.json \
|
|
714
|
-
--store ./.synapsor/local.db
|
|
715
|
-
```
|
|
716
|
-
|
|
717
|
-
`smoke call` uses the same runtime as MCP, records evidence/query audit or a
|
|
718
|
-
proposal in the local store, and then prints the evidence/proposal/replay
|
|
719
|
-
commands to inspect what happened. If you skipped the optional smoke input in
|
|
720
|
-
the wizard, pass one real row id instead:
|
|
721
|
-
|
|
722
|
-
```bash
|
|
723
|
-
npx -y -p @synapsor/runner synapsor-runner smoke call \
|
|
724
|
-
<generated.inspect_tool_name> \
|
|
725
|
-
--json '{"<lookup_arg>":"<real_id>"}' \
|
|
726
|
-
--config ./synapsor.runner.json \
|
|
727
|
-
--store ./.synapsor/local.db
|
|
728
|
-
```
|
|
729
|
-
|
|
730
|
-
Serve the semantic MCP tools locally:
|
|
731
|
-
|
|
732
|
-
```bash
|
|
733
|
-
npx -y -p @synapsor/runner synapsor-runner mcp serve \
|
|
734
|
-
--config ./synapsor.runner.json \
|
|
735
|
-
--store ./.synapsor/local.db
|
|
736
|
-
```
|
|
737
|
-
|
|
738
|
-
## Three Ways To Run MCP
|
|
739
|
-
|
|
740
|
-
Use stdio when the MCP client runs locally and can launch Synapsor Runner. Use
|
|
741
|
-
Streamable HTTP when a standard HTTP MCP client connects to a long-running
|
|
742
|
-
Runner process. Use the JSON-RPC bridge only when you want simple POST calls
|
|
743
|
-
from your own app/server wrapper.
|
|
744
|
-
|
|
745
|
-
Local MCP clients:
|
|
746
|
-
|
|
747
|
-
```bash
|
|
748
|
-
synapsor-runner mcp serve \
|
|
749
|
-
--config ./synapsor.runner.json \
|
|
750
|
-
--store ./.synapsor/local.db
|
|
751
|
-
```
|
|
752
|
-
|
|
753
|
-
For OpenAI Agents SDK over stdio, add OpenAI-safe aliases:
|
|
754
|
-
|
|
755
|
-
```bash
|
|
756
|
-
synapsor-runner mcp serve \
|
|
757
|
-
--config ./synapsor.runner.json \
|
|
758
|
-
--store ./.synapsor/local.db \
|
|
759
|
-
--alias-mode openai
|
|
760
|
-
```
|
|
761
|
-
|
|
762
|
-
App/server deployments:
|
|
763
|
-
|
|
764
|
-
```bash
|
|
765
|
-
export SYNAPSOR_RUNNER_HTTP_TOKEN="dev-local-token"
|
|
766
|
-
|
|
767
|
-
synapsor-runner mcp serve-streamable-http \
|
|
768
|
-
--config ./synapsor.runner.json \
|
|
769
|
-
--store ./.synapsor/local.db \
|
|
770
|
-
--auth-token-env SYNAPSOR_RUNNER_HTTP_TOKEN \
|
|
771
|
-
--alias-mode openai
|
|
772
|
-
```
|
|
773
|
-
|
|
774
|
-
You can also start the same review-mode server through the safer startup
|
|
775
|
-
checklist:
|
|
776
|
-
|
|
777
|
-
```bash
|
|
778
|
-
synapsor-runner up --serve \
|
|
779
|
-
--config ./synapsor.runner.json \
|
|
780
|
-
--store ./.synapsor/local.db \
|
|
781
|
-
--auth-token-env SYNAPSOR_RUNNER_HTTP_TOKEN \
|
|
782
|
-
--alias-mode openai
|
|
783
|
-
```
|
|
784
|
-
|
|
785
|
-
The same Streamable HTTP server can also be started through the unified serve
|
|
786
|
-
command:
|
|
787
|
-
|
|
788
|
-
```bash
|
|
789
|
-
synapsor-runner mcp serve \
|
|
790
|
-
--transport streamable-http \
|
|
791
|
-
--config ./synapsor.runner.json \
|
|
792
|
-
--store ./.synapsor/local.db \
|
|
793
|
-
--auth-token-env SYNAPSOR_RUNNER_HTTP_TOKEN \
|
|
794
|
-
--alias-mode openai
|
|
795
|
-
```
|
|
796
|
-
|
|
797
|
-
Streamable HTTP defaults to `127.0.0.1:8766`, requires bearer auth by default,
|
|
798
|
-
and should use private networking, TLS, and rate limits before being exposed
|
|
799
|
-
beyond a local machine. With `--alias-mode openai`, tools are exposed to
|
|
800
|
-
the model as OpenAI-safe aliases such as `billing__inspect_invoice`; `_meta`
|
|
801
|
-
still includes `synapsor.canonical_tool_name = billing.inspect_invoice`, and
|
|
802
|
-
Runner routes calls back to the canonical Synapsor capability. Use
|
|
803
|
-
`--alias-mode both` during migrations if one client still expects canonical
|
|
804
|
-
dotted names while another needs OpenAI-safe aliases.
|
|
805
|
-
|
|
806
|
-
Bridge mode:
|
|
807
|
-
|
|
808
|
-
```bash
|
|
809
|
-
synapsor-runner mcp serve-http \
|
|
810
|
-
--config ./synapsor.runner.json \
|
|
811
|
-
--store ./.synapsor/local.db \
|
|
812
|
-
--auth-token-env SYNAPSOR_RUNNER_HTTP_TOKEN
|
|
813
|
-
```
|
|
814
|
-
|
|
815
|
-
Bridge HTTP defaults to `127.0.0.1:8765` and supports only JSON-RPC
|
|
816
|
-
`tools/list`, `tools/call`, and `resources/read`. It does not implement MCP
|
|
817
|
-
Streamable HTTP `initialize`/session behavior.
|
|
818
|
-
|
|
819
|
-
OpenAI Agents SDK examples:
|
|
820
|
-
|
|
821
|
-
```text
|
|
822
|
-
examples/openai-agents-stdio/
|
|
823
|
-
examples/openai-agents-http/
|
|
824
|
-
```
|
|
825
|
-
|
|
826
|
-
Detailed setup: [docs/openai-agents-sdk.md](docs/openai-agents-sdk.md).
|
|
827
|
-
|
|
828
|
-
Use `--mode review` only when you are ready to create proposal tools and test
|
|
829
|
-
guarded writeback. Review mode needs an approved write path and a separate
|
|
830
|
-
trusted write credential; the model-facing read URL should stay least
|
|
831
|
-
privilege.
|
|
832
|
-
|
|
833
|
-
## Audit Your MCP Database Tools
|
|
834
|
-
|
|
835
|
-
`synapsor-runner audit` is a static MCP/database risk review. It is useful even before
|
|
836
|
-
you adopt the full runner.
|
|
837
|
-
|
|
838
|
-
```bash
|
|
839
|
-
synapsor-runner audit --example dangerous-db-mcp
|
|
840
|
-
synapsor-runner audit --example dangerous-db-mcp --format markdown
|
|
841
|
-
synapsor-runner audit ./synapsor.runner.json
|
|
842
|
-
synapsor-runner audit --mcp-config ./claude_desktop_config.json
|
|
843
|
-
synapsor-runner audit --stdio "node ./my-db-mcp-server.js"
|
|
844
|
-
```
|
|
845
|
-
|
|
846
|
-
The built-in example runs without cloning this repository or downloading an
|
|
847
|
-
examples file. File-based audits still work when you have your own exported MCP
|
|
848
|
-
tool manifest.
|
|
849
|
-
|
|
850
|
-
It looks for patterns such as:
|
|
851
|
-
|
|
852
|
-
- arbitrary SQL tools;
|
|
853
|
-
- broad database write tools;
|
|
854
|
-
- model-facing approval/commit tools;
|
|
855
|
-
- missing tenant/principal context;
|
|
856
|
-
- dangerous tool names;
|
|
857
|
-
- unclear parameter schemas;
|
|
858
|
-
- mutation tools without proposal/approval.
|
|
859
|
-
|
|
860
|
-
Example finding:
|
|
861
|
-
|
|
862
|
-
```text
|
|
863
|
-
Risk: high
|
|
864
|
-
|
|
865
|
-
Found:
|
|
866
|
-
- execute_sql appears to expose arbitrary database access.
|
|
867
|
-
- approve_refund appears to let the model approve a durable write.
|
|
868
|
-
- update_customer appears to mutate state without a proposal boundary.
|
|
869
|
-
- No trusted tenant/principal context was detected.
|
|
870
|
-
|
|
871
|
-
Suggested safer shape:
|
|
872
|
-
- billing.inspect_invoice
|
|
873
|
-
- billing.propose_late_fee_waiver
|
|
874
|
-
- approval outside MCP
|
|
875
|
-
- guarded writeback after approval
|
|
876
|
-
|
|
877
|
-
Note:
|
|
878
|
-
This is a static risk review, not a security guarantee.
|
|
879
|
-
```
|
|
880
|
-
|
|
881
|
-
## Why Not Just Use A Read-Only Database User?
|
|
882
|
-
|
|
883
|
-
You should use one.
|
|
884
|
-
|
|
885
|
-
Synapsor Runner is not a replacement for least-privilege database permissions.
|
|
886
|
-
Start with a read-only user, restricted views, row-level security, and staging
|
|
887
|
-
data where appropriate.
|
|
888
|
-
|
|
889
|
-
The difference is that database permissions protect the connection. Synapsor
|
|
890
|
-
Runner shapes the model-facing interface.
|
|
891
|
-
|
|
892
|
-
Instead of exposing `execute_sql`, `query_database`, table names, or
|
|
893
|
-
model-controlled tenant filters, Synapsor exposes reviewed business
|
|
894
|
-
capabilities such as `billing.inspect_invoice` and
|
|
895
|
-
`billing.propose_late_fee_waiver`.
|
|
896
|
-
|
|
897
|
-
For read-only use cases, Runner provides scoped semantic tools, trusted context
|
|
898
|
-
binding, evidence handles, query audit, and local inspection. Proposal
|
|
899
|
-
workflows add full replay across evidence, approval, writeback receipts, and
|
|
900
|
-
events.
|
|
901
|
-
|
|
902
|
-
If all you need is restricted reads, database permissions are a good start.
|
|
903
|
-
Use Synapsor Runner when you also want the agent-facing layer: semantic tools,
|
|
904
|
-
trusted context, evidence handles, query audit, local inspection, and
|
|
905
|
-
proposal-first writes.
|
|
906
|
-
|
|
907
|
-
## Find Evidence And Replay
|
|
908
|
-
|
|
909
|
-
The commands in this section require this checkout or an alpha package that
|
|
910
|
-
includes the local-ledger CLI surface.
|
|
911
|
-
|
|
912
|
-
Synapsor Runner writes a local evidence/replay ledger to SQLite. Use it to
|
|
913
|
-
answer questions such as:
|
|
914
|
-
|
|
915
|
-
```text
|
|
916
|
-
What did the agent see and do for invoice INV-3001?
|
|
917
|
-
```
|
|
918
|
-
|
|
919
|
-
Search the local activity ledger:
|
|
920
|
-
|
|
921
|
-
```bash
|
|
922
|
-
synapsor-runner activity search --tenant acme --object invoice:INV-3001
|
|
923
|
-
synapsor-runner activity search --capability billing.propose_late_fee_waiver --from 2026-06-01 --to 2026-06-23
|
|
924
|
-
synapsor-runner events tail --store ./.synapsor/local.db
|
|
925
|
-
synapsor-runner events webhook --url http://127.0.0.1:8788/synapsor/events --kind proposal_created --store ./.synapsor/local.db
|
|
926
|
-
```
|
|
927
|
-
|
|
928
|
-
Inspect the linked records:
|
|
929
|
-
|
|
930
|
-
```bash
|
|
931
|
-
synapsor-runner proposals list --tenant acme --object invoice:INV-3001 --status approved
|
|
932
|
-
synapsor-runner evidence show ev_...
|
|
933
|
-
synapsor-runner query-audit list --evidence ev_...
|
|
934
|
-
synapsor-runner receipts list --proposal wrp_...
|
|
935
|
-
synapsor-runner receipts show <receipt_id>
|
|
936
|
-
synapsor-runner replay show --proposal wrp_...
|
|
937
|
-
synapsor-runner replay show --replay replay_wrp_...
|
|
938
|
-
```
|
|
939
|
-
|
|
940
|
-
The default views answer what happened, whether the source DB changed, the
|
|
941
|
-
current status, and the next command to run. Add `--details` when you need
|
|
942
|
-
target URIs, primary keys, proposal hash/version, conflict guards, query
|
|
943
|
-
fingerprints, event timestamps, or receipt internals.
|
|
944
|
-
|
|
945
|
-
Export replay or evidence for review:
|
|
946
|
-
|
|
947
|
-
```bash
|
|
948
|
-
synapsor-runner replay export --proposal wrp_... --format json --output replay.json
|
|
949
|
-
synapsor-runner replay export --proposal wrp_... --format markdown --output replay.md
|
|
950
|
-
synapsor-runner evidence export ev_... --format markdown --output evidence.md
|
|
951
|
-
```
|
|
952
|
-
|
|
953
|
-
Create a redacted local diagnostic report:
|
|
954
|
-
|
|
955
|
-
```bash
|
|
956
|
-
synapsor-runner doctor --config synapsor.runner.json --report --redact --output synapsor-doctor.md
|
|
957
|
-
synapsor-runner doctor --config synapsor.runner.json --check-writeback
|
|
958
|
-
```
|
|
959
|
-
|
|
960
|
-
Inspect or compact the local ledger:
|
|
961
|
-
|
|
962
|
-
```bash
|
|
963
|
-
synapsor-runner store stats --store ./.synapsor/local.db
|
|
964
|
-
synapsor-runner events tail --store ./.synapsor/local.db --follow
|
|
965
|
-
synapsor-runner events webhook --url-env SYNAPSOR_EVENT_WEBHOOK_URL --auth-token-env SYNAPSOR_EVENT_WEBHOOK_TOKEN --follow --store ./.synapsor/local.db
|
|
966
|
-
synapsor-runner store vacuum --store ./.synapsor/local.db
|
|
967
|
-
synapsor-runner store prune --store ./.synapsor/local.db --older-than 30d --dry-run
|
|
968
|
-
synapsor-runner store reset --store ./.synapsor/local.db --yes
|
|
969
|
-
```
|
|
970
|
-
|
|
971
|
-
`events webhook` is a local/dev/staging convenience for review UIs, Slack
|
|
972
|
-
bridges, or app-local notifications. It POSTs one redacted local event envelope
|
|
973
|
-
per lifecycle event; it is not a hosted central ledger.
|
|
974
|
-
|
|
975
|
-
This is local indexed search for local/dev/staging usage. It is not a hosted
|
|
976
|
-
central ledger, not RBAC/SSO, not cross-runner search, and not compliance
|
|
977
|
-
retention. Synapsor Cloud adds a shared contract registry and enabled hosted
|
|
978
|
-
activity/evidence surfaces; confirm retention and production operations for
|
|
979
|
-
the specific design-partner deployment.
|
|
980
|
-
|
|
981
|
-
## Connect Claude, Cursor, Or Another MCP Client
|
|
982
|
-
|
|
983
|
-
Generate a local MCP client snippet:
|
|
984
|
-
|
|
985
|
-
```bash
|
|
986
|
-
synapsor-runner mcp config --config ./synapsor.runner.json --store ./.synapsor/local.db
|
|
987
|
-
```
|
|
988
|
-
|
|
989
|
-
Use a specific client shape when needed:
|
|
990
|
-
|
|
991
|
-
```bash
|
|
992
|
-
synapsor-runner mcp config cursor --config ./synapsor.runner.json --store ./.synapsor/local.db
|
|
993
|
-
synapsor-runner mcp config vscode --config ./synapsor.runner.json --store ./.synapsor/local.db
|
|
994
|
-
synapsor-runner mcp config generic --config ./synapsor.runner.json --store ./.synapsor/local.db
|
|
995
|
-
synapsor-runner mcp client-config --client openai-agents --config ./synapsor.runner.json --store ./.synapsor/local.db
|
|
996
|
-
```
|
|
997
|
-
|
|
998
|
-
The generated config references the local runner command. It does not include:
|
|
999
|
-
|
|
1000
|
-
- database URL;
|
|
1001
|
-
- database password;
|
|
1002
|
-
- write credentials;
|
|
1003
|
-
- approval tools;
|
|
1004
|
-
- commit/apply tools.
|
|
1005
|
-
|
|
1006
|
-
## Sanity Check The Agent Connection
|
|
1007
|
-
|
|
1008
|
-
After you connect Claude, Cursor, OpenAI Agents SDK, or another MCP client, run
|
|
1009
|
-
one tiny tool-call test before asking the agent to solve a real task.
|
|
1010
|
-
|
|
1011
|
-
First preview the tools Runner will expose:
|
|
125
|
+
Set the trusted values in the process that launches Runner, then validate and
|
|
126
|
+
preview the exact model-facing boundary before connecting an MCP client:
|
|
1012
127
|
|
|
1013
128
|
```bash
|
|
129
|
+
export SYNAPSOR_TENANT_ID="acme"
|
|
130
|
+
export SYNAPSOR_PRINCIPAL="local-developer"
|
|
131
|
+
synapsor-runner config validate --config ./synapsor.runner.json
|
|
1014
132
|
synapsor-runner tools preview --config ./synapsor.runner.json --store ./.synapsor/local.db
|
|
133
|
+
synapsor-runner mcp serve --config ./synapsor.runner.json --store ./.synapsor/local.db
|
|
1015
134
|
```
|
|
1016
135
|
|
|
1017
|
-
For
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
--store ./.synapsor/local.db \
|
|
1023
|
-
--alias-mode openai
|
|
1024
|
-
```
|
|
1025
|
-
|
|
1026
|
-
Example:
|
|
1027
|
-
|
|
1028
|
-
```text
|
|
1029
|
-
Exposed to MCP:
|
|
1030
|
-
- billing__inspect_invoice -> billing.inspect_invoice
|
|
1031
|
-
```
|
|
1032
|
-
|
|
1033
|
-
Then ask the agent:
|
|
1034
|
-
|
|
1035
|
-
```text
|
|
1036
|
-
Use the Synapsor Runner MCP tool to inspect invoice INV-3001.
|
|
1037
|
-
Do not answer from memory.
|
|
1038
|
-
Return the tool name called, the evidence handle, and whether raw SQL was available.
|
|
1039
|
-
```
|
|
1040
|
-
|
|
1041
|
-
For your own database, replace `invoice INV-3001` with one real object ID and
|
|
1042
|
-
the semantic tool name from `tools preview`.
|
|
1043
|
-
|
|
1044
|
-
Expected result:
|
|
1045
|
-
|
|
1046
|
-
- the agent calls a Synapsor Runner tool such as `billing.inspect_invoice`;
|
|
1047
|
-
- the response includes an evidence handle or local ledger reference;
|
|
1048
|
-
- the agent says raw SQL/write/approval tools were not available.
|
|
1049
|
-
|
|
1050
|
-
If the agent gives generic advice, a freeform summary, or unrelated planning
|
|
1051
|
-
text without a tool call or evidence handle, Runner is not in the loop yet. Fix
|
|
1052
|
-
the MCP client config, restart the client, confirm trusted context environment
|
|
1053
|
-
variables are set, and rerun `synapsor-runner tools preview`.
|
|
1054
|
-
|
|
1055
|
-
## What The Model Gets
|
|
1056
|
-
|
|
1057
|
-
The model gets reviewed semantic capabilities from `synapsor.runner.json`, for
|
|
1058
|
-
example:
|
|
1059
|
-
|
|
1060
|
-
```text
|
|
1061
|
-
billing.inspect_invoice
|
|
1062
|
-
billing.propose_late_fee_waiver
|
|
1063
|
-
support.inspect_ticket
|
|
1064
|
-
support.propose_plan_credit
|
|
1065
|
-
orders.inspect_order
|
|
1066
|
-
orders.propose_status_change
|
|
1067
|
-
```
|
|
1068
|
-
|
|
1069
|
-
These are business tools with trusted scope, visible fields, evidence rules,
|
|
1070
|
-
proposal boundaries, and writeback guards.
|
|
1071
|
-
|
|
1072
|
-
## Fixture Benchmark
|
|
1073
|
-
|
|
1074
|
-
Run the included MCP efficiency fixture:
|
|
1075
|
-
|
|
1076
|
-
```bash
|
|
1077
|
-
synapsor-runner benchmark mcp-efficiency
|
|
1078
|
-
```
|
|
1079
|
-
|
|
1080
|
-
Current fixture result for the late-fee-waiver workflow:
|
|
1081
|
-
|
|
1082
|
-
```text
|
|
1083
|
-
Generic database MCP reference:
|
|
1084
|
-
exposed tools: 4
|
|
1085
|
-
scripted tool calls: 5
|
|
1086
|
-
raw SQL exposed: yes
|
|
1087
|
-
approval separated: no
|
|
1088
|
-
stale-row conflict checked: no
|
|
1089
|
-
|
|
1090
|
-
Synapsor Runner semantic path:
|
|
1091
|
-
exposed tools: 2
|
|
1092
|
-
scripted tool calls: 2
|
|
1093
|
-
raw SQL exposed: no
|
|
1094
|
-
approval separated: yes
|
|
1095
|
-
stale-row conflict checked: yes
|
|
1096
|
-
```
|
|
1097
|
-
|
|
1098
|
-
The fixture tokenizer is deterministic and repeatable for this repo. It is not
|
|
1099
|
-
a model billing tokenizer and not a universal token-savings claim.
|
|
1100
|
-
|
|
1101
|
-
## Safe Write Examples
|
|
1102
|
-
|
|
1103
|
-
The disposable reference app includes three proposal-first write shapes:
|
|
1104
|
-
|
|
1105
|
-
- `billing.propose_late_fee_waiver`: waive a late fee after evidence and review.
|
|
1106
|
-
- `support.propose_plan_credit`: propose a bounded customer credit for a support case.
|
|
1107
|
-
- `orders.propose_status_change`: move an order through an allowlisted status transition.
|
|
1108
|
-
|
|
1109
|
-
Each tool creates evidence, a before/after diff, and a local proposal. The
|
|
1110
|
-
source database is unchanged until approval outside MCP and guarded writeback.
|
|
1111
|
-
|
|
1112
|
-
## What The Model Never Gets
|
|
1113
|
-
|
|
1114
|
-
Synapsor Runner does not expose:
|
|
1115
|
-
|
|
1116
|
-
```text
|
|
1117
|
-
execute_sql
|
|
1118
|
-
raw_sql
|
|
1119
|
-
query_database
|
|
1120
|
-
database URLs
|
|
1121
|
-
write credentials
|
|
1122
|
-
approval tools
|
|
1123
|
-
commit/apply tools
|
|
1124
|
-
arbitrary table names
|
|
1125
|
-
arbitrary column names
|
|
1126
|
-
model-controlled tenant authority
|
|
1127
|
-
direct write access
|
|
1128
|
-
```
|
|
1129
|
-
|
|
1130
|
-
Approval and writeback stay outside the model-facing MCP tool surface.
|
|
1131
|
-
|
|
1132
|
-
## App-Owned Writeback
|
|
1133
|
-
|
|
1134
|
-
Direct guarded DB writeback is useful for local/staging demos and simple
|
|
1135
|
-
single-row updates. If your application service already owns business writes,
|
|
1136
|
-
configure an `http_handler` or `command_handler` executor instead.
|
|
1137
|
-
|
|
1138
|
-
The flow stays the same: model-facing MCP creates a proposal, approval happens
|
|
1139
|
-
outside MCP, Synapsor Runner sends an approved job to your app handler, and the
|
|
1140
|
-
handler returns an applied/conflict/failed receipt for replay.
|
|
1141
|
-
|
|
1142
|
-
> **Important:** your app handler owns the final business write. Runner creates
|
|
1143
|
-
> the proposal and calls your handler only after approval, but your handler must
|
|
1144
|
-
> still enforce tenant/scope checks, expected-version or conflict guards,
|
|
1145
|
-
> idempotency keys, allowed business actions, transaction/rollback, and safe
|
|
1146
|
-
> error receipts. If you skip those checks, you can reintroduce cross-tenant
|
|
1147
|
-
> writes, lost updates, or duplicate writes. Keep handler credentials out of MCP.
|
|
1148
|
-
|
|
1149
|
-
Details: [docs/writeback-executors.md](docs/writeback-executors.md). Starter
|
|
1150
|
-
handlers live in [examples/app-owned-writeback](examples/app-owned-writeback).
|
|
1151
|
-
The runner npm package includes handler templates and the
|
|
1152
|
-
`examples/mcp-postgres-billing-app-handler/synapsor-handler.mjs` bundled helper
|
|
1153
|
-
shim. These show bearer/HMAC auth, tenant scope, expected-version guards,
|
|
1154
|
-
idempotency, transaction rollback, and safe receipts around your business
|
|
1155
|
-
effect. There is no separate handler package to install.
|
|
1156
|
-
The full Postgres billing example in
|
|
1157
|
-
[examples/mcp-postgres-billing-app-handler](examples/mcp-postgres-billing-app-handler)
|
|
1158
|
-
shows `billing.propose_account_credit` creating a proposal first, then inserting
|
|
1159
|
-
an `account_credits` row through an app-owned HTTP handler after approval.
|
|
1160
|
-
You can also generate a starter handler directly:
|
|
1161
|
-
|
|
1162
|
-
```bash
|
|
1163
|
-
npx -y -p @synapsor/runner synapsor-runner handler template node-fastify \
|
|
1164
|
-
--output ./synapsor-writeback-handler.mjs
|
|
1165
|
-
```
|
|
1166
|
-
|
|
1167
|
-
For direct SQL writeback, set the writer env var named by the source
|
|
1168
|
-
`write_url_env`, for example `SYNAPSOR_DATABASE_WRITE_URL`. Runner also creates
|
|
1169
|
-
or writes `synapsor_writeback_receipts` for idempotency/replay, so the writer
|
|
1170
|
-
needs permission for that receipt table or an administrator must pre-create and
|
|
1171
|
-
grant it. Use app-owned handlers when you do not want Runner creating receipt
|
|
1172
|
-
tables in your application schema.
|
|
1173
|
-
|
|
1174
|
-
## Safety Model
|
|
1175
|
-
|
|
1176
|
-
```text
|
|
1177
|
-
MCP client
|
|
1178
|
-
-> Synapsor Runner
|
|
1179
|
-
-> semantic capability
|
|
1180
|
-
-> trusted tenant/principal context
|
|
1181
|
-
-> scoped DB read
|
|
1182
|
-
-> evidence-backed proposal
|
|
1183
|
-
-> approval outside MCP
|
|
1184
|
-
-> guarded writeback
|
|
1185
|
-
-> receipt and replay
|
|
1186
|
-
```
|
|
1187
|
-
|
|
1188
|
-
Current boundaries:
|
|
1189
|
-
|
|
1190
|
-
- no generic SQL tools;
|
|
1191
|
-
- no model-facing approval or apply tools;
|
|
1192
|
-
- tenant/principal scoping is enforced;
|
|
1193
|
-
- allowed columns are enforced;
|
|
1194
|
-
- primary-key targeting is required;
|
|
1195
|
-
- conflict/version guards are available;
|
|
1196
|
-
- idempotency keys are used;
|
|
1197
|
-
- affected row count is checked;
|
|
1198
|
-
- direct DB writeback is limited to guarded single-row `UPDATE`.
|
|
136
|
+
For proposal capabilities and writes, follow the
|
|
137
|
+
[complete own-database guide](docs/getting-started-own-database.md). One-row
|
|
138
|
+
updates can use Runner's guarded direct writeback. Inserts, multiple tables, or
|
|
139
|
+
external effects go through an [app-owned executor](docs/writeback-executors.md)
|
|
140
|
+
after approval.
|
|
1199
141
|
|
|
1200
|
-
##
|
|
142
|
+
## Trust And Verification
|
|
1201
143
|
|
|
1202
|
-
|
|
144
|
+
Start with the **[Threat Model](THREAT_MODEL.md)**. It defines protected assets,
|
|
145
|
+
trust boundaries, covered threats, non-goals, and required operator controls.
|
|
1203
146
|
|
|
1204
|
-
-
|
|
1205
|
-
-
|
|
1206
|
-
|
|
1207
|
-
-
|
|
1208
|
-
|
|
147
|
+
- [Conformance fixtures](docs/conformance.md) prove trusted context, scoped
|
|
148
|
+
reads, kept-out fields, proposal boundaries, approval, receipts, and replay
|
|
149
|
+
behavior rather than only validating JSON shape.
|
|
150
|
+
- `corepack pnpm test:live-apply` runs disposable Postgres and MySQL scenarios.
|
|
151
|
+
It proves source rows stay unchanged before approval, guarded writeback
|
|
152
|
+
applies once, idempotent retry does not duplicate the effect, and a stale row
|
|
153
|
+
returns a conflict.
|
|
154
|
+
- The C++/Cloud round-trip verifier exports normalized contracts, validates
|
|
155
|
+
them with `@synapsor/spec`, and loads them in Runner. The shared contract and
|
|
156
|
+
verification commands are documented in [Conformance](docs/conformance.md).
|
|
1209
157
|
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
Result: conflict
|
|
1215
|
-
Source DB changed by Synapsor: no
|
|
1216
|
-
```
|
|
158
|
+
Runner is a narrow agent/database safety boundary, not a replacement for
|
|
159
|
+
least-privilege database access, host security, or application authorization.
|
|
160
|
+
See [Security Boundary](docs/security-boundary.md) and
|
|
161
|
+
[Current Limitations](docs/limitations.md).
|
|
1217
162
|
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
## Local Features
|
|
163
|
+
## Packages
|
|
1221
164
|
|
|
1222
|
-
|
|
|
165
|
+
| Package | Purpose |
|
|
1223
166
|
| --- | --- |
|
|
1224
|
-
|
|
|
1225
|
-
|
|
|
1226
|
-
|
|
|
1227
|
-
| Proposals | Local before/after change sets |
|
|
1228
|
-
| Approval | Local CLI/UI approval outside MCP |
|
|
1229
|
-
| Writeback | Guarded single-row `UPDATE` for Postgres/MySQL |
|
|
1230
|
-
| Replay | Local replay of proposal, evidence, events, receipts, and query audit |
|
|
1231
|
-
| MCP audit | Static risk review for MCP database tools |
|
|
1232
|
-
|
|
1233
|
-
The runner intentionally does not include full Synapsor Cloud/DBMS features such
|
|
1234
|
-
as workflow DAGs, native branches, time travel, settlement policies, governed
|
|
1235
|
-
memory, RBAC/SSO, hosted evidence ledger, managed runners, CDC, or C++ DBMS
|
|
1236
|
-
internals.
|
|
1237
|
-
|
|
1238
|
-
## Local Runner Vs Synapsor Cloud
|
|
1239
|
-
|
|
1240
|
-
| Need | Synapsor Runner | Synapsor Cloud |
|
|
1241
|
-
| --- | --- | --- |
|
|
1242
|
-
| Local MCP server | Yes | Contracts export back to Runner; a managed fleet is not claimed |
|
|
1243
|
-
| Local trusted context bindings | Yes | Contract bindings are registered; hosted session behavior is pilot-specific |
|
|
1244
|
-
| Local semantic capabilities | Yes | Hosted registry + versioning |
|
|
1245
|
-
| Local evidence/proposal/replay | Yes | Central searchable ledger |
|
|
1246
|
-
| Local approval | CLI/UI | Existing team approval surfaces where enabled for a pilot |
|
|
1247
|
-
| Writeback | Guarded single-row `UPDATE` | Cloud-linked jobs exist; managed production orchestration is not claimed |
|
|
1248
|
-
| MCP risk audit | Static/local | Continuous/org-wide |
|
|
1249
|
-
| RBAC/SSO | No | RBAC where configured; SAML/SCIM are not in this beta |
|
|
1250
|
-
| Policy packs | Local reviewed subset | Registry preserves policies; hosted enforcement is not implied |
|
|
1251
|
-
| Workflow builder | No | Existing Cloud authoring surfaces; full public DAG parity is not claimed |
|
|
1252
|
-
| Native branches/time travel | No | Yes |
|
|
1253
|
-
| Settlement policies | No | Yes |
|
|
1254
|
-
| Compliance exports | No | Audit/retention primitives exist; legal hold/certification are not claimed |
|
|
1255
|
-
| Production support/SLA | No | Design-partner support; no enterprise SLA is claimed |
|
|
1256
|
-
|
|
1257
|
-
The runner is useful by itself for local/staging safety. Synapsor Cloud adds a
|
|
1258
|
-
shared contract registry, immutable versions, downloadable Runner bundles, and
|
|
1259
|
-
existing team activity/evidence/approval surfaces where enabled. Managed
|
|
1260
|
-
runners, SAML/SCIM, legal hold, and an enterprise SLA remain future work.
|
|
1261
|
-
|
|
1262
|
-
Portable contracts can be checked locally before Cloud import:
|
|
1263
|
-
|
|
1264
|
-
```bash
|
|
1265
|
-
synapsor-runner contract validate ./synapsor.contract.json
|
|
1266
|
-
synapsor-runner contract bundle ./synapsor.contract.json --out ./synapsor-runner-bundle
|
|
1267
|
-
synapsor-runner cloud push ./synapsor.contract.json --dry-run
|
|
1268
|
-
synapsor-runner cloud push ./synapsor.contract.json \
|
|
1269
|
-
--api-url "$SYNAPSOR_CLOUD_BASE_URL" \
|
|
1270
|
-
--token "$SYNAPSOR_CLOUD_TOKEN" \
|
|
1271
|
-
--workspace "$SYNAPSOR_PROJECT_ID" \
|
|
1272
|
-
--name billing-late-fee
|
|
1273
|
-
```
|
|
1274
|
-
|
|
1275
|
-
## Current Limitations
|
|
1276
|
-
|
|
1277
|
-
Supported in the current `0.1.x` line:
|
|
1278
|
-
|
|
1279
|
-
- stdio MCP server;
|
|
1280
|
-
- authenticated HTTP MCP server for app/server deployments;
|
|
1281
|
-
- Postgres/MySQL inspection;
|
|
1282
|
-
- semantic read tools;
|
|
1283
|
-
- evidence-backed proposals;
|
|
1284
|
-
- local approval outside MCP;
|
|
1285
|
-
- guarded single-row `UPDATE`;
|
|
1286
|
-
- local SQLite evidence/proposal/replay store;
|
|
1287
|
-
- tenant, primary-key, allowed-column, idempotency, and conflict guards;
|
|
1288
|
-
- static MCP risk audit.
|
|
1289
|
-
|
|
1290
|
-
Not supported:
|
|
1291
|
-
|
|
1292
|
-
- raw `execute_sql`;
|
|
1293
|
-
- model-generated SQL;
|
|
1294
|
-
- DDL;
|
|
1295
|
-
- INSERT;
|
|
1296
|
-
- DELETE;
|
|
1297
|
-
- UPSERT;
|
|
1298
|
-
- multi-row writes;
|
|
1299
|
-
- stored procedures;
|
|
1300
|
-
- physical branching of external Postgres/MySQL;
|
|
1301
|
-
- full Synapsor workflow DAG execution;
|
|
1302
|
-
- Synapsor SQL generation;
|
|
1303
|
-
- auto-merge or settlement-policy semantics;
|
|
1304
|
-
- model-callable approval or commit tools;
|
|
1305
|
-
- general prompt-injection prevention;
|
|
1306
|
-
- production SLA or compliance certification.
|
|
1307
|
-
|
|
1308
|
-
Contract and DSL authoring can declare workflows and allowed capabilities with
|
|
1309
|
-
`CREATE AGENT WORKFLOW`. Runner 0.1 validates, bundles, and surfaces those
|
|
1310
|
-
contracts, but it does not execute full Synapsor Cloud workflow DAGs,
|
|
1311
|
-
auto-merge, settlement policies, or native branching.
|
|
1312
|
-
|
|
1313
|
-
Complete limits: [docs/limitations.md](docs/limitations.md).
|
|
1314
|
-
|
|
1315
|
-
Security boundary: [docs/security-boundary.md](docs/security-boundary.md).
|
|
167
|
+
| `@synapsor/runner` | CLI, MCP runtime, local ledger, proposals, approval, guarded writeback, replay, and MCP audit. |
|
|
168
|
+
| `@synapsor/spec` | Canonical portable contracts for contexts, capabilities, workflows, evidence, proposals, receipts, and replay. |
|
|
169
|
+
| `@synapsor/dsl` | SQL-like authoring that compiles contexts, capabilities, and workflow declarations into canonical contract JSON. |
|
|
1316
170
|
|
|
1317
|
-
|
|
1318
|
-
|
|
171
|
+
Runner executes locally. The spec is the portable contract shared by Runner
|
|
172
|
+
and Cloud/C++. The DSL gives that contract a reviewable source format. Start
|
|
173
|
+
with [Capability Authoring](docs/capability-authoring.md).
|
|
1319
174
|
|
|
1320
|
-
|
|
1321
|
-
[docs/release-notes.md](docs/release-notes.md).
|
|
175
|
+
## OSS And Cloud
|
|
1322
176
|
|
|
1323
|
-
|
|
177
|
+
Synapsor Runner works by itself for local and single-node deployments: your
|
|
178
|
+
database remains the source of truth and the local SQLite ledger stores review
|
|
179
|
+
artifacts. Synapsor Cloud adds a shared contract registry, immutable versions,
|
|
180
|
+
downloadable Runner bundles, and team activity, evidence, and approval
|
|
181
|
+
surfaces. See [OSS Runner vs Synapsor Cloud](docs/oss-vs-cloud.md) for the
|
|
182
|
+
detailed boundary.
|
|
1324
183
|
|
|
1325
|
-
|
|
1326
|
-
through the `0.1.x` line unless a release note explicitly marks a deprecation
|
|
1327
|
-
first:
|
|
184
|
+
## Next Steps
|
|
1328
185
|
|
|
1329
|
-
- the `
|
|
1330
|
-
-
|
|
1331
|
-
-
|
|
1332
|
-
-
|
|
1333
|
-
-
|
|
1334
|
-
- proposal, approval, guarded writeback, receipt, evidence, query-audit, and
|
|
1335
|
-
replay inspection commands;
|
|
1336
|
-
- direct SQL writeback and app-owned executor contracts documented in this
|
|
1337
|
-
README and `docs/writeback-executors.md`.
|
|
1338
|
-
|
|
1339
|
-
Stable does not mean production SLA, hosted Cloud features, compliance
|
|
1340
|
-
certification, physical Postgres/MySQL branching, generic SQL writeback, or
|
|
1341
|
-
support for undocumented local SQLite internals. Those limits remain explicit
|
|
1342
|
-
in [docs/limitations.md](docs/limitations.md).
|
|
186
|
+
- Run the [`support-plan-credit` flagship example](examples/support-plan-credit).
|
|
187
|
+
- Connect [Claude, Cursor, OpenAI Agents SDK, or another MCP client](docs/mcp-clients.md).
|
|
188
|
+
- Author and [push a validated contract to Cloud](docs/cloud-push.md).
|
|
189
|
+
- Browse the [task-first documentation index](docs/README.md).
|
|
190
|
+
- Report bugs or request features through [GitHub Issues](https://github.com/Synapsor/Synapsor-Runner/issues).
|
|
1343
191
|
|
|
1344
192
|
## License
|
|
1345
193
|
|
|
1346
|
-
Synapsor Runner is open source under the Apache License 2.0 (`Apache-2.0`).
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
Synapsor name, logo, hosted cloud service, or proprietary Synapsor platform
|
|
1350
|
-
features. See [docs/licensing.md](docs/licensing.md) and
|
|
1351
|
-
[TRADEMARKS.md](TRADEMARKS.md).
|
|
1352
|
-
|
|
1353
|
-
Synapsor Cloud, hosted governance, advanced policy/workflow engines, enterprise
|
|
1354
|
-
controls, and native Synapsor DBMS/C++ internals are outside this Apache-2.0
|
|
1355
|
-
repository. Managed runners and other hosted features, where offered, are
|
|
1356
|
-
proprietary and are not implied by the OSS package.
|
|
1357
|
-
|
|
1358
|
-
## Developer And Contributor Commands
|
|
1359
|
-
|
|
1360
|
-
Public docs use `synapsor-runner`. During source-checkout development, if the
|
|
1361
|
-
global binary is not linked yet, use `./bin/synapsor-runner ...` or
|
|
1362
|
-
`corepack pnpm runner ...`.
|
|
1363
|
-
|
|
1364
|
-
Helper scripts are wrappers and development conveniences, not the main product
|
|
1365
|
-
interface:
|
|
1366
|
-
|
|
1367
|
-
```bash
|
|
1368
|
-
./scripts/try-synapsor.sh
|
|
1369
|
-
./scripts/demo-docker.sh
|
|
1370
|
-
./scripts/open-demo-ui.sh
|
|
1371
|
-
./scripts/use-your-db.sh
|
|
1372
|
-
./scripts/mcp-config.sh
|
|
1373
|
-
```
|
|
1374
|
-
|
|
1375
|
-
Contributor checks:
|
|
1376
|
-
|
|
1377
|
-
```bash
|
|
1378
|
-
corepack pnpm install
|
|
1379
|
-
./scripts/verify-release-gate.sh
|
|
1380
|
-
```
|
|
1381
|
-
|
|
1382
|
-
After a manual alpha publish, verify the public npm package:
|
|
1383
|
-
|
|
1384
|
-
```bash
|
|
1385
|
-
VERIFY_PUBLISHED_ALPHA=1 ./scripts/verify-release-gate.sh 0.1.0-alpha.17
|
|
1386
|
-
```
|
|
1387
|
-
|
|
1388
|
-
After a manual stable publish/promotion, verify `latest`:
|
|
1389
|
-
|
|
1390
|
-
```bash
|
|
1391
|
-
./scripts/verify-published-stable.sh 0.1.0
|
|
1392
|
-
```
|
|
1393
|
-
|
|
1394
|
-
## Repository Map
|
|
1395
|
-
|
|
1396
|
-
- `apps/runner`: CLI entrypoint and local UI.
|
|
1397
|
-
- `packages/spec`: canonical portable contract schemas, normalization, CLI, and conformance fixtures.
|
|
1398
|
-
- `packages/dsl`: SQL-like contract authoring for contexts, capabilities, and workflow declarations.
|
|
1399
|
-
- `packages/mcp-server`: stdio/HTTP MCP server and configured tool runtime.
|
|
1400
|
-
- `packages/schema-inspector`: Postgres/MySQL metadata inspection and config generation.
|
|
1401
|
-
- `packages/proposal-store`: local SQLite evidence/proposal/replay store.
|
|
1402
|
-
- `packages/postgres`, `packages/mysql`: guarded writeback adapters.
|
|
1403
|
-
- `packages/worker-core`: shared runner orchestration.
|
|
1404
|
-
- `recipes`: optional starter contracts.
|
|
1405
|
-
- `examples`: disposable local demos and reference app.
|
|
1406
|
-
- `docs`: focused setup, MCP, security, troubleshooting, and limitation docs.
|
|
1407
|
-
|
|
1408
|
-
## Community
|
|
1409
|
-
|
|
1410
|
-
Synapsor Runner is maintained by Synapsor.
|
|
194
|
+
Synapsor Runner is open source under the Apache License 2.0 (`Apache-2.0`). See
|
|
195
|
+
[Licensing](docs/licensing.md) and [Trademarks](TRADEMARKS.md). Synapsor Cloud
|
|
196
|
+
and proprietary Synapsor platform components are outside this repository.
|
|
1411
197
|
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
- License: Apache License 2.0 (`Apache-2.0`)
|
|
1415
|
-
- Issues: use GitHub Issues
|
|
198
|
+
Maintainer and contributor workflows live in [CONTRIBUTING.md](CONTRIBUTING.md)
|
|
199
|
+
and [AGENTS.md](AGENTS.md).
|