@synapsor/runner 0.1.0-alpha.1 → 0.1.0-alpha.10

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.
Files changed (44) hide show
  1. package/README.md +387 -19
  2. package/TRADEMARKS.md +23 -0
  3. package/dist/cli.d.ts +4 -0
  4. package/dist/cli.d.ts.map +1 -1
  5. package/dist/cli.js +20 -8723
  6. package/dist/runner.mjs +12759 -0
  7. package/docs/README.md +36 -0
  8. package/docs/getting-started-own-database.md +460 -0
  9. package/docs/http-mcp.md +242 -0
  10. package/docs/limitations.md +95 -0
  11. package/docs/local-mode.md +351 -0
  12. package/docs/mcp-audit.md +152 -0
  13. package/docs/mcp-client-setup.md +231 -0
  14. package/docs/recipes.md +61 -0
  15. package/docs/release-notes.md +129 -0
  16. package/docs/security-boundary.md +94 -0
  17. package/docs/troubleshooting-first-run.md +248 -0
  18. package/docs/writeback-executors.md +209 -0
  19. package/examples/app-owned-writeback/README.md +120 -0
  20. package/examples/app-owned-writeback/business-actions.md +221 -0
  21. package/examples/app-owned-writeback/command-handler.mjs +46 -0
  22. package/examples/app-owned-writeback/node-fastify-handler.mjs +55 -0
  23. package/examples/app-owned-writeback/python-fastapi-handler.py +57 -0
  24. package/examples/dangerous-mcp-tools.json +88 -0
  25. package/examples/openai-agents-http/README.md +56 -0
  26. package/examples/openai-agents-http/agent.py +54 -0
  27. package/examples/openai-agents-http/requirements.txt +1 -0
  28. package/examples/openai-agents-stdio/README.md +62 -0
  29. package/examples/openai-agents-stdio/agent.py +70 -0
  30. package/examples/openai-agents-stdio/requirements.txt +1 -0
  31. package/examples/reference-support-billing-app/README.md +137 -0
  32. package/examples/reference-support-billing-app/docker-compose.yml +13 -0
  33. package/examples/reference-support-billing-app/mcp-client.generic.json +11 -0
  34. package/examples/reference-support-billing-app/schema.sql +68 -0
  35. package/examples/reference-support-billing-app/scripts/run-demo.sh +7 -0
  36. package/examples/reference-support-billing-app/seed.sql +33 -0
  37. package/examples/reference-support-billing-app/synapsor.runner.json +241 -0
  38. package/package.json +12 -4
  39. package/recipes/accounts.trial_extension.json +42 -0
  40. package/recipes/billing.late_fee_waiver.json +46 -0
  41. package/recipes/credits.account_credit.json +45 -0
  42. package/recipes/orders.refund_review.json +57 -0
  43. package/recipes/support.ticket_resolution.json +51 -0
  44. package/dist/bin.cjs +0 -13
@@ -0,0 +1,242 @@
1
+ # HTTP MCP
2
+
3
+ Use HTTP MCP when an app, server-side agent, container, or Python/Node process
4
+ needs to connect to a long-running Synapsor Runner service.
5
+
6
+ Use stdio MCP when a local MCP client such as Claude Desktop, Cursor, or a
7
+ local agent tool can launch Synapsor Runner directly.
8
+
9
+ Synapsor Runner has two HTTP modes:
10
+
11
+ - `mcp serve-streamable-http`: spec-compatible MCP Streamable HTTP. Use this
12
+ when an MCP SDK/client expects `initialize`, session IDs, POST/GET/DELETE, and
13
+ standard HTTP MCP behavior.
14
+ - `mcp serve-http`: a lightweight authenticated JSON-RPC bridge for
15
+ `tools/list`, `tools/call`, and `resources/read`. Use this when your app wants
16
+ simple POST calls or an explicit wrapper around Runner tools.
17
+
18
+ ## Start Standard Streamable HTTP MCP
19
+
20
+ ```bash
21
+ export SYNAPSOR_RUNNER_HTTP_TOKEN="dev-local-token"
22
+
23
+ synapsor-runner mcp serve-streamable-http \
24
+ --host 127.0.0.1 \
25
+ --port 8766 \
26
+ --config ./synapsor.runner.json \
27
+ --store ./.synapsor/local.db \
28
+ --auth-token-env SYNAPSOR_RUNNER_HTTP_TOKEN
29
+ ```
30
+
31
+ Defaults:
32
+
33
+ ```text
34
+ host: 127.0.0.1
35
+ port: 8766
36
+ auth: bearer token required
37
+ cors: disabled
38
+ sessions: in-memory
39
+ ```
40
+
41
+ Use `/mcp` as the MCP endpoint. Health is available at `/healthz`.
42
+
43
+ ## Start The JSON-RPC Bridge
44
+
45
+ ```bash
46
+ export SYNAPSOR_RUNNER_HTTP_TOKEN="dev-local-token"
47
+
48
+ synapsor-runner mcp serve-http \
49
+ --host 127.0.0.1 \
50
+ --port 8765 \
51
+ --config ./synapsor.runner.json \
52
+ --store ./.synapsor/local.db \
53
+ --auth-token-env SYNAPSOR_RUNNER_HTTP_TOKEN
54
+ ```
55
+
56
+ Defaults:
57
+
58
+ ```text
59
+ host: 127.0.0.1
60
+ port: 8765
61
+ auth: bearer token required
62
+ cors: disabled
63
+ ```
64
+
65
+ Bridge scope: `serve-http` does not implement MCP Streamable HTTP
66
+ `initialize`/session behavior. Standard SDK HTTP MCP clients should use
67
+ `serve-streamable-http` instead.
68
+
69
+ Startup output prints the URL, config path, store path, and token environment
70
+ variable name. It does not print token values or database URLs.
71
+
72
+ ## Health Check
73
+
74
+ ```bash
75
+ curl -i http://127.0.0.1:8766/healthz
76
+ curl -i http://127.0.0.1:8765/healthz
77
+ ```
78
+
79
+ The health endpoint is secret-free:
80
+
81
+ ```json
82
+ {
83
+ "ok": true,
84
+ "transport": "streamable-http",
85
+ "tools": 1,
86
+ "mode": "read_only"
87
+ }
88
+ ```
89
+
90
+ ## List Tools Through The JSON-RPC Bridge
91
+
92
+ Unauthorized requests fail:
93
+
94
+ ```bash
95
+ curl -i \
96
+ -H "Content-Type: application/json" \
97
+ -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' \
98
+ http://127.0.0.1:8765/mcp
99
+ ```
100
+
101
+ Authorized requests include the bearer token:
102
+
103
+ ```bash
104
+ curl -i \
105
+ -H "Authorization: Bearer dev-local-token" \
106
+ -H "Content-Type: application/json" \
107
+ -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' \
108
+ http://127.0.0.1:8765/mcp
109
+ ```
110
+
111
+ The tool catalog should contain semantic tools such as:
112
+
113
+ ```text
114
+ billing.inspect_invoice
115
+ billing.propose_late_fee_waiver
116
+ ```
117
+
118
+ It should not contain:
119
+
120
+ ```text
121
+ execute_sql
122
+ raw_sql
123
+ approval tools
124
+ commit/apply tools
125
+ database URLs
126
+ write credentials
127
+ model-controlled tenant authority
128
+ arbitrary table or column names
129
+ ```
130
+
131
+ ## Call A Tool Through The JSON-RPC Bridge
132
+
133
+ ```bash
134
+ curl -i \
135
+ -H "Authorization: Bearer dev-local-token" \
136
+ -H "Content-Type: application/json" \
137
+ -d '{
138
+ "jsonrpc": "2.0",
139
+ "id": 2,
140
+ "method": "tools/call",
141
+ "params": {
142
+ "name": "billing.inspect_invoice",
143
+ "arguments": { "invoice_id": "INV-3001" }
144
+ }
145
+ }' \
146
+ http://127.0.0.1:8765/mcp
147
+ ```
148
+
149
+ The response includes scoped data, trusted context, evidence handles, and
150
+ `source_database_mutated: false`. The agent still does not receive SQL,
151
+ database credentials, or approval/commit authority.
152
+
153
+ ## Read Evidence Or Replay Resources Through The JSON-RPC Bridge
154
+
155
+ Use `resources/read` with a `synapsor://...` handle returned by a tool call:
156
+
157
+ ```bash
158
+ curl -i \
159
+ -H "Authorization: Bearer dev-local-token" \
160
+ -H "Content-Type: application/json" \
161
+ -d '{
162
+ "jsonrpc": "2.0",
163
+ "id": 3,
164
+ "method": "resources/read",
165
+ "params": { "uri": "synapsor://evidence/ev_..." }
166
+ }' \
167
+ http://127.0.0.1:8765/mcp
168
+ ```
169
+
170
+ ## CORS
171
+
172
+ CORS is disabled by default. If a local browser app needs access during
173
+ development, allow one explicit origin:
174
+
175
+ ```bash
176
+ synapsor-runner mcp serve-http \
177
+ --config ./synapsor.runner.json \
178
+ --store ./.synapsor/local.db \
179
+ --cors-origin http://localhost:3000
180
+ ```
181
+
182
+ Do not use wildcard CORS for a model-facing database tool service.
183
+
184
+ ## Network Exposure
185
+
186
+ Synapsor Runner binds to `127.0.0.1` by default.
187
+
188
+ If you explicitly bind to all interfaces:
189
+
190
+ ```bash
191
+ synapsor-runner mcp serve-http --host 0.0.0.0
192
+ ```
193
+
194
+ the CLI prints a warning. Treat this as a production-like service:
195
+
196
+ - keep bearer auth enabled;
197
+ - use TLS or a trusted reverse proxy;
198
+ - prefer private networking;
199
+ - add rate limits and request-size limits at the edge;
200
+ - do not log request bodies by default;
201
+ - rotate the bearer token if it is exposed.
202
+
203
+ `--dev-no-auth` is accepted only on `localhost` or `127.0.0.1`. It fails closed
204
+ with `--host 0.0.0.0`.
205
+
206
+ ## Trusted Context
207
+
208
+ Tenant and principal values must come from trusted configuration such as
209
+ environment variables or a server-side session. HTTP request arguments cannot
210
+ override trusted fields such as:
211
+
212
+ ```text
213
+ tenant_id
214
+ principal
215
+ principal_id
216
+ project_id
217
+ source_id
218
+ allowed_columns
219
+ approval_identity
220
+ ```
221
+
222
+ Use `read_only` mode first. Proposal/review mode should use a separate trusted
223
+ write path and a separate write credential. The model-facing HTTP MCP endpoint
224
+ must not receive write credentials.
225
+
226
+ ## OpenAI Agents SDK
227
+
228
+ See:
229
+
230
+ ```text
231
+ examples/openai-agents-http/
232
+ examples/openai-agents-stdio/
233
+ ```
234
+
235
+ Both examples use the MCP client integration from the OpenAI Agents SDK when it
236
+ is available. The stdio example launches Runner as a child process. The HTTP
237
+ example connects to `synapsor-runner mcp serve-streamable-http` through
238
+ `MCPServerStreamableHttp`. Use the JSON-RPC bridge only when you intentionally
239
+ want a small app-owned wrapper instead of standard HTTP MCP.
240
+
241
+ The boundary is the same in both modes: the agent calls a semantic Synapsor
242
+ tool, not raw SQL.
@@ -0,0 +1,95 @@
1
+ # Limitations
2
+
3
+ Synapsor Runner is intentionally narrow in the current alpha.
4
+
5
+ ## Supported
6
+
7
+ - Stdio MCP server for semantic database capabilities.
8
+ - Local read and proposal tools.
9
+ - Local SQLite evidence/proposal/query-audit/replay store.
10
+ - Human approval through CLI commands.
11
+ - Public protocol objects:
12
+ - `synapsor.change-set.v1`
13
+ - `synapsor.writeback-job.v1`
14
+ - `synapsor.execution-receipt.v1`
15
+ - `synapsor.runner-registration.v1`
16
+ - Guarded single-row `UPDATE` for Postgres and MySQL.
17
+ - App/API handler writeback through approved `http_handler` executors.
18
+ - Local script writeback through approved `command_handler` executors.
19
+ - Primary-key guard.
20
+ - Tenant guard.
21
+ - Allowed-column validation.
22
+ - Version-column or explicit weak row-hash conflict guard.
23
+ - Idempotency receipts.
24
+ - Named local trusted contexts for capability configs.
25
+ - Capability recipes that generate reviewed starter configs.
26
+ - Shadow-mode proposal-vs-human-action comparison.
27
+ - Static MCP database risk review.
28
+ - Local indexed search for proposals, evidence bundles, query audit, writeback
29
+ receipts, and proposal replay.
30
+
31
+ ## Runtime Contract
32
+
33
+ Local capabilities are config-defined, not built into the server. The runtime
34
+ does not special-case billing, support, orders, refunds, invoices, or tickets.
35
+ Those domains appear only in demos, smoke tests, and optional recipe JSON files.
36
+ When you connect your own database, `synapsor.runner.json` is the source of
37
+ truth for the model-facing tools.
38
+
39
+ ## Not Supported
40
+
41
+ - Arbitrary SQL.
42
+ - Model-generated SQL.
43
+ - DDL.
44
+ - INSERT.
45
+ - DELETE.
46
+ - UPSERT.
47
+ - Multi-row UPDATE.
48
+ - Stored procedures.
49
+ - Cross-database transactions.
50
+ - Physical branching of Postgres/MySQL.
51
+ - Full Synapsor workflow/DAG execution.
52
+ - `CREATE AGENT WORKFLOW` or hosted Synapsor SQL generation.
53
+ - Auto-merge or settlement policy semantics.
54
+ - Automatic rollback of external database writes.
55
+ - Model-callable approval or commit tools.
56
+ - Generic MCP firewall behavior.
57
+ - Prompt-injection prevention.
58
+ - High availability, SLA, compliance certification, or production support guarantee.
59
+
60
+ ## Important External Database Semantics
61
+
62
+ External Postgres/MySQL databases are not branched or merged by Synapsor Runner.
63
+
64
+ The proposal, evidence, replay, and approval state live in Synapsor Runner locally or in Synapsor Cloud. The external source database changes only when a trusted runner applies an approved writeback job.
65
+
66
+ Local replay means replay of records captured by the runner:
67
+
68
+ - trusted context values used by the capability;
69
+ - captured/projected source-row excerpts;
70
+ - query audit fingerprints and redacted parameter metadata;
71
+ - proposal before/proposed diffs;
72
+ - approval/rejection events;
73
+ - guarded writeback jobs;
74
+ - applied/conflict/failed receipts.
75
+
76
+ It does not mean external Postgres/MySQL time travel. Runner cannot reconstruct
77
+ arbitrary historical rows that were never captured as evidence, and it does not
78
+ provide `AS OF` queries over an external source.
79
+
80
+ Local search is single-node SQLite search over the local runner store. It is
81
+ useful for local/dev/staging usage. It is not a hosted central evidence ledger,
82
+ not cross-runner aggregation, not RBAC/SSO, and not compliance retention.
83
+
84
+ Use this wording:
85
+
86
+ ```text
87
+ External DB = Synapsor review state + trusted writeback
88
+ Synapsor-native = real branch + merge
89
+ ```
90
+
91
+ Do not describe external approval as merge.
92
+
93
+ ## Weak Conflict Guards
94
+
95
+ A version/timestamp column is the preferred conflict guard. A weak row-hash guard can be acknowledged for local/dev use, but it should not be presented as equivalent to a durable version column.
@@ -0,0 +1,351 @@
1
+ # Local mode
2
+
3
+ Local mode runs Synapsor Runner inside the developer or customer environment. No Synapsor Cloud account is required for local review flows.
4
+
5
+ Command model:
6
+
7
+ - `./scripts/demo-docker.sh` runs the no-install Docker demo.
8
+ - `synapsor <command>` is the public CLI surface.
9
+ - From a source checkout, use `./bin/synapsor-runner <command>` if the global binary is
10
+ not linked yet.
11
+
12
+ `synapsor-runner demo --quick` creates a fixture ledger for learning and CLI
13
+ verification. In a terminal it walks through the safety model step by step; in
14
+ CI or piped output it prints a short summary and exits without waiting for
15
+ Enter. It does not read or write external Postgres/MySQL. Local mode with
16
+ `synapsor-runner mcp serve`, `synapsor-runner demo`, or an own generated config is the real
17
+ Postgres/MySQL path. Use `synapsor-runner demo inspect` to print the follow-up
18
+ commands for the quick-demo fixture.
19
+
20
+ Current local-mode foundation:
21
+
22
+ - strict JSON capability config validation in `packages/config`;
23
+ - local SQLite proposal/event/evidence/query-audit/writeback/replay store in `packages/proposal-store`;
24
+ - local proposal review CLI in `apps/runner`;
25
+ - local localhost proposal review UI through `synapsor-runner ui`;
26
+ - static MCP database risk review with `synapsor-runner audit`;
27
+ - local stdio MCP server with semantic read/proposal tools;
28
+ - authenticated HTTP MCP server for app/server agents;
29
+ - MCP resource reads for `synapsor://proposals/*`, `synapsor://evidence/*`, and `synapsor://replay/*`;
30
+ - local approved proposal to `synapsor.writeback-job.v1` job generation;
31
+ - guarded Postgres/MySQL writeback adapters for approved structured jobs.
32
+
33
+ Still pending:
34
+
35
+ The alpha package requires Node >= 22.5.0 because the local evidence/replay
36
+ ledger uses Node's `node:sqlite` runtime. The published package declares that
37
+ engine requirement and the CLI exits early with a clear message on older Node
38
+ versions. The Docker-backed demo remains the recommended path when you do not
39
+ want to change your host Node version.
40
+
41
+ ## Initialize a config
42
+
43
+ Create a starter config without putting credentials in the file:
44
+
45
+ ```bash
46
+ npx -y -p @synapsor/runner@alpha synapsor-runner init --engine postgres --mode review
47
+ ```
48
+
49
+ For MySQL:
50
+
51
+ ```bash
52
+ npx -y -p @synapsor/runner@alpha synapsor-runner init --engine mysql --mode review --output synapsor.mysql.runner.json
53
+ ```
54
+
55
+ The generated config uses environment-variable names for read/write URLs and trusted context. Edit the table, column, and capability names before serving tools.
56
+
57
+ Do not include credential-bearing columns in reviewed visible fields or
58
+ evidence. The local store rejects obvious database URLs, bearer tokens, runner
59
+ tokens, private-key blocks, and secret-like field names before they can be
60
+ persisted into proposals, evidence, query audit, runner state, or replay.
61
+
62
+ For a reviewed own-database setup generated from explicit selections, use:
63
+
64
+ ```bash
65
+ npx -y -p @synapsor/runner@alpha synapsor-runner init --spec onboarding-selection.json --non-interactive
66
+ npx -y -p @synapsor/runner@alpha synapsor-runner doctor --config synapsor.runner.json
67
+ ```
68
+
69
+ `doctor --config` checks config validation, required environment variables,
70
+ read/write credential separation, metadata visibility for configured targets,
71
+ and the semantic MCP tool boundary without printing credential values.
72
+
73
+ ## Stdio Vs HTTP MCP
74
+
75
+ Use stdio for local MCP clients that launch Synapsor Runner:
76
+
77
+ ```bash
78
+ npx -y -p @synapsor/runner@alpha synapsor-runner mcp serve \
79
+ --config ./synapsor.runner.json \
80
+ --store ./.synapsor/local.db
81
+ ```
82
+
83
+ Use Streamable HTTP when your app/server agent connects through a standard HTTP
84
+ MCP client:
85
+
86
+ ```bash
87
+ export SYNAPSOR_RUNNER_HTTP_TOKEN="dev-local-token"
88
+
89
+ npx -y -p @synapsor/runner@alpha synapsor-runner mcp serve-streamable-http \
90
+ --config ./synapsor.runner.json \
91
+ --store ./.synapsor/local.db \
92
+ --auth-token-env SYNAPSOR_RUNNER_HTTP_TOKEN
93
+ ```
94
+
95
+ Streamable HTTP defaults to `127.0.0.1:8766`, requires bearer auth by default,
96
+ and should run behind private networking/TLS before production-like exposure.
97
+ Use `synapsor-runner mcp serve-http` only when you explicitly want the smaller
98
+ JSON-RPC bridge. Details: [HTTP MCP](http-mcp.md).
99
+
100
+ ## Local safety modes
101
+
102
+ The local runner modes are intentionally narrow:
103
+
104
+ - `read_only`: exposes read tools only; proposal tools fail closed.
105
+ - `shadow`: lets proposal tools create local proposals, evidence, query audit, and replay records, but approval and writeback-job creation are disabled.
106
+ - `review`: lets proposal tools create local proposals, then a human/operator can approve and create a guarded writeback job.
107
+ - `cloud`: delegates reviewed tools to Synapsor Cloud through a runner token.
108
+
109
+ Use `shadow` when you want to test the shape of proposals without any path to mutate the source database. Use `review` only when you are ready to exercise the trusted writeback worker.
110
+
111
+ ## Store path
112
+
113
+ Commands use `--store` or `SYNAPSOR_LOCAL_STORE`.
114
+
115
+ ```bash
116
+ export SYNAPSOR_LOCAL_STORE="./.synapsor/local.db"
117
+ ```
118
+
119
+ If neither is set, the CLI uses:
120
+
121
+ ```text
122
+ ./.synapsor/local.db
123
+ ```
124
+
125
+ ## Proposal review
126
+
127
+ List proposals:
128
+
129
+ ```bash
130
+ npx -y -p @synapsor/runner@alpha synapsor-runner proposals list --store ./.synapsor/local.db
131
+ ```
132
+
133
+ Show a proposal:
134
+
135
+ ```bash
136
+ npx -y -p @synapsor/runner@alpha synapsor-runner proposals show wrp_123 --store ./.synapsor/local.db
137
+ ```
138
+
139
+ Approve:
140
+
141
+ ```bash
142
+ npx -y -p @synapsor/runner@alpha synapsor-runner proposals approve wrp_123 \
143
+ --store ./.synapsor/local.db \
144
+ --actor local_reviewer \
145
+ --yes
146
+ ```
147
+
148
+ Before approval, the CLI prints the reviewer-critical proposal details: trusted principal, tenant, target row, primary key, required role, proposal hash/version, allowed columns, conflict guard, evidence bundle/query fingerprint, writeback boundary, source mutation state, and exact before/after diff. Interactive approval still requires typing `yes`; noninteractive scripts must pass `--yes`.
149
+
150
+ Create a guarded writeback job from an approved proposal:
151
+
152
+ ```bash
153
+ npx -y -p @synapsor/runner@alpha synapsor-runner proposals writeback-job wrp_123 \
154
+ --store ./.synapsor/local.db \
155
+ --project local \
156
+ --runner local_runner \
157
+ --output job.json
158
+ ```
159
+
160
+ The generated job uses the public `synapsor.writeback-job.v1` protocol and can be applied by the guarded worker:
161
+
162
+ ```bash
163
+ export SYNAPSOR_DATABASE_WRITE_URL="postgresql://writer:<password>@localhost:5432/app"
164
+ SYNAPSOR_ENGINE=postgres \
165
+ npx -y -p @synapsor/runner@alpha synapsor-runner apply --job job.json --config synapsor.runner.json --store ./.synapsor/local.db
166
+ ```
167
+
168
+ When `--config` is passed, direct SQL writeback reads the writer connection from
169
+ the source `write_url_env` in that config. `SYNAPSOR_DATABASE_URL` is only a
170
+ legacy fallback for direct worker flows without a local runner config.
171
+
172
+ Passing `--store` records the terminal `synapsor.execution-receipt.v1` locally. Replay then links the proposal, approval, writeback job, applied/conflict/failed receipt, evidence, and query audit.
173
+
174
+ Reject:
175
+
176
+ ```bash
177
+ npx -y -p @synapsor/runner@alpha synapsor-runner proposals reject wrp_123 \
178
+ --store ./.synapsor/local.db \
179
+ --reason "policy evidence is incomplete" \
180
+ --yes
181
+ ```
182
+
183
+ `approve` and `reject` require either interactive confirmation or explicit `--yes`.
184
+
185
+ Approval records the approver against the exact proposal hash/version. The proposal patch is immutable after creation.
186
+
187
+ Shadow-mode proposals are inspectable through `proposals show` and `replay show`, but `proposals approve` and `proposals writeback-job` reject them. Shadow mode never mutates Postgres/MySQL.
188
+
189
+ ## Browser review UI
190
+
191
+ Start a localhost-only review UI:
192
+
193
+ ```bash
194
+ npx -y -p @synapsor/runner@alpha synapsor-runner ui --config synapsor.runner.json --store ./.synapsor/local.db
195
+ ```
196
+
197
+ The UI shows setup summary, semantic tools, proposal states, exact diffs,
198
+ evidence, approval state, receipts, and replay. It binds to `127.0.0.1` by
199
+ default, uses a per-run local session token, and requires CSRF protection for
200
+ approve/reject actions.
201
+
202
+ The UI does not expose raw SQL, database URLs, password values, MCP approval
203
+ tools, MCP commit tools, or controls that widen configured tables/columns.
204
+
205
+ ## Replay
206
+
207
+ Show replay:
208
+
209
+ ```bash
210
+ npx -y -p @synapsor/runner@alpha synapsor-runner replay show wrp_123 --store ./.synapsor/local.db
211
+ npx -y -p @synapsor/runner@alpha synapsor-runner replay show --proposal wrp_123 --store ./.synapsor/local.db
212
+ npx -y -p @synapsor/runner@alpha synapsor-runner replay show --replay replay_wrp_123 --store ./.synapsor/local.db
213
+ npx -y -p @synapsor/runner@alpha synapsor-runner replay show --evidence ev_123 --store ./.synapsor/local.db
214
+ ```
215
+
216
+ Export replay:
217
+
218
+ ```bash
219
+ npx -y -p @synapsor/runner@alpha synapsor-runner replay export wrp_123 \
220
+ --store ./.synapsor/local.db \
221
+ --output replay.json
222
+
223
+ npx -y -p @synapsor/runner@alpha synapsor-runner replay export --proposal wrp_123 \
224
+ --format markdown \
225
+ --store ./.synapsor/local.db \
226
+ --output replay.md
227
+ ```
228
+
229
+ Replay records include proposal metadata, before/after diff, events, writeback receipts, evidence summaries, and query audit rows currently stored for the proposal.
230
+ Human output is concise by default. Use `--details` for reviewer metadata or
231
+ `--json` for complete machine-readable records.
232
+
233
+ ## Local evidence, query audit, and receipts
234
+
235
+ The local SQLite store is also searchable without relying on `latest`:
236
+
237
+ ```bash
238
+ synapsor-runner activity search \
239
+ --tenant acme \
240
+ --object invoice:INV-3001 \
241
+ --store ./.synapsor/local.db
242
+
243
+ synapsor-runner evidence list \
244
+ --tenant acme \
245
+ --capability billing.inspect_invoice \
246
+ --source app_postgres \
247
+ --table invoices \
248
+ --store ./.synapsor/local.db
249
+
250
+ synapsor-runner evidence show ev_123 --store ./.synapsor/local.db
251
+ synapsor-runner query-audit list --evidence ev_123 --store ./.synapsor/local.db
252
+ synapsor-runner receipts list --proposal wrp_123 --store ./.synapsor/local.db
253
+ synapsor-runner receipts show <receipt_id> --store ./.synapsor/local.db
254
+ ```
255
+
256
+ Default inspection output is intentionally short. Add `--details` when you need
257
+ target URIs, primary keys, proposal hash/version, conflict guards, query
258
+ fingerprints, event timestamps, or receipt internals.
259
+
260
+ Read-only MCP tools record evidence bundles and query-audit rows and return an
261
+ evidence handle. Use `evidence show`, `evidence list`, and `query-audit list`
262
+ to inspect those captured rows and fingerprints later without rerunning the
263
+ external database read.
264
+
265
+ This is local indexed search over the runner's SQLite ledger. It is not
266
+ external Postgres/MySQL time travel, not native branching, and not a hosted
267
+ cross-runner audit ledger.
268
+
269
+ ## Local store maintenance
270
+
271
+ The local ledger is a developer/staging SQLite file. You can inspect, compact,
272
+ or prune it without touching your source Postgres/MySQL database:
273
+
274
+ ```bash
275
+ synapsor-runner store stats --store ./.synapsor/local.db
276
+ synapsor-runner store vacuum --store ./.synapsor/local.db
277
+ synapsor-runner store prune --store ./.synapsor/local.db --older-than 30d --dry-run
278
+ synapsor-runner store prune --store ./.synapsor/local.db --older-than 30d --yes
279
+ ```
280
+
281
+ `store prune` defaults to dry-run. Use `--yes` only after reviewing the row
282
+ counts it will remove.
283
+
284
+ ## Boundary
285
+
286
+ Local mode does not expose `approve_proposal` or `commit_proposal` as model-callable MCP tools. The intended flow is:
287
+
288
+ ```text
289
+ MCP tool call
290
+ -> reviewed semantic proposal
291
+ -> local store
292
+ -> human/operator approval outside the model
293
+ -> guarded worker writeback
294
+ -> terminal receipt
295
+ -> replay
296
+ ```
297
+
298
+ The external Postgres/MySQL database is not physically branched. It remains unchanged until a trusted runner applies an approved writeback job.
299
+
300
+ ## Local MCP smoke
301
+
302
+ The repository includes a one-command Docker-only local demo:
303
+
304
+ ```bash
305
+ ./scripts/demo-docker.sh
306
+ ```
307
+
308
+ This path requires Docker only. It builds the runner image locally, starts disposable Postgres/MySQL fixtures, runs the stdio MCP proof, and tears down the disposable resources. No Synapsor Cloud account, API key, hosted workspace, or host Node/Corepack setup is required.
309
+
310
+ If you already have Node/Corepack installed for contributor work, the direct wrapper is also available:
311
+
312
+ ```bash
313
+ ./scripts/demo-local.sh
314
+ corepack pnpm demo:local
315
+ ```
316
+
317
+ The Docker-only script is also available through pnpm after dependencies are installed:
318
+
319
+ ```bash
320
+ corepack pnpm demo:docker
321
+ ```
322
+
323
+ The contributor script checks Docker/Corepack, installs dependencies if needed, starts disposable Postgres/MySQL containers, and runs the stdio MCP proof flow.
324
+
325
+ For CI or direct verification, use:
326
+
327
+ ```bash
328
+ corepack pnpm test:mcp-local
329
+ ```
330
+
331
+ It launches the official MCP stdio client transport against `synapsor-runner mcp serve`, exercises the Postgres billing, Postgres support, and MySQL orders examples, checks that source rows are unchanged before approval, approves locally, generates versioned writeback jobs, applies them, retries idempotently, and then proves stale-row conflict:
332
+
333
+ ```text
334
+ The business state changed after the agent saw it, so Synapsor refused to commit.
335
+ ```
336
+
337
+ ## Optional MCP client configs
338
+
339
+ After the Docker demo passes, developers who want to attach an MCP client can use the checked-in stdio config shapes in:
340
+
341
+ ```text
342
+ examples/mcp-client-configs/
343
+ ```
344
+
345
+ Verify those config files without launching any client UI:
346
+
347
+ ```bash
348
+ corepack pnpm test:mcp-client-configs
349
+ ```
350
+
351
+ That command starts the runner through each config shape, calls MCP `tools/list`, and verifies that the server exposes semantic tools such as `billing.inspect_invoice` and `billing.propose_late_fee_waiver` without exposing raw SQL, approval, or commit tools. It verifies the stdio contract and config shape; it does not claim that a specific client application's UI was manually tested.