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

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 (51) hide show
  1. package/README.md +20 -14
  2. package/TRADEMARKS.md +23 -0
  3. package/dist/cli.d.ts.map +1 -1
  4. package/dist/cli.js +15 -8723
  5. package/dist/runner.mjs +8864 -0
  6. package/docs/MCP_RUNNER_IMPLEMENTATION_PLAN.md +187 -0
  7. package/docs/README.md +56 -0
  8. package/docs/architecture.md +65 -0
  9. package/docs/capability-config.md +180 -0
  10. package/docs/cloud-mode.md +140 -0
  11. package/docs/config-migrations.md +67 -0
  12. package/docs/demo-transcript.md +73 -0
  13. package/docs/dependency-license-inventory.md +35 -0
  14. package/docs/first-10-minutes.md +147 -0
  15. package/docs/getting-started-own-database.md +367 -0
  16. package/docs/licensing.md +38 -0
  17. package/docs/limitations.md +75 -0
  18. package/docs/local-mode.md +246 -0
  19. package/docs/local-ui.md +163 -0
  20. package/docs/mcp-audit.md +146 -0
  21. package/docs/mcp-client-setup.md +155 -0
  22. package/docs/mcp-efficiency-benchmark.md +84 -0
  23. package/docs/operations.md +38 -0
  24. package/docs/own-db-20-minutes.md +185 -0
  25. package/docs/production-readiness.md +39 -0
  26. package/docs/protocol.md +90 -0
  27. package/docs/recipes.md +61 -0
  28. package/docs/roadmap.md +13 -0
  29. package/docs/schema-inspection.md +88 -0
  30. package/docs/security-boundary.md +70 -0
  31. package/docs/shadow-mode.md +67 -0
  32. package/docs/telemetry.md +28 -0
  33. package/docs/threat-model.md +25 -0
  34. package/docs/troubleshooting-first-run.md +248 -0
  35. package/docs/trusted-context.md +70 -0
  36. package/docs/writeback-executors.md +128 -0
  37. package/examples/dangerous-mcp-tools.json +88 -0
  38. package/examples/reference-support-billing-app/README.md +86 -0
  39. package/examples/reference-support-billing-app/docker-compose.yml +13 -0
  40. package/examples/reference-support-billing-app/mcp-client.generic.json +11 -0
  41. package/examples/reference-support-billing-app/schema.sql +55 -0
  42. package/examples/reference-support-billing-app/scripts/run-demo.sh +7 -0
  43. package/examples/reference-support-billing-app/seed.sql +26 -0
  44. package/examples/reference-support-billing-app/synapsor.runner.json +136 -0
  45. package/package.json +10 -4
  46. package/recipes/accounts.trial_extension.json +42 -0
  47. package/recipes/billing.late_fee_waiver.json +46 -0
  48. package/recipes/credits.account_credit.json +45 -0
  49. package/recipes/orders.refund_review.json +57 -0
  50. package/recipes/support.ticket_resolution.json +51 -0
  51. package/dist/bin.cjs +0 -13
@@ -0,0 +1,38 @@
1
+ # Licensing
2
+
3
+ Synapsor Runner is open source under the Apache License 2.0 (`Apache-2.0`).
4
+
5
+ This page is a plain-English summary, not legal advice. If this summary
6
+ conflicts with `../LICENSE`, the `LICENSE` file controls.
7
+
8
+ Apache-2.0 applies to the code in this runner repository. It grants copyright
9
+ and patent rights under the license terms.
10
+
11
+ Apache-2.0 does not grant trademark rights. The Synapsor name, Synapsor Runner
12
+ name, logos, hosted Cloud service, and proprietary Synapsor platform features
13
+ remain separate. See `../TRADEMARKS.md`.
14
+
15
+ This license change applies only to `synapsor-runner`.
16
+
17
+ It does not open source:
18
+
19
+ - Synapsor Cloud;
20
+ - the hosted control plane;
21
+ - hosted capability registry;
22
+ - advanced policy/capability compiler;
23
+ - team approvals, RBAC, or SSO;
24
+ - hosted audit/evidence ledger;
25
+ - managed runners;
26
+ - production writeback orchestration;
27
+ - workflow builder;
28
+ - native Synapsor engine;
29
+ - C++/DBMS internals;
30
+ - branching, time travel, or settlement;
31
+ - compliance exports or production support/SLA.
32
+
33
+ Synapsor Cloud is a separate hosted commercial service. Use Cloud when your team
34
+ needs shared approvals, RBAC, hosted evidence/replay search, runner fleet
35
+ status, leases, retention, audit visibility, enterprise controls, and support.
36
+
37
+ Before public release, license and trademark text must be reviewed by qualified
38
+ counsel.
@@ -0,0 +1,75 @@
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
+
29
+ ## Runtime Contract
30
+
31
+ Local capabilities are config-defined, not built into the server. The runtime
32
+ does not special-case billing, support, orders, refunds, invoices, or tickets.
33
+ Those domains appear only in demos, smoke tests, and optional recipe JSON files.
34
+ When you connect your own database, `synapsor.runner.json` is the source of
35
+ truth for the model-facing tools.
36
+
37
+ ## Not Supported
38
+
39
+ - Arbitrary SQL.
40
+ - Model-generated SQL.
41
+ - DDL.
42
+ - INSERT.
43
+ - DELETE.
44
+ - UPSERT.
45
+ - Multi-row UPDATE.
46
+ - Stored procedures.
47
+ - Cross-database transactions.
48
+ - Physical branching of Postgres/MySQL.
49
+ - Full Synapsor workflow/DAG execution.
50
+ - `CREATE AGENT WORKFLOW` or hosted Synapsor SQL generation.
51
+ - Auto-merge or settlement policy semantics.
52
+ - Automatic rollback of external database writes.
53
+ - Model-callable approval or commit tools.
54
+ - Generic MCP firewall behavior.
55
+ - Prompt-injection prevention.
56
+ - High availability, SLA, compliance certification, or production support guarantee.
57
+
58
+ ## Important External Database Semantics
59
+
60
+ External Postgres/MySQL databases are not branched or merged by Synapsor Runner.
61
+
62
+ 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.
63
+
64
+ Use this wording:
65
+
66
+ ```text
67
+ External DB = Synapsor review state + trusted writeback
68
+ Synapsor-native = real branch + merge
69
+ ```
70
+
71
+ Do not describe external approval as merge.
72
+
73
+ ## Weak Conflict Guards
74
+
75
+ 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,246 @@
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 <command>` if the global binary is
10
+ not linked yet.
11
+
12
+ Current local-mode foundation:
13
+
14
+ - strict JSON capability config validation in `packages/config`;
15
+ - local SQLite proposal/event/evidence/query-audit/writeback/replay store in `packages/proposal-store`;
16
+ - local proposal review CLI in `apps/runner`;
17
+ - local localhost proposal review UI through `synapsor ui`;
18
+ - static MCP database risk review with `synapsor audit`;
19
+ - local stdio MCP server with semantic read/proposal tools;
20
+ - MCP resource reads for `synapsor://proposals/*`, `synapsor://evidence/*`, and `synapsor://replay/*`;
21
+ - local approved proposal to `synapsor.writeback-job.v1` job generation;
22
+ - guarded Postgres/MySQL writeback adapters for approved structured jobs.
23
+
24
+ Still pending:
25
+
26
+ - Public-release hardening around the experimental `node:sqlite` dependency.
27
+
28
+ ## Initialize a config
29
+
30
+ Create a starter config without putting credentials in the file:
31
+
32
+ ```bash
33
+ npx -y -p @synapsor/runner@alpha synapsor init --engine postgres --mode review
34
+ ```
35
+
36
+ For MySQL:
37
+
38
+ ```bash
39
+ npx -y -p @synapsor/runner@alpha synapsor init --engine mysql --mode review --output synapsor.mysql.runner.json
40
+ ```
41
+
42
+ The generated config uses environment-variable names for read/write URLs and trusted context. Edit the table, column, and capability names before serving tools.
43
+
44
+ Do not include credential-bearing columns in reviewed visible fields or
45
+ evidence. The local store rejects obvious database URLs, bearer tokens, runner
46
+ tokens, private-key blocks, and secret-like field names before they can be
47
+ persisted into proposals, evidence, query audit, runner state, or replay.
48
+
49
+ For a reviewed own-database setup generated from explicit selections, use:
50
+
51
+ ```bash
52
+ npx -y -p @synapsor/runner@alpha synapsor init --spec onboarding-selection.json --non-interactive
53
+ npx -y -p @synapsor/runner@alpha synapsor doctor --config synapsor.runner.json
54
+ ```
55
+
56
+ `doctor --config` checks config validation, required environment variables,
57
+ read/write credential separation, metadata visibility for configured targets,
58
+ and the semantic MCP tool boundary without printing credential values.
59
+
60
+ ## Local safety modes
61
+
62
+ The local runner modes are intentionally narrow:
63
+
64
+ - `read_only`: exposes read tools only; proposal tools fail closed.
65
+ - `shadow`: lets proposal tools create local proposals, evidence, query audit, and replay records, but approval and writeback-job creation are disabled.
66
+ - `review`: lets proposal tools create local proposals, then a human/operator can approve and create a guarded writeback job.
67
+ - `cloud`: delegates reviewed tools to Synapsor Cloud through a runner token.
68
+
69
+ 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.
70
+
71
+ ## Store path
72
+
73
+ Commands use `--store` or `SYNAPSOR_LOCAL_STORE`.
74
+
75
+ ```bash
76
+ export SYNAPSOR_LOCAL_STORE="./.synapsor/local.db"
77
+ ```
78
+
79
+ If neither is set, the CLI uses:
80
+
81
+ ```text
82
+ ./.synapsor/local.db
83
+ ```
84
+
85
+ ## Proposal review
86
+
87
+ List proposals:
88
+
89
+ ```bash
90
+ npx -y -p @synapsor/runner@alpha synapsor proposals list --store ./.synapsor/local.db
91
+ ```
92
+
93
+ Show a proposal:
94
+
95
+ ```bash
96
+ npx -y -p @synapsor/runner@alpha synapsor proposals show wrp_123 --store ./.synapsor/local.db
97
+ ```
98
+
99
+ Approve:
100
+
101
+ ```bash
102
+ npx -y -p @synapsor/runner@alpha synapsor proposals approve wrp_123 \
103
+ --store ./.synapsor/local.db \
104
+ --actor local_reviewer \
105
+ --yes
106
+ ```
107
+
108
+ 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`.
109
+
110
+ Create a guarded writeback job from an approved proposal:
111
+
112
+ ```bash
113
+ npx -y -p @synapsor/runner@alpha synapsor proposals writeback-job wrp_123 \
114
+ --store ./.synapsor/local.db \
115
+ --project local \
116
+ --runner local_runner \
117
+ --output job.json
118
+ ```
119
+
120
+ The generated job uses the public `synapsor.writeback-job.v1` protocol and can be applied by the guarded worker:
121
+
122
+ ```bash
123
+ SYNAPSOR_ENGINE=postgres \
124
+ SYNAPSOR_DATABASE_URL="postgresql://writer:<password>@localhost:5432/app" \
125
+ npx -y -p @synapsor/runner@alpha synapsor apply --job job.json --config synapsor.runner.json --store ./.synapsor/local.db
126
+ ```
127
+
128
+ 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.
129
+
130
+ Reject:
131
+
132
+ ```bash
133
+ npx -y -p @synapsor/runner@alpha synapsor proposals reject wrp_123 \
134
+ --store ./.synapsor/local.db \
135
+ --reason "policy evidence is incomplete" \
136
+ --yes
137
+ ```
138
+
139
+ `approve` and `reject` require either interactive confirmation or explicit `--yes`.
140
+
141
+ Approval records the approver against the exact proposal hash/version. The proposal patch is immutable after creation.
142
+
143
+ 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.
144
+
145
+ ## Browser review UI
146
+
147
+ Start a localhost-only review UI:
148
+
149
+ ```bash
150
+ npx -y -p @synapsor/runner@alpha synapsor ui --config synapsor.runner.json --store ./.synapsor/local.db
151
+ ```
152
+
153
+ The UI shows setup summary, semantic tools, proposal states, exact diffs,
154
+ evidence, approval state, receipts, and replay. It binds to `127.0.0.1` by
155
+ default, uses a per-run local session token, and requires CSRF protection for
156
+ approve/reject actions.
157
+
158
+ The UI does not expose raw SQL, database URLs, password values, MCP approval
159
+ tools, MCP commit tools, or controls that widen configured tables/columns.
160
+
161
+ ## Replay
162
+
163
+ Show replay:
164
+
165
+ ```bash
166
+ npx -y -p @synapsor/runner@alpha synapsor replay show wrp_123 --store ./.synapsor/local.db
167
+ ```
168
+
169
+ Export replay:
170
+
171
+ ```bash
172
+ npx -y -p @synapsor/runner@alpha synapsor replay export wrp_123 \
173
+ --store ./.synapsor/local.db \
174
+ --output replay.json
175
+ ```
176
+
177
+ Replay records include proposal metadata, before/after diff, events, writeback receipts, evidence summaries, and query audit rows currently stored for the proposal.
178
+
179
+ ## Boundary
180
+
181
+ Local mode does not expose `approve_proposal` or `commit_proposal` as model-callable MCP tools. The intended flow is:
182
+
183
+ ```text
184
+ MCP tool call
185
+ -> reviewed semantic proposal
186
+ -> local store
187
+ -> human/policy approval outside the model
188
+ -> guarded worker writeback
189
+ -> terminal receipt
190
+ -> replay
191
+ ```
192
+
193
+ The external Postgres/MySQL database is not physically branched. It remains unchanged until a trusted runner applies an approved writeback job.
194
+
195
+ ## Local MCP smoke
196
+
197
+ The repository includes a one-command Docker-only local demo:
198
+
199
+ ```bash
200
+ ./scripts/demo-docker.sh
201
+ ```
202
+
203
+ 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.
204
+
205
+ If you already have Node/Corepack installed for contributor work, the direct wrapper is also available:
206
+
207
+ ```bash
208
+ ./scripts/demo-local.sh
209
+ corepack pnpm demo:local
210
+ ```
211
+
212
+ The Docker-only script is also available through pnpm after dependencies are installed:
213
+
214
+ ```bash
215
+ corepack pnpm demo:docker
216
+ ```
217
+
218
+ The contributor script checks Docker/Corepack, installs dependencies if needed, starts disposable Postgres/MySQL containers, and runs the stdio MCP proof flow.
219
+
220
+ For CI or direct verification, use:
221
+
222
+ ```bash
223
+ corepack pnpm test:mcp-local
224
+ ```
225
+
226
+ It launches the official MCP stdio client transport against `synapsor 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:
227
+
228
+ ```text
229
+ The business state changed after the agent saw it, so Synapsor refused to commit.
230
+ ```
231
+
232
+ ## Optional MCP client configs
233
+
234
+ After the Docker demo passes, developers who want to attach an MCP client can use the checked-in stdio config shapes in:
235
+
236
+ ```text
237
+ examples/mcp-client-configs/
238
+ ```
239
+
240
+ Verify those config files without launching any client UI:
241
+
242
+ ```bash
243
+ corepack pnpm test:mcp-client-configs
244
+ ```
245
+
246
+ 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.
@@ -0,0 +1,163 @@
1
+ # Local UI
2
+
3
+ `synapsor ui` starts a lightweight browser review surface for a local Runner
4
+ store.
5
+
6
+ From a source checkout, use `./bin/synapsor ui ...` if the global binary is not
7
+ linked yet.
8
+
9
+ ```bash
10
+ npx -y -p @synapsor/runner@alpha synapsor ui --config ./synapsor.runner.json --store ./.synapsor/local.db
11
+ ```
12
+
13
+ By default it binds to localhost only and prints a per-run URL:
14
+
15
+ ```text
16
+ Synapsor Runner local UI: http://127.0.0.1:51234/?token=...
17
+ ```
18
+
19
+ Use the UI after `synapsor mcp serve` has created local proposals. The UI is a
20
+ review surface; it is not a raw SQL console and it does not serve MCP tools.
21
+
22
+ ## The Review Console
23
+
24
+ Selecting a proposal opens a **Review** tab that tells the story of what
25
+ happened, step by step, instead of leading with raw JSON:
26
+
27
+ 1. **Agent requested a change** — the semantic tool that was called and the
28
+ object it targeted (for example `billing.propose_late_fee_waiver for
29
+ INV-3001`). The model could request, but had no SQL, approve, or commit
30
+ tools.
31
+ 2. **Synapsor Runner created a proposal** — proposal id, tenant, and principal.
32
+ 3. **The proposed change** — an exact before/proposed field diff.
33
+ 4. **Safety result** — `Source database changed: No/Yes`.
34
+ 5. **Approval boundary** — “Approval happened outside MCP. The model did not get
35
+ approve or commit tools,” plus the current approval status.
36
+ 6. **Commit result** — the terminal outcome in plain language, e.g. “Conflict:
37
+ the row changed after the proposal. No write applied,” with an expandable
38
+ guard checklist.
39
+ 7. **Replay** — a timeline of evidence, proposal, approval, writeback receipt,
40
+ and conflict events.
41
+
42
+ A second **View raw JSON** tab exposes the full proposal, events, receipts, and
43
+ evidence payloads for developers who want the underlying records. Each
44
+ configuration card also keeps its raw JSON behind a per-card drawer.
45
+
46
+ ## What It Shows
47
+
48
+ The setup summary shows:
49
+
50
+ - config path and local store path;
51
+ - Runner mode;
52
+ - source engine and environment-variable names;
53
+ - trusted context binding;
54
+ - selected table/view targets;
55
+ - semantic capabilities;
56
+ - config validation status;
57
+ - whether forbidden model-facing tools such as raw SQL or approval/commit tools
58
+ are present.
59
+
60
+ The tools view shows:
61
+
62
+ - semantic tool names;
63
+ - read/proposal labels;
64
+ - target table/view;
65
+ - input schema;
66
+ - hidden trusted bindings;
67
+ - visible columns;
68
+ - allowed patch columns;
69
+ - conflict guard;
70
+ - clear “No raw SQL” status.
71
+
72
+ The proposals view shows:
73
+
74
+ - pending, approved, rejected, applied, conflict, and failed states;
75
+ - tenant/object/principal;
76
+ - source database changed: yes/no;
77
+ - source row before approval/writeback;
78
+ - proposed patch values;
79
+ - expected version guard;
80
+ - exact before/proposed field diff;
81
+ - evidence handle and summary;
82
+ - receipts when present.
83
+
84
+ The review panel lets a local reviewer:
85
+
86
+ - approve outside the model-facing MCP tool surface;
87
+ - reject with a reason;
88
+ - see the message “The model can propose this change. It cannot approve or
89
+ commit it.” before execution;
90
+ - see “Commit executed by trusted runner” after terminal writeback;
91
+ - see “Conflict: source row changed after proposal” for stale-row cases;
92
+ - inspect the guard checklist for tenant scope, allowed columns, primary key,
93
+ conflict/version column, idempotency key, and affected-row count;
94
+ - inspect writeback mode and executor status;
95
+ - inspect replay for the selected proposal.
96
+
97
+ Approval and rejection record the reviewer identity against the exact proposal
98
+ hash/version in the local SQLite proposal store.
99
+
100
+ ## Security Boundary
101
+
102
+ The local UI keeps the same authority split as the CLI:
103
+
104
+ ```text
105
+ MCP tool call = request/proposal authority
106
+ Trusted local UI/CLI reviewer = approval authority
107
+ Trusted runner apply path = execution authority
108
+ ```
109
+
110
+ Security behavior:
111
+
112
+ - binds to `127.0.0.1` by default;
113
+ - refuses non-localhost binding unless `--allow-remote-bind` is explicitly
114
+ passed;
115
+ - requires a per-run local session token;
116
+ - sets the local session token in an HttpOnly SameSite cookie after the first
117
+ token URL load;
118
+ - requires a CSRF token for approve/reject actions;
119
+ - does not expose database URLs, passwords, bearer tokens, runner tokens, or
120
+ obvious secret strings in JSON API responses;
121
+ - does not expose a raw SQL editor;
122
+ - does not expose approval, commit, or writeback tools through MCP;
123
+ - does not allow widening configured tables, columns, or mutable fields from the
124
+ browser.
125
+
126
+ The UI displays proposal business data from the local store, so use reviewed
127
+ visible columns and denied-column rules before creating proposals. Obvious
128
+ secret-looking fields and connection strings are redacted defensively, but the
129
+ UI is not a replacement for selecting safe capability projections.
130
+
131
+ ## Remote Binding
132
+
133
+ For normal use, do not bind the UI to anything except localhost.
134
+
135
+ For a deliberate trusted local-network demo:
136
+
137
+ ```bash
138
+ npx -y -p @synapsor/runner@alpha synapsor ui --host 0.0.0.0 --allow-remote-bind
139
+ ```
140
+
141
+ Do this only in an isolated environment. The local UI is not a hosted
142
+ multi-user approval product; use Synapsor Cloud when a team needs shared RBAC,
143
+ approval queues, audit retention, and hosted replay search.
144
+
145
+ ## Current Limits
146
+
147
+ The UI is intentionally small in the current alpha:
148
+
149
+ - proposal review and replay only;
150
+ - no graphical capability builder;
151
+ - no raw SQL editor;
152
+ - no direct writeback apply button;
153
+ - no hosted/team auth;
154
+ - no Cloud approval queue replacement.
155
+
156
+ Use the CLI apply path after approval:
157
+
158
+ ```bash
159
+ npx -y -p @synapsor/runner@alpha synapsor proposals writeback-job wrp_123 --store ./.synapsor/local.db --output job.json
160
+ SYNAPSOR_ENGINE=postgres \
161
+ SYNAPSOR_DATABASE_URL="$SYNAPSOR_DATABASE_WRITE_URL" \
162
+ npx -y -p @synapsor/runner@alpha synapsor apply --job job.json --config synapsor.runner.json --store ./.synapsor/local.db
163
+ ```
@@ -0,0 +1,146 @@
1
+ # MCP database risk review
2
+
3
+ `npx -y -p @synapsor/runner@alpha synapsor audit <target>` performs a
4
+ static MCP database risk review over an exported tool manifest, a remote MCP
5
+ `tools/list` endpoint, or a stdio MCP server. The `mcp audit` subcommand is also
6
+ available for users who look for the command under the MCP namespace.
7
+
8
+ From a source checkout, use `./bin/synapsor ...` if the global binary is not
9
+ linked yet.
10
+
11
+ It does not call business tools. It only inspects names, descriptions, input schemas, output schemas, annotations, and examples when those are present.
12
+
13
+ Every report includes this disclaimer:
14
+
15
+ ```text
16
+ This is a static risk review, not proof that an MCP server is secure.
17
+ ```
18
+
19
+ MCP annotations are treated as hints, not enforcement.
20
+
21
+ ## Usage
22
+
23
+ Built-in database MCP risk example:
24
+
25
+ ```bash
26
+ npx -y -p @synapsor/runner@alpha synapsor audit --example dangerous-db-mcp
27
+ ```
28
+
29
+ This bundled example does not require a source checkout or local examples file.
30
+ It audits a deliberately risky database MCP shape with `execute_sql`,
31
+ `run_query`, model-callable approval/update/delete tools, arbitrary
32
+ table/column inputs, and model-controlled tenant/principal fields.
33
+
34
+ Human-readable output:
35
+
36
+ ```bash
37
+ npx -y -p @synapsor/runner@alpha synapsor audit ./tools-list.json
38
+ ```
39
+
40
+ Remote `tools/list` endpoint with a bearer token kept in the environment:
41
+
42
+ ```bash
43
+ SYNAPSOR_MCP_AUDIT_BEARER="..." \
44
+ npx -y -p @synapsor/runner@alpha synapsor audit https://mcp.example.com --json
45
+ ```
46
+
47
+ Remote endpoint with a custom bearer-token environment variable:
48
+
49
+ ```bash
50
+ npx -y -p @synapsor/runner@alpha synapsor audit https://mcp.example.com --bearer-env MCP_AUDIT_TOKEN --json
51
+ ```
52
+
53
+ Stdio MCP server:
54
+
55
+ ```bash
56
+ npx -y -p @synapsor/runner@alpha synapsor audit 'stdio:node ./server.mjs' --timeout-ms 5000
57
+ ```
58
+
59
+ JSON output:
60
+
61
+ ```bash
62
+ npx -y -p @synapsor/runner@alpha synapsor audit ./tools-list.json --json
63
+ ```
64
+
65
+ During local development, the repo-local wrapper can run the same command:
66
+
67
+ ```bash
68
+ ./bin/synapsor audit ./tools-list.json
69
+ ./bin/synapsor audit ./tools-list.json --json
70
+ ```
71
+
72
+ ## Supported inputs
73
+
74
+ The audit accepts common exported shapes:
75
+
76
+ ```json
77
+ { "tools": [] }
78
+ ```
79
+
80
+ ```json
81
+ { "result": { "tools": [] } }
82
+ ```
83
+
84
+ ```json
85
+ { "data": { "tools": [] } }
86
+ ```
87
+
88
+ It also scans nested `adapter`, `mcpServers`, and `servers` blocks when they include tool metadata.
89
+
90
+ For live targets, the audit calls only JSON-RPC `tools/list`. It does not call business tools, approval tools, commit tools, or writeback tools.
91
+
92
+ ## Findings
93
+
94
+ The audit flags database-commit risks such as:
95
+
96
+ - generic `execute_sql`, `run_query`, or raw SQL tools;
97
+ - tools accepting arbitrary SQL, schema, table, or column identifiers;
98
+ - tools accepting `tenant_id`, `principal`, source ids, allowed columns, row versions, or approval identity as model input;
99
+ - model-callable approval, commit, apply, settle, merge, or writeback tools;
100
+ - write-like tools with no visible proposal, approval, or guarded-writeback boundary;
101
+ - missing structured output schemas;
102
+ - missing idempotency/request-key metadata for direct write-like tools;
103
+ - missing row-version/conflict-guard metadata for direct write-like tools;
104
+ - ambiguous read/write tool boundaries;
105
+ - missing business descriptions, annotations, or fixture examples.
106
+
107
+ ## Recommended target shape
108
+
109
+ A safer model-facing database MCP tool should look like a reviewed semantic proposal capability:
110
+
111
+ ```json
112
+ {
113
+ "name": "billing.propose_late_fee_waiver",
114
+ "description": "Create an evidence-backed proposal for support lead approval before trusted writeback.",
115
+ "inputSchema": {
116
+ "type": "object",
117
+ "properties": {
118
+ "invoice_id": { "type": "string" },
119
+ "reason": { "type": "string" }
120
+ },
121
+ "required": ["invoice_id", "reason"]
122
+ },
123
+ "outputSchema": {
124
+ "type": "object",
125
+ "properties": {
126
+ "status": { "type": "string" },
127
+ "proposal_id": { "type": "string" },
128
+ "evidence_bundle_id": { "type": "string" },
129
+ "source_database_changed": { "type": "boolean" }
130
+ },
131
+ "required": ["status", "proposal_id", "source_database_changed"]
132
+ },
133
+ "annotations": {
134
+ "readOnlyHint": false,
135
+ "destructiveHint": false
136
+ },
137
+ "examples": [
138
+ {
139
+ "invoice_id": "INV-3001",
140
+ "reason": "customer requested review"
141
+ }
142
+ ]
143
+ }
144
+ ```
145
+
146
+ Trusted values such as tenant, principal, source, allowed columns, approval identity, row-version guard, and database credentials must come from Synapsor/runner context, not from model-facing arguments.