@synapsor/runner 0.1.0-alpha.8 → 0.1.0
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/CHANGELOG.md +162 -0
- package/README.md +391 -25
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/runner.mjs +2945 -193
- package/docs/README.md +40 -0
- package/docs/app-owned-executors.md +38 -0
- package/docs/capability-authoring.md +265 -0
- package/docs/cloud-mode.md +24 -0
- package/docs/current-scope.md +29 -0
- package/docs/dependency-license-inventory.md +35 -0
- package/docs/doctor.md +98 -0
- package/docs/getting-started-own-database.md +131 -46
- package/docs/handler-helper.md +228 -0
- package/docs/http-mcp.md +85 -17
- package/docs/licensing.md +36 -0
- package/docs/local-mode.md +44 -25
- package/docs/mcp-audit.md +8 -8
- package/docs/mcp-client-setup.md +59 -21
- package/docs/openai-agents-sdk.md +57 -0
- package/docs/recipes.md +6 -6
- package/docs/release-notes.md +327 -0
- package/docs/release-policy.md +125 -0
- package/docs/result-envelope-v2.md +151 -0
- package/docs/rfcs/001-result-envelope-v2.md +143 -0
- package/docs/rfcs/002-app-owned-handler-helper.md +161 -0
- package/docs/rfcs/003-integrator-feedback-teardown.md +97 -0
- package/docs/store-lifecycle.md +83 -0
- package/docs/troubleshooting-first-run.md +6 -6
- package/docs/use-your-own-database.md +18 -0
- package/docs/writeback-executors.md +92 -1
- package/examples/app-owned-writeback/README.md +128 -0
- package/examples/app-owned-writeback/business-actions.md +221 -0
- package/examples/app-owned-writeback/command-handler.mjs +55 -0
- package/examples/app-owned-writeback/node-fastify-handler.mjs +64 -0
- package/examples/app-owned-writeback/python-fastapi-handler.py +66 -0
- package/examples/mcp-postgres-billing-app-handler/README.md +94 -0
- package/examples/mcp-postgres-billing-app-handler/app-handler.mjs +123 -0
- package/examples/mcp-postgres-billing-app-handler/docker-compose.yml +13 -0
- package/examples/mcp-postgres-billing-app-handler/schema.sql +59 -0
- package/examples/mcp-postgres-billing-app-handler/scripts/run-demo.sh +100 -0
- package/examples/mcp-postgres-billing-app-handler/seed.sql +39 -0
- package/examples/mcp-postgres-billing-app-handler/synapsor-handler.mjs +437 -0
- package/examples/mcp-postgres-billing-app-handler/synapsor.runner.json +158 -0
- package/examples/openai-agents-http/README.md +19 -12
- package/examples/openai-agents-http/agent.py +29 -65
- package/examples/openai-agents-stdio/README.md +10 -6
- package/examples/openai-agents-stdio/agent.py +4 -2
- package/examples/reference-support-billing-app/README.md +16 -16
- package/examples/reference-support-billing-app/mcp-client.generic.json +1 -1
- package/fixtures/benchmark/mcp-efficiency.json +53 -0
- package/fixtures/benchmark/mcp-efficiency.txt +25 -0
- package/fixtures/protocol/MANIFEST.json +54 -0
- package/fixtures/protocol/change-set.late-fee-waiver.v1.json +72 -0
- package/fixtures/protocol/execution-receipt.applied.v1.json +14 -0
- package/fixtures/protocol/execution-receipt.conflict.v1.json +15 -0
- package/fixtures/protocol/runner-registration.v1.json +22 -0
- package/fixtures/protocol/writeback-job.late-fee-waiver.v1.json +44 -0
- package/package.json +6 -1
- package/schemas/change-set.v1.schema.json +140 -0
- package/schemas/execution-receipt.v1.schema.json +34 -0
- package/schemas/onboarding-selection.v1.schema.json +132 -0
- package/schemas/runner-registration.v1.schema.json +48 -0
- package/schemas/synapsor.app-handler-receipt.v1.json +39 -0
- package/schemas/synapsor.app-handler-request.v1.json +119 -0
- package/schemas/synapsor.runner.schema.json +415 -0
- package/schemas/writeback-job.v1.schema.json +121 -0
package/README.md
CHANGED
|
@@ -7,6 +7,68 @@ Runner lets an MCP agent inspect scoped data and request database-backed
|
|
|
7
7
|
business actions without receiving raw SQL, write credentials, approval tools,
|
|
8
8
|
or commit tools.
|
|
9
9
|
|
|
10
|
+
## The Five-Line Model
|
|
11
|
+
|
|
12
|
+
Your agent talks to Synapsor Runner, not directly to your database.
|
|
13
|
+
It can look: scoped reads through reviewed tools.
|
|
14
|
+
It can suggest: saved proposals with evidence and exact diffs.
|
|
15
|
+
It cannot commit: approval and writeback happen outside the model-facing tool.
|
|
16
|
+
After writeback, Runner keeps receipts and replay so you can inspect what happened.
|
|
17
|
+
|
|
18
|
+
## Four Terms
|
|
19
|
+
|
|
20
|
+
- Capability: a tool you define in config, such as `billing.inspect_invoice`
|
|
21
|
+
or `billing.propose_late_fee_waiver`. The agent only sees capabilities.
|
|
22
|
+
- Proposal: the agent's suggested database-backed change. It is saved, not
|
|
23
|
+
applied.
|
|
24
|
+
- Writeback: the moment an approved proposal actually changes the database.
|
|
25
|
+
- Executor: your app's writeback handler for anything richer than a guarded
|
|
26
|
+
one-row update.
|
|
27
|
+
|
|
28
|
+
You install only `@synapsor/runner`. There is no separate handler package to
|
|
29
|
+
install. A handler is your app's endpoint or script for rich approved writes;
|
|
30
|
+
Runner includes templates and examples to help you build one.
|
|
31
|
+
|
|
32
|
+
## Who Does What
|
|
33
|
+
|
|
34
|
+
You write the config: sources, trusted context, capabilities, visible fields,
|
|
35
|
+
proposal fields, and guards. For rich writes, you also write a small handler.
|
|
36
|
+
|
|
37
|
+
Synapsor Runner serves the MCP tools, stores evidence/proposals/receipts,
|
|
38
|
+
enforces tenant, column, version, and idempotency guards, routes writeback, and
|
|
39
|
+
keeps the replay log. You do not rebuild the safety loop yourself.
|
|
40
|
+
|
|
41
|
+
## The Writeback Rule
|
|
42
|
+
|
|
43
|
+
One-row update to an existing row: Runner can do guarded direct writeback.
|
|
44
|
+
Anything else, such as inserting a row, touching two tables, or emitting an
|
|
45
|
+
event: your app-owned executor does it after approval.
|
|
46
|
+
|
|
47
|
+
## How An External Handler Works
|
|
48
|
+
|
|
49
|
+
Some changes are too rich for Runner's one-row writeback: insert a credit row,
|
|
50
|
+
touch two tables, or emit an event. For those, you run a small endpoint. The
|
|
51
|
+
flow is:
|
|
52
|
+
|
|
53
|
+
```text
|
|
54
|
+
agent proposes
|
|
55
|
+
-> human approves outside MCP
|
|
56
|
+
-> Runner POSTs the approved change to your endpoint
|
|
57
|
+
-> your code writes it in its own transaction and returns a receipt
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
The model never touches this code. You are the last line of defense: Runner
|
|
61
|
+
hands you the tenant, expected row version, and idempotency key, and your
|
|
62
|
+
handler must re-check all three. Skipping those checks reintroduces
|
|
63
|
+
cross-tenant writes, lost updates, or duplicate writes. Start from
|
|
64
|
+
`synapsor-runner handler template ...` instead of hand-rolling the safety checks.
|
|
65
|
+
|
|
66
|
+
## Deliberate Limits
|
|
67
|
+
|
|
68
|
+
Runner does not expose raw SQL, write credentials, approval tools, or commit
|
|
69
|
+
tools to the model. Direct Runner writeback does not do generic `INSERT`,
|
|
70
|
+
`DELETE`, `UPSERT`, DDL, or multi-row SQL. Those are app-owned executor jobs.
|
|
71
|
+
|
|
10
72
|
```text
|
|
11
73
|
AI agent or MCP client
|
|
12
74
|
(Claude, Cursor, OpenAI Agents SDK, LangGraph)
|
|
@@ -51,7 +113,7 @@ Run the guided quick demo first. It does not require Docker, a database, a
|
|
|
51
113
|
config file, an MCP client, or a Synapsor Cloud account.
|
|
52
114
|
|
|
53
115
|
```bash
|
|
54
|
-
npx -y -p @synapsor/runner
|
|
116
|
+
npx -y -p @synapsor/runner synapsor-runner demo --quick
|
|
55
117
|
```
|
|
56
118
|
|
|
57
119
|
In a terminal, it walks through the safety model step by step. In CI, piped
|
|
@@ -63,7 +125,7 @@ It does not prove database connectivity. It shows the proposal, evidence, and
|
|
|
63
125
|
replay flow without giving the runner a database URL.
|
|
64
126
|
|
|
65
127
|
```bash
|
|
66
|
-
npx -y -p @synapsor/runner
|
|
128
|
+
npx -y -p @synapsor/runner synapsor-runner demo inspect
|
|
67
129
|
```
|
|
68
130
|
|
|
69
131
|
Human output is concise by default. Use `--details` for reviewer metadata or
|
|
@@ -81,14 +143,69 @@ synapsor-runner demo inspect --npx
|
|
|
81
143
|
Then choose one path:
|
|
82
144
|
|
|
83
145
|
```text
|
|
84
|
-
Full disposable proof -> npx -y -p @synapsor/runner
|
|
146
|
+
Full disposable proof -> npx -y -p @synapsor/runner synapsor-runner demo
|
|
85
147
|
Your own staging DB -> export DATABASE_URL=... then run the inspect command below
|
|
86
|
-
MCP risk review -> npx -y -p @synapsor/runner
|
|
148
|
+
MCP risk review -> npx -y -p @synapsor/runner synapsor-runner audit --example dangerous-db-mcp
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
For your own database, do this before wiring Claude, Cursor, OpenAI Agents SDK,
|
|
152
|
+
or another MCP client:
|
|
153
|
+
|
|
154
|
+
```text
|
|
155
|
+
1. Generate the 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. Only then run up --serve or mcp serve.
|
|
87
159
|
```
|
|
88
160
|
|
|
89
161
|
`synapsor-runner` is the public command for this OSS runner. `synapsor` is
|
|
90
162
|
reserved for the Synapsor Cloud CLI.
|
|
91
163
|
|
|
164
|
+
Authoring reference:
|
|
165
|
+
|
|
166
|
+
- [Capability Authoring](docs/capability-authoring.md): read/proposal tools,
|
|
167
|
+
model-facing descriptions, result envelope v2, trusted context, and writeback
|
|
168
|
+
guards.
|
|
169
|
+
- [Result Envelope v2](docs/result-envelope-v2.md): stable
|
|
170
|
+
`ok`/`summary`/`data`/`proposal`/`error` MCP tool results.
|
|
171
|
+
- [JSON Schema](schemas/synapsor.runner.schema.json): editor validation for
|
|
172
|
+
`synapsor.runner.json`.
|
|
173
|
+
|
|
174
|
+
## Current Alpha Details
|
|
175
|
+
|
|
176
|
+
These are current alpha requirements, not hidden behavior:
|
|
177
|
+
|
|
178
|
+
- Writeback with `--config ./synapsor.runner.json` reads the trusted writer
|
|
179
|
+
connection from the source `write_url_env`, for example
|
|
180
|
+
`SYNAPSOR_DATABASE_WRITE_URL`. `SYNAPSOR_DATABASE_URL` is only the legacy
|
|
181
|
+
fallback when you run direct worker/apply flows without a local config.
|
|
182
|
+
- `synapsor-runner mcp serve` is standard stdio MCP for local clients that can
|
|
183
|
+
launch Runner.
|
|
184
|
+
- `synapsor-runner mcp serve-streamable-http` is standard MCP Streamable HTTP
|
|
185
|
+
with `initialize` and in-memory session behavior for SDK/client HTTP MCP
|
|
186
|
+
integrations.
|
|
187
|
+
- OpenAI Agents SDK rejects dotted function/tool names. Use
|
|
188
|
+
`--alias-mode openai` or `--openai-tool-aliases` for OpenAI-facing MCP
|
|
189
|
+
transports. Runner exposes aliases such as `billing__inspect_invoice` and
|
|
190
|
+
keeps the canonical Synapsor capability name in tool metadata.
|
|
191
|
+
- `synapsor-runner mcp serve-http` is a small authenticated JSON-RPC bridge for
|
|
192
|
+
`tools/list`, `tools/call`, and `resources/read`. Use it only when you want a
|
|
193
|
+
simple app/server wrapper instead of full HTTP MCP.
|
|
194
|
+
- Direct SQL writeback creates or writes `synapsor_writeback_receipts` for
|
|
195
|
+
idempotency and replay. The trusted writer needs permission for that table,
|
|
196
|
+
or an administrator must pre-create it and grant access. Use an app-owned
|
|
197
|
+
`http_handler` or `command_handler` if Runner should not create receipt
|
|
198
|
+
tables in your application schema.
|
|
199
|
+
- Run `synapsor-runner doctor --config synapsor.runner.json --check-writeback`
|
|
200
|
+
after reviewing receipt-table DDL/grants to verify writer connectivity,
|
|
201
|
+
receipt-table permissions, and rollback-only target-table access. The probe
|
|
202
|
+
never mutates business rows, but it can create the receipt table if the
|
|
203
|
+
writer has permission.
|
|
204
|
+
- For app-owned `http_handler` executors, configure `signing_secret_env` to
|
|
205
|
+
have Runner sign writeback requests with `X-Synapsor-Signature`. Run
|
|
206
|
+
`synapsor-runner doctor --config synapsor.runner.json --check-handlers` to
|
|
207
|
+
check handler env vars and network reachability without applying a proposal.
|
|
208
|
+
|
|
92
209
|
## Connect Your Own Staging Database
|
|
93
210
|
|
|
94
211
|
Put a read-only connection string in the environment:
|
|
@@ -101,17 +218,160 @@ For disposable dev RDS fixtures only, use `sslmode=no-verify` if your local
|
|
|
101
218
|
Node/Postgres TLS stack cannot verify the test certificate chain. For real
|
|
102
219
|
staging or production-like databases, keep certificate verification enabled.
|
|
103
220
|
|
|
104
|
-
|
|
221
|
+
Run the guided own-database path:
|
|
105
222
|
|
|
106
223
|
```bash
|
|
107
|
-
npx -y -p @synapsor/runner
|
|
108
|
-
--engine auto \
|
|
224
|
+
npx -y -p @synapsor/runner synapsor-runner start \
|
|
109
225
|
--from-env DATABASE_URL \
|
|
110
226
|
--schema public
|
|
111
227
|
```
|
|
112
228
|
|
|
113
|
-
|
|
114
|
-
|
|
229
|
+
`start --from-env` is the low-friction alias for `onboard db --from-env`. That
|
|
230
|
+
path inspects metadata, helps you choose one table/view, creates trusted
|
|
231
|
+
context bindings, generates semantic MCP tools, validates the tool boundary,
|
|
232
|
+
and prints the exact MCP/UI next commands. It does not require hand-authored
|
|
233
|
+
JSON. If you provide an optional real object id during the wizard, it also
|
|
234
|
+
writes `./.synapsor/smoke-input.json` so the first tool call can use an actual
|
|
235
|
+
row instead of guessed sample data. When the read URL env var and trusted
|
|
236
|
+
tenant/principal env vars are already set, onboarding also attempts that smoke
|
|
237
|
+
call immediately and stores the evidence/query audit in the local ledger. If
|
|
238
|
+
those env vars are missing, it prints the exact command to run after you set
|
|
239
|
+
them from `.env.example`.
|
|
240
|
+
|
|
241
|
+
The end-to-end shape is:
|
|
242
|
+
|
|
243
|
+
```text
|
|
244
|
+
1. Put your read-only DB URL in DATABASE_URL.
|
|
245
|
+
2. Run start --from-env DATABASE_URL.
|
|
246
|
+
3. Choose one table/view and the safe fields agents may see.
|
|
247
|
+
4. Preview the generated capabilities.
|
|
248
|
+
5. Serve them over MCP to Claude, Cursor, OpenAI Agents SDK, or your app.
|
|
249
|
+
6. For writes, approve a proposal outside MCP before writeback.
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
The generated config is just the safety contract. A small reviewed version
|
|
253
|
+
looks like this:
|
|
254
|
+
|
|
255
|
+
Bring the generated review-mode workspace up with one command:
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
npx -y -p @synapsor/runner synapsor-runner up \
|
|
259
|
+
--serve \
|
|
260
|
+
--config ./synapsor.runner.json \
|
|
261
|
+
--store ./.synapsor/local.db
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
`up` validates the config/store, summarizes model-facing tools, shows whether
|
|
265
|
+
proposal tools use direct SQL writeback or app-owned executors, checks active
|
|
266
|
+
store leases, and prints the next smoke, approve, apply, replay, UI, and doctor
|
|
267
|
+
commands. By default, `up` is guidance-only. Use `up --serve` to start the
|
|
268
|
+
standard Streamable HTTP MCP server after the checklist; use `--dry-run` to
|
|
269
|
+
rehearse without starting it. For app-owned executor configs, add
|
|
270
|
+
`--with-handler` to run the handler doctor before serving.
|
|
271
|
+
|
|
272
|
+
For CI, shell scripts, or an LLM driving the setup, use the prompt-free path:
|
|
273
|
+
|
|
274
|
+
```bash
|
|
275
|
+
npx -y -p @synapsor/runner synapsor-runner onboard db \
|
|
276
|
+
--from-env DATABASE_URL \
|
|
277
|
+
--schema public \
|
|
278
|
+
--table invoices \
|
|
279
|
+
--mode review \
|
|
280
|
+
--tenant-column tenant_id \
|
|
281
|
+
--primary-key id \
|
|
282
|
+
--conflict-column updated_at \
|
|
283
|
+
--namespace billing \
|
|
284
|
+
--object-name invoice \
|
|
285
|
+
--id-arg invoice_id \
|
|
286
|
+
--visible-columns id,tenant_id,late_fee_cents,waiver_reason,updated_at \
|
|
287
|
+
--patch late_fee_cents=fixed:0,waiver_reason=arg:reason \
|
|
288
|
+
--patch-bounds late_fee_cents=0:5500 \
|
|
289
|
+
--write-url-env SYNAPSOR_DATABASE_WRITE_URL \
|
|
290
|
+
--yes
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
If `--namespace` is omitted, Runner derives a namespace from the table name
|
|
294
|
+
instead of creating `source.*` tools. Use `--read-tool` and `--proposal-tool`
|
|
295
|
+
when you need exact model-facing names.
|
|
296
|
+
|
|
297
|
+
For app-owned writeback, replace `--write-url-env ...` with
|
|
298
|
+
`--writeback http_handler --handler-url-env APP_WRITEBACK_URL --emit-handler`.
|
|
299
|
+
Runner marks that source as read-only unless you explicitly pass a writer env,
|
|
300
|
+
so `config validate` does not warn that direct SQL writeback is disabled.
|
|
301
|
+
You can also pass `--answers ./answers.json --yes` for a fully declarative
|
|
302
|
+
setup file.
|
|
303
|
+
|
|
304
|
+
```json
|
|
305
|
+
{
|
|
306
|
+
"version": 1,
|
|
307
|
+
"mode": "review",
|
|
308
|
+
"result_format": 2,
|
|
309
|
+
"sources": {
|
|
310
|
+
"app_postgres": {
|
|
311
|
+
"engine": "postgres",
|
|
312
|
+
"read_url_env": "DATABASE_URL",
|
|
313
|
+
"write_url_env": "SYNAPSOR_DATABASE_WRITE_URL"
|
|
314
|
+
}
|
|
315
|
+
},
|
|
316
|
+
"trusted_context": {
|
|
317
|
+
"provider": "environment",
|
|
318
|
+
"values": {
|
|
319
|
+
"tenant_id_env": "SYNAPSOR_TENANT_ID",
|
|
320
|
+
"principal_env": "SYNAPSOR_PRINCIPAL"
|
|
321
|
+
}
|
|
322
|
+
},
|
|
323
|
+
"capabilities": [
|
|
324
|
+
{
|
|
325
|
+
"name": "billing.inspect_invoice",
|
|
326
|
+
"kind": "read",
|
|
327
|
+
"source": "app_postgres",
|
|
328
|
+
"target": {
|
|
329
|
+
"schema": "public",
|
|
330
|
+
"table": "invoices",
|
|
331
|
+
"primary_key": "id",
|
|
332
|
+
"tenant_key": "tenant_id"
|
|
333
|
+
},
|
|
334
|
+
"args": {
|
|
335
|
+
"invoice_id": { "type": "string", "required": true }
|
|
336
|
+
},
|
|
337
|
+
"lookup": { "id_from_arg": "invoice_id" },
|
|
338
|
+
"visible_columns": ["id", "status", "late_fee_cents", "updated_at"],
|
|
339
|
+
"evidence": "required",
|
|
340
|
+
"max_rows": 1
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
"name": "billing.propose_late_fee_waiver",
|
|
344
|
+
"kind": "proposal",
|
|
345
|
+
"source": "app_postgres",
|
|
346
|
+
"target": {
|
|
347
|
+
"schema": "public",
|
|
348
|
+
"table": "invoices",
|
|
349
|
+
"primary_key": "id",
|
|
350
|
+
"tenant_key": "tenant_id"
|
|
351
|
+
},
|
|
352
|
+
"args": {
|
|
353
|
+
"invoice_id": { "type": "string", "required": true },
|
|
354
|
+
"reason": { "type": "string", "required": true }
|
|
355
|
+
},
|
|
356
|
+
"lookup": { "id_from_arg": "invoice_id" },
|
|
357
|
+
"visible_columns": ["id", "status", "late_fee_cents", "updated_at"],
|
|
358
|
+
"patch": {
|
|
359
|
+
"late_fee_cents": { "fixed": 0 },
|
|
360
|
+
"waiver_reason": { "from_arg": "reason" }
|
|
361
|
+
},
|
|
362
|
+
"allowed_columns": ["late_fee_cents", "waiver_reason"],
|
|
363
|
+
"conflict_guard": { "column": "updated_at" },
|
|
364
|
+
"approval": { "mode": "human", "required_role": "billing_lead" }
|
|
365
|
+
}
|
|
366
|
+
]
|
|
367
|
+
}
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
The agent sees `billing.inspect_invoice` and
|
|
371
|
+
`billing.propose_late_fee_waiver`. It does not see the database URL, writer
|
|
372
|
+
credential, raw SQL, approval command, or commit command.
|
|
373
|
+
|
|
374
|
+
The wizard creates this local flow:
|
|
115
375
|
|
|
116
376
|
```text
|
|
117
377
|
trusted context -> capability -> MCP tool
|
|
@@ -119,10 +379,11 @@ trusted context -> capability -> MCP tool
|
|
|
119
379
|
|
|
120
380
|
It asks which table/view backs the context, which tenant/scope column and
|
|
121
381
|
backend session env vars are trusted, which fields are visible, and what
|
|
122
|
-
semantic capability name to expose.
|
|
382
|
+
semantic capability name to expose. Before writing files, it shows a final
|
|
383
|
+
preview and lets you revise visible fields or capability names.
|
|
123
384
|
|
|
124
385
|
```bash
|
|
125
|
-
npx -y -p @synapsor/runner
|
|
386
|
+
npx -y -p @synapsor/runner synapsor-runner init \
|
|
126
387
|
--wizard \
|
|
127
388
|
--engine auto \
|
|
128
389
|
--from-env DATABASE_URL \
|
|
@@ -133,15 +394,26 @@ npx -y -p @synapsor/runner@alpha synapsor-runner init \
|
|
|
133
394
|
Preview and serve the semantic tools:
|
|
134
395
|
|
|
135
396
|
```bash
|
|
136
|
-
npx -y -p @synapsor/runner
|
|
397
|
+
npx -y -p @synapsor/runner synapsor-runner tools preview \
|
|
137
398
|
--config ./synapsor.runner.json \
|
|
138
399
|
--store ./.synapsor/local.db
|
|
139
400
|
|
|
140
|
-
npx -y -p @synapsor/runner
|
|
401
|
+
npx -y -p @synapsor/runner synapsor-runner smoke call \
|
|
402
|
+
<generated.inspect_tool_name> \
|
|
403
|
+
--input ./.synapsor/smoke-input.json \
|
|
404
|
+
--config ./synapsor.runner.json \
|
|
405
|
+
--store ./.synapsor/local.db
|
|
406
|
+
|
|
407
|
+
npx -y -p @synapsor/runner synapsor-runner mcp serve \
|
|
141
408
|
--config ./synapsor.runner.json \
|
|
142
409
|
--store ./.synapsor/local.db
|
|
143
410
|
```
|
|
144
411
|
|
|
412
|
+
`smoke call` uses the same runtime as MCP, records evidence/query audit or a
|
|
413
|
+
proposal in the local store, and prints the evidence/proposal/replay commands
|
|
414
|
+
to inspect what happened. If you skipped the optional smoke input in the
|
|
415
|
+
wizard, pass `--json '{"<lookup_arg>":"<real_id>"}'` instead.
|
|
416
|
+
|
|
145
417
|
## Two Ways To Run MCP
|
|
146
418
|
|
|
147
419
|
Use stdio when the MCP client runs locally and can launch Synapsor Runner. Use
|
|
@@ -156,26 +428,70 @@ synapsor-runner mcp serve \
|
|
|
156
428
|
--store ./.synapsor/local.db
|
|
157
429
|
```
|
|
158
430
|
|
|
431
|
+
For OpenAI Agents SDK over stdio, add OpenAI-safe aliases:
|
|
432
|
+
|
|
433
|
+
```bash
|
|
434
|
+
synapsor-runner mcp serve \
|
|
435
|
+
--config ./synapsor.runner.json \
|
|
436
|
+
--store ./.synapsor/local.db \
|
|
437
|
+
--alias-mode openai
|
|
438
|
+
```
|
|
439
|
+
|
|
159
440
|
App/server deployments:
|
|
160
441
|
|
|
161
442
|
```bash
|
|
162
443
|
export SYNAPSOR_RUNNER_HTTP_TOKEN="dev-local-token"
|
|
163
444
|
|
|
445
|
+
synapsor-runner mcp serve-streamable-http \
|
|
446
|
+
--config ./synapsor.runner.json \
|
|
447
|
+
--store ./.synapsor/local.db \
|
|
448
|
+
--auth-token-env SYNAPSOR_RUNNER_HTTP_TOKEN \
|
|
449
|
+
--alias-mode openai
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
You can also start the same review-mode server through the safer startup
|
|
453
|
+
checklist:
|
|
454
|
+
|
|
455
|
+
```bash
|
|
456
|
+
synapsor-runner up --serve \
|
|
457
|
+
--config ./synapsor.runner.json \
|
|
458
|
+
--store ./.synapsor/local.db \
|
|
459
|
+
--auth-token-env SYNAPSOR_RUNNER_HTTP_TOKEN \
|
|
460
|
+
--alias-mode openai
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
Equivalent unified command:
|
|
464
|
+
|
|
465
|
+
```bash
|
|
466
|
+
synapsor-runner mcp serve \
|
|
467
|
+
--transport streamable-http \
|
|
468
|
+
--config ./synapsor.runner.json \
|
|
469
|
+
--store ./.synapsor/local.db \
|
|
470
|
+
--auth-token-env SYNAPSOR_RUNNER_HTTP_TOKEN \
|
|
471
|
+
--alias-mode openai
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
Streamable HTTP defaults to `127.0.0.1:8766`, requires bearer auth by default,
|
|
475
|
+
and should use private networking, TLS, and rate limits before being exposed
|
|
476
|
+
beyond a local machine. With `--alias-mode openai`, tools are exposed to
|
|
477
|
+
the model as OpenAI-safe aliases such as `billing__inspect_invoice`; `_meta`
|
|
478
|
+
still includes `synapsor.canonical_tool_name = billing.inspect_invoice`, and
|
|
479
|
+
Runner routes calls back to the canonical Synapsor capability. Use
|
|
480
|
+
`--alias-mode both` during migrations if one client still expects canonical
|
|
481
|
+
dotted names while another needs OpenAI-safe aliases.
|
|
482
|
+
|
|
483
|
+
Bridge mode:
|
|
484
|
+
|
|
485
|
+
```bash
|
|
164
486
|
synapsor-runner mcp serve-http \
|
|
165
487
|
--config ./synapsor.runner.json \
|
|
166
488
|
--store ./.synapsor/local.db \
|
|
167
489
|
--auth-token-env SYNAPSOR_RUNNER_HTTP_TOKEN
|
|
168
490
|
```
|
|
169
491
|
|
|
170
|
-
HTTP defaults to `127.0.0.1:8765
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
HTTP alpha scope: `serve-http` is a JSON-RPC endpoint for `tools/list`,
|
|
175
|
-
`tools/call`, and `resources/read`. It is not full MCP Streamable HTTP and does
|
|
176
|
-
not implement `initialize`/SSE. If an SDK HTTP MCP client expects that
|
|
177
|
-
handshake, use stdio mode or wrap the HTTP endpoint like the OpenAI HTTP
|
|
178
|
-
example.
|
|
492
|
+
Bridge HTTP defaults to `127.0.0.1:8765` and supports only JSON-RPC
|
|
493
|
+
`tools/list`, `tools/call`, and `resources/read`. It does not implement MCP
|
|
494
|
+
Streamable HTTP `initialize`/session behavior.
|
|
179
495
|
|
|
180
496
|
OpenAI Agents SDK examples:
|
|
181
497
|
|
|
@@ -195,6 +511,15 @@ Before asking an agent to solve a real task, confirm it can call a Runner tool:
|
|
|
195
511
|
synapsor-runner tools preview --config ./synapsor.runner.json --store ./.synapsor/local.db
|
|
196
512
|
```
|
|
197
513
|
|
|
514
|
+
For OpenAI-facing clients:
|
|
515
|
+
|
|
516
|
+
```bash
|
|
517
|
+
synapsor-runner tools preview \
|
|
518
|
+
--config ./synapsor.runner.json \
|
|
519
|
+
--store ./.synapsor/local.db \
|
|
520
|
+
--alias-mode openai
|
|
521
|
+
```
|
|
522
|
+
|
|
198
523
|
Then ask the agent:
|
|
199
524
|
|
|
200
525
|
```text
|
|
@@ -217,12 +542,25 @@ The disposable reference app includes proposal-first write examples for:
|
|
|
217
542
|
Each tool creates evidence, a before/after diff, and a proposal. The source
|
|
218
543
|
database remains unchanged until approval outside MCP and guarded writeback.
|
|
219
544
|
|
|
220
|
-
For a longer local session, you can install the
|
|
545
|
+
For a longer local session, you can install the package globally:
|
|
221
546
|
|
|
222
547
|
```bash
|
|
223
|
-
npm install -g @synapsor/runner
|
|
548
|
+
npm install -g @synapsor/runner
|
|
224
549
|
```
|
|
225
550
|
|
|
551
|
+
## Stable Compatibility Promise
|
|
552
|
+
|
|
553
|
+
Starting with `0.1.0`, Synapsor Runner keeps the documented `synapsor-runner`
|
|
554
|
+
binary, `synapsor.runner.json` schema version `1`, result envelope v2, stdio
|
|
555
|
+
MCP, Streamable HTTP MCP, MCP client snippets, proposal/approval/writeback
|
|
556
|
+
inspection commands, direct SQL writeback contract, and app-owned executor
|
|
557
|
+
contract compatible through the `0.1.x` line unless a release note marks a
|
|
558
|
+
deprecation first.
|
|
559
|
+
|
|
560
|
+
Stable does not mean production SLA, hosted Cloud features, compliance
|
|
561
|
+
certification, physical Postgres/MySQL branching, generic SQL writeback, or
|
|
562
|
+
support for undocumented local SQLite internals.
|
|
563
|
+
|
|
226
564
|
## Runtime Flow
|
|
227
565
|
|
|
228
566
|
The local runner keeps the model-facing tool call separate from approval and
|
|
@@ -307,6 +645,8 @@ relying on `latest`:
|
|
|
307
645
|
|
|
308
646
|
```bash
|
|
309
647
|
synapsor-runner activity search --tenant acme --object invoice:INV-3001
|
|
648
|
+
synapsor-runner events tail --store ./.synapsor/local.db
|
|
649
|
+
synapsor-runner events webhook --url http://127.0.0.1:8788/synapsor/events --kind proposal_created --store ./.synapsor/local.db
|
|
310
650
|
synapsor-runner proposals list --tenant acme --object invoice:INV-3001 --status approved
|
|
311
651
|
synapsor-runner evidence show ev_...
|
|
312
652
|
synapsor-runner query-audit list --evidence ev_...
|
|
@@ -332,16 +672,24 @@ Create a redacted local diagnostic report:
|
|
|
332
672
|
|
|
333
673
|
```bash
|
|
334
674
|
synapsor-runner doctor --config synapsor.runner.json --report --redact --output synapsor-doctor.md
|
|
675
|
+
synapsor-runner doctor --config synapsor.runner.json --check-writeback
|
|
335
676
|
```
|
|
336
677
|
|
|
337
678
|
Inspect or compact the local ledger:
|
|
338
679
|
|
|
339
680
|
```bash
|
|
340
681
|
synapsor-runner store stats --store ./.synapsor/local.db
|
|
682
|
+
synapsor-runner events tail --store ./.synapsor/local.db --follow
|
|
683
|
+
synapsor-runner events webhook --url-env SYNAPSOR_EVENT_WEBHOOK_URL --auth-token-env SYNAPSOR_EVENT_WEBHOOK_TOKEN --follow --store ./.synapsor/local.db
|
|
341
684
|
synapsor-runner store vacuum --store ./.synapsor/local.db
|
|
342
685
|
synapsor-runner store prune --store ./.synapsor/local.db --older-than 30d --dry-run
|
|
686
|
+
synapsor-runner store reset --store ./.synapsor/local.db --yes
|
|
343
687
|
```
|
|
344
688
|
|
|
689
|
+
`events webhook` is a local/dev/staging convenience for review UIs, Slack
|
|
690
|
+
bridges, or app-local notifications. It POSTs one redacted local event envelope
|
|
691
|
+
per lifecycle event; it is not a hosted central ledger.
|
|
692
|
+
|
|
345
693
|
This is local indexed search for local/dev/staging usage. It is not external
|
|
346
694
|
database time travel, not cross-runner search, and not hosted compliance
|
|
347
695
|
retention.
|
|
@@ -353,6 +701,24 @@ your application service already owns business writes, configure an
|
|
|
353
701
|
`http_handler` or `command_handler` executor. Approval still happens outside
|
|
354
702
|
MCP, and the handler returns an applied/conflict/failed receipt for replay.
|
|
355
703
|
|
|
704
|
+
> **Important:** your app handler owns the final business write. Runner creates
|
|
705
|
+
> the proposal and calls your handler only after approval, but your handler must
|
|
706
|
+
> still enforce tenant/scope checks, expected-version or conflict guards,
|
|
707
|
+
> idempotency keys, allowed business actions, transaction/rollback, and safe
|
|
708
|
+
> error receipts. If you skip those checks, you can reintroduce cross-tenant
|
|
709
|
+
> writes, lost updates, or duplicate writes. Keep handler credentials out of MCP.
|
|
710
|
+
|
|
711
|
+
Starter handlers are included under `examples/app-owned-writeback`.
|
|
712
|
+
The packaged app-owned billing example also includes a bundled
|
|
713
|
+
`synapsor-handler.mjs` helper shim. There is no separate handler package to
|
|
714
|
+
install.
|
|
715
|
+
You can also generate a starter handler directly:
|
|
716
|
+
|
|
717
|
+
```bash
|
|
718
|
+
npx -y -p @synapsor/runner synapsor-runner handler template node-fastify \
|
|
719
|
+
--output ./synapsor-writeback-handler.mjs
|
|
720
|
+
```
|
|
721
|
+
|
|
356
722
|
For direct SQL writeback, set the writer env var named by the source
|
|
357
723
|
`write_url_env`, for example `SYNAPSOR_DATABASE_WRITE_URL`. Runner also creates
|
|
358
724
|
or writes `synapsor_writeback_receipts` for idempotency/replay, so the writer
|
|
@@ -372,4 +738,4 @@ Synapsor DBMS, not a physical branch engine for Postgres/MySQL, and not a
|
|
|
372
738
|
general MCP security platform.
|
|
373
739
|
|
|
374
740
|
See the full repository README and docs for Docker demos, MCP client setup,
|
|
375
|
-
configuration recipes, and
|
|
741
|
+
configuration recipes, security boundaries, and release notes.
|
package/dist/cli.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { type DbRowReader } from "@synapsor-runner/mcp-server";
|
|
2
3
|
import { type WritebackJob } from "@synapsor-runner/protocol";
|
|
3
4
|
import { type SchemaInspection } from "@synapsor-runner/schema-inspector";
|
|
4
5
|
export declare function main(argv: string[]): Promise<number>;
|
|
@@ -7,6 +8,7 @@ export declare function runInitWizard(args: string[], options?: {
|
|
|
7
8
|
ask?: WizardAsk;
|
|
8
9
|
env?: NodeJS.ProcessEnv;
|
|
9
10
|
inspection?: SchemaInspection;
|
|
11
|
+
readRow?: DbRowReader;
|
|
10
12
|
stdout?: Pick<NodeJS.WriteStream, "write">;
|
|
11
13
|
}): Promise<number>;
|
|
12
14
|
export declare function resolveSqlWriteDatabaseUrl(job: WritebackJob, configPath: string, env: NodeJS.ProcessEnv): Promise<string>;
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAYA,OAAO,EAAqG,KAAK,WAAW,EAA2F,MAAM,6BAA6B,CAAC;AAmB3P,OAAO,EAA6G,KAAK,YAAY,EAAwB,MAAM,2BAA2B,CAAC;AAC/L,OAAO,EAOL,KAAK,gBAAgB,EAEtB,MAAM,mCAAmC,CAAC;AA4U3C,wBAAsB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAmD1D;AA+DD,KAAK,SAAS,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAE9E,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,GAAE;IACP,GAAG,CAAC,EAAE,SAAS,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;CACvC,GACL,OAAO,CAAC,MAAM,CAAC,CA2TjB;AAo7DD,wBAAsB,0BAA0B,CAAC,GAAG,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAM/H"}
|