@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.
- package/README.md +387 -19
- package/TRADEMARKS.md +23 -0
- package/dist/cli.d.ts +4 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +20 -8723
- package/dist/runner.mjs +12759 -0
- package/docs/README.md +36 -0
- package/docs/getting-started-own-database.md +460 -0
- package/docs/http-mcp.md +242 -0
- package/docs/limitations.md +95 -0
- package/docs/local-mode.md +351 -0
- package/docs/mcp-audit.md +152 -0
- package/docs/mcp-client-setup.md +231 -0
- package/docs/recipes.md +61 -0
- package/docs/release-notes.md +129 -0
- package/docs/security-boundary.md +94 -0
- package/docs/troubleshooting-first-run.md +248 -0
- package/docs/writeback-executors.md +209 -0
- package/examples/app-owned-writeback/README.md +120 -0
- package/examples/app-owned-writeback/business-actions.md +221 -0
- package/examples/app-owned-writeback/command-handler.mjs +46 -0
- package/examples/app-owned-writeback/node-fastify-handler.mjs +55 -0
- package/examples/app-owned-writeback/python-fastapi-handler.py +57 -0
- package/examples/dangerous-mcp-tools.json +88 -0
- package/examples/openai-agents-http/README.md +56 -0
- package/examples/openai-agents-http/agent.py +54 -0
- package/examples/openai-agents-http/requirements.txt +1 -0
- package/examples/openai-agents-stdio/README.md +62 -0
- package/examples/openai-agents-stdio/agent.py +70 -0
- package/examples/openai-agents-stdio/requirements.txt +1 -0
- package/examples/reference-support-billing-app/README.md +137 -0
- package/examples/reference-support-billing-app/docker-compose.yml +13 -0
- package/examples/reference-support-billing-app/mcp-client.generic.json +11 -0
- package/examples/reference-support-billing-app/schema.sql +68 -0
- package/examples/reference-support-billing-app/scripts/run-demo.sh +7 -0
- package/examples/reference-support-billing-app/seed.sql +33 -0
- package/examples/reference-support-billing-app/synapsor.runner.json +241 -0
- package/package.json +12 -4
- package/recipes/accounts.trial_extension.json +42 -0
- package/recipes/billing.late_fee_waiver.json +46 -0
- package/recipes/credits.account_credit.json +45 -0
- package/recipes/orders.refund_review.json +57 -0
- package/recipes/support.ticket_resolution.json +51 -0
- package/dist/bin.cjs +0 -13
package/docs/http-mcp.md
ADDED
|
@@ -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.
|