@synapsor/runner 0.1.10 → 0.1.12

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 (26) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/README.md +49 -25
  3. package/dist/cli.d.ts.map +1 -1
  4. package/dist/runner.mjs +275 -20
  5. package/docs/README.md +6 -0
  6. package/docs/cloud-mode.md +18 -0
  7. package/docs/cloud-push.md +54 -0
  8. package/docs/current-scope.md +1 -1
  9. package/docs/mcp-clients.md +123 -0
  10. package/docs/release-notes.md +41 -0
  11. package/docs/runner-bundles.md +59 -0
  12. package/examples/support-plan-credit/.env.example +10 -0
  13. package/examples/support-plan-credit/README.md +107 -10
  14. package/examples/support-plan-credit/expected-output/cloud-push-response.json +9 -0
  15. package/examples/support-plan-credit/expected-output/proposal-created.json +23 -0
  16. package/examples/support-plan-credit/expected-output/receipt.json +13 -0
  17. package/examples/support-plan-credit/expected-output/replay-summary.json +13 -0
  18. package/examples/support-plan-credit/expected-output/tools-preview.txt +15 -0
  19. package/examples/support-plan-credit/mcp-client-examples/claude-desktop.json +20 -0
  20. package/examples/support-plan-credit/mcp-client-examples/cursor-global.mcp.json +20 -0
  21. package/examples/support-plan-credit/mcp-client-examples/cursor-project.mcp.json +20 -0
  22. package/examples/support-plan-credit/mcp-client-examples/generic-stdio.json +17 -0
  23. package/examples/support-plan-credit/mcp-client-examples/generic-streamable-http.json +5 -0
  24. package/examples/support-plan-credit/mcp-client-examples/openai-agents-stdio.ts +19 -0
  25. package/examples/support-plan-credit/mcp-client-examples/openai-agents-streamable-http.ts +20 -0
  26. package/package.json +1 -1
@@ -0,0 +1,54 @@
1
+ # Push A Contract To Synapsor Cloud
2
+
3
+ Cloud push registers the same canonical contract that you validate and run
4
+ locally. Cloud stores a normalized immutable version, computes its digest,
5
+ records the actor, and makes the safety boundary visible in the workspace
6
+ registry.
7
+
8
+ ## Preview Without A Network Call
9
+
10
+ ```bash
11
+ synapsor-runner cloud push ./synapsor.contract.json --dry-run
12
+ synapsor-runner cloud push ./synapsor.contract.json --dry-run --json
13
+ ```
14
+
15
+ Dry-run validates and normalizes locally. It performs no network request.
16
+
17
+ ## Push
18
+
19
+ ```bash
20
+ export SYNAPSOR_CLOUD_BASE_URL="https://api.synapsor.ai"
21
+ export SYNAPSOR_CLOUD_TOKEN="<workspace-scoped-token>"
22
+ export SYNAPSOR_WORKSPACE_ID="<workspace-id>"
23
+
24
+ synapsor-runner cloud push ./synapsor.contract.json \
25
+ --name support-plan-credit
26
+ ```
27
+
28
+ The response includes the contract id, immutable version id, server-computed
29
+ digest, summary counts, status, and registry path. Identical normalized content
30
+ is idempotent; changed content creates the next version.
31
+
32
+ Tokens are sent in the authorization header and are never part of the contract.
33
+ Database URLs, passwords, private keys, and model-controlled tenant bindings
34
+ are rejected by server-side validation.
35
+
36
+ `SYNAPSOR_CLOUD_WORKSPACE` is accepted as an alias for
37
+ `SYNAPSOR_WORKSPACE_ID`. Explicit `--workspace` wins over environment values.
38
+
39
+ Cloud push fails before upload when local validation fails. HTTP failures are
40
+ reported distinctly for invalid/expired tokens (`401`), insufficient workspace
41
+ permission (`403`), missing workspace/API paths (`404`), registry conflicts
42
+ (`409`), server validation (`422`), and Cloud/network failures. Error output
43
+ does not echo the bearer token.
44
+
45
+ ## Cloud To Local
46
+
47
+ Open **Contract registry** in the workspace, choose a version, and download its
48
+ runner bundle. The ZIP contains the normalized contract, local runner wiring,
49
+ placeholder environment file, README, and MCP client examples. It contains no
50
+ live credentials or table rows.
51
+
52
+ Cloud currently preserves approval policy definitions in the contract and
53
+ bundle. Hosted approval-policy enforcement remains a separate Cloud feature;
54
+ do not infer it from registry storage alone.
@@ -2,7 +2,7 @@
2
2
 
3
3
  The canonical scope page is [Current Limitations](limitations.md).
4
4
 
5
- Current alpha scope:
5
+ Current `0.1.x` scope:
6
6
 
7
7
  - local semantic MCP tools for Postgres/MySQL-backed business actions;
8
8
  - schema inspection and guided config generation;
@@ -0,0 +1,123 @@
1
+ # MCP Client Configs
2
+
3
+ Synapsor Runner exposes reviewed semantic tools over standard MCP. The model
4
+ receives inspect/propose capabilities; it does not receive raw SQL, database
5
+ credentials, approval commands, or apply commands.
6
+
7
+ The complete copy-paste templates live in:
8
+
9
+ - [`examples/support-plan-credit/mcp-client-examples/`](../examples/support-plan-credit/mcp-client-examples/)
10
+ - every local `synapsor-runner contract bundle` output;
11
+ - every downloadable Synapsor Cloud runner bundle.
12
+
13
+ Before connecting a client, validate the local boundary:
14
+
15
+ ```bash
16
+ synapsor-runner config validate --config ./synapsor.runner.json
17
+ synapsor-runner tools preview --config ./synapsor.runner.json --store ./.synapsor/local.db
18
+ ```
19
+
20
+ Set database and trusted-context values in the environment that launches the
21
+ MCP process. Keep real URLs and tokens in your shell or secret manager, not in
22
+ the checked-in client JSON.
23
+
24
+ ## Stdio
25
+
26
+ Use stdio for Claude Desktop, Cursor, and other local MCP clients:
27
+
28
+ ```json
29
+ {
30
+ "command": "npx",
31
+ "args": [
32
+ "-y", "-p", "@synapsor/runner", "synapsor-runner",
33
+ "mcp", "serve", "--config", "./synapsor.runner.json",
34
+ "--store", "./.synapsor/local.db"
35
+ ]
36
+ }
37
+ ```
38
+
39
+ Relative paths are resolved from the MCP client's working directory. Use the
40
+ project template when the client starts in your repository; replace the marked
41
+ bundle path in the global template when it does not.
42
+
43
+ ### Claude Desktop
44
+
45
+ 1. Open Claude Desktop settings and choose the developer option to edit its MCP
46
+ configuration.
47
+ 2. Merge `claude-desktop.json` into the existing `mcpServers` object.
48
+ 3. Replace the marked working directory or use absolute paths when Claude does
49
+ not start in the bundle directory.
50
+ 4. Restart Claude Desktop completely, then confirm the two semantic tools are
51
+ listed.
52
+
53
+ Claude Desktop launched from a graphical session may not inherit your terminal
54
+ environment. Supply the required env values through the OS process environment
55
+ or a local secret-manager wrapper; do not paste production credentials into a
56
+ repository file.
57
+
58
+ ### Cursor
59
+
60
+ For one repository, place the project template at `.cursor/mcp.json`. For a
61
+ global setup, merge `cursor-global.mcp.json` through Cursor's MCP settings and
62
+ replace every `<absolute-path-to-bundle>` marker. Restart the MCP server from
63
+ Cursor settings after editing.
64
+
65
+ The model-facing list should contain only the contract's inspect/propose tools.
66
+ If Cursor reports a missing config or store, use absolute paths and rerun
67
+ `tools preview` from the same working directory.
68
+
69
+ ### OpenAI Agents SDK
70
+
71
+ Install the SDK in your agent project and run either TypeScript template:
72
+
73
+ ```bash
74
+ npm install @openai/agents
75
+ ```
76
+
77
+ OpenAI function names cannot contain dots. The stdio template therefore starts
78
+ Runner with `--alias-mode openai`; model-visible names use `__`, while result
79
+ metadata preserves the canonical dotted Synapsor capability name.
80
+
81
+ ## Streamable HTTP
82
+
83
+ ```bash
84
+ synapsor-runner mcp serve \
85
+ --transport streamable-http \
86
+ --alias-mode openai \
87
+ --host 127.0.0.1 \
88
+ --port 8766 \
89
+ --config ./synapsor.runner.json \
90
+ --store ./.synapsor/local.db
91
+ ```
92
+
93
+ Connect a standard Streamable HTTP MCP client to
94
+ `http://127.0.0.1:8766/mcp`. Keep it on loopback for local development. For a
95
+ network deployment, terminate TLS, require authentication, restrict network
96
+ access, and follow the [production guide](production.md).
97
+
98
+ Use `--alias-mode openai` for the OpenAI Agents SDK. Omit it for clients that
99
+ accept canonical dotted names, or use `--alias-mode both` only during a planned
100
+ migration where duplicate canonical/alias tools are acceptable.
101
+
102
+ ## Verify The Boundary
103
+
104
+ ```bash
105
+ synapsor-runner tools preview --config ./synapsor.runner.json --store ./.synapsor/local.db
106
+ synapsor-runner smoke call --config ./synapsor.runner.json --store ./.synapsor/local.db
107
+ ```
108
+
109
+ The preview must list semantic capabilities and must not list `execute_sql`,
110
+ approval/apply tools, database URLs, write credentials, or model-controlled
111
+ tenant authority.
112
+
113
+ ## Troubleshooting
114
+
115
+ - `ENOENT` or missing config: use absolute config/store paths.
116
+ - empty tool list: run `contract validate`, then `tools preview` against the
117
+ exact config used by the client.
118
+ - database connection failure: verify the client process received the read URL
119
+ and trusted tenant/principal env values.
120
+ - OpenAI rejects a dotted name: start Runner with `--alias-mode openai`.
121
+ - HTTP `initialize` failure: use `mcp serve --transport streamable-http`, not
122
+ the legacy `serve-http` JSON-RPC bridge.
123
+ - no ready message: inspect client stderr; Runner keeps stdout protocol-clean.
@@ -12,6 +12,47 @@ for the Synapsor Cloud CLI.
12
12
 
13
13
  ## Unreleased
14
14
 
15
+ Prepared package version: `@synapsor/runner@0.1.12`. The already-published
16
+ `@synapsor/spec@0.1.4` and `@synapsor/dsl@0.1.4` do not change and must not be
17
+ republished for this release.
18
+
19
+ ### Runner Version Invocation
20
+
21
+ - Keeps `synapsor-runner --version`, `synapsor-runner -v`, and
22
+ `synapsor-runner version` stable if an npm/npx wrapper forwards a duplicated
23
+ executable token.
24
+ - Uses Runner's bundled package metadata instead of the invoking project's
25
+ `npm_package_version` environment value.
26
+ - Adds source-wrapper and installed-tarball verification for all three forms.
27
+
28
+ ## 0.1.11
29
+
30
+ ### Cloud Adoption Loop
31
+
32
+ - Adds complete Claude, Cursor, OpenAI Agents SDK, and generic MCP templates to
33
+ local and Cloud-generated Runner bundles.
34
+ - Adds a flagship adoption verifier and a real local Cloud registry/version/ZIP
35
+ bundle round trip.
36
+ - Expands the `support-plan-credit` walkthrough from no-database validation to
37
+ Docker-backed policy tiers, MCP setup, Cloud push, bundle download, replay,
38
+ cleanup, and troubleshooting.
39
+ - Supports `SYNAPSOR_CLOUD_WORKSPACE` and verifies distinct 401/403/404/409/422,
40
+ server, and network errors without exposing tokens.
41
+ - Clarifies that Cloud registry/versioning is beta-ready while managed runners,
42
+ SAML/SCIM, hosted policy enforcement, legal hold, and enterprise SLA are not
43
+ part of this release.
44
+ - Corrects `cloud push --help` to describe the real authenticated registry
45
+ upload and network-free dry-run behavior.
46
+
47
+ ## 0.1.10
48
+
49
+ ### Policy Auto-Approval
50
+
51
+ - Adds portable approval-policy references and threshold rules.
52
+ - Adds DSL `AUTO APPROVE WHEN field <= integer` and the three-tier
53
+ `support-plan-credit` example: policy approval, operator review, and bound
54
+ rejection.
55
+
15
56
  ## 0.1.9
16
57
 
17
58
  ### CLI Hygiene
@@ -0,0 +1,59 @@
1
+ # Runner Bundles
2
+
3
+ A runner bundle is the portable Cloud-to-local side of the canonical loop:
4
+
5
+ ```text
6
+ local DSL/spec -> cloud push -> immutable registry version -> runner bundle -> local Runner
7
+ ```
8
+
9
+ Every bundle contains:
10
+
11
+ ```text
12
+ synapsor.contract.json
13
+ synapsor.runner.json
14
+ .env.example
15
+ README.md
16
+ mcp-client-examples/
17
+ claude-desktop.json
18
+ cursor-project.mcp.json
19
+ cursor-global.mcp.json
20
+ openai-agents-stdio.ts
21
+ openai-agents-streamable-http.ts
22
+ generic-stdio.json
23
+ generic-streamable-http.json
24
+ ```
25
+
26
+ It never contains database passwords, write credentials, live API tokens,
27
+ private keys, customer rows, or machine-specific local paths.
28
+
29
+ ## Create Locally
30
+
31
+ ```bash
32
+ synapsor-runner contract bundle ./synapsor.contract.json \
33
+ --out ./synapsor-runner-bundle
34
+ ```
35
+
36
+ ## Run A Downloaded Bundle
37
+
38
+ ```bash
39
+ cd ./synapsor-runner-bundle
40
+ cp .env.example .env
41
+ set -a && . ./.env && set +a
42
+
43
+ npx -y -p @synapsor/runner synapsor-runner contract validate ./synapsor.contract.json
44
+ npx -y -p @synapsor/runner synapsor-runner config validate --config ./synapsor.runner.json
45
+ npx -y -p @synapsor/runner synapsor-runner tools preview --config ./synapsor.runner.json --store ./.synapsor/local.db
46
+ npx -y -p @synapsor/runner synapsor-runner mcp serve --config ./synapsor.runner.json --store ./.synapsor/local.db
47
+ ```
48
+
49
+ For the OpenAI Agents SDK, use the included TypeScript examples. Their stdio
50
+ command enables `--alias-mode openai`; the Streamable HTTP example includes the
51
+ matching server command. Claude, Cursor, and generic templates use canonical
52
+ dotted capability names.
53
+
54
+ Approval and writeback remain outside the model-facing MCP tool surface. Use
55
+ `proposals`, `apply`, `receipts`, and `replay` from a trusted operator shell.
56
+
57
+ The bundle's `.env.example` contains names and placeholders only. Fill it for a
58
+ local or staging source, source it into the shell or process that launches your
59
+ MCP client, and keep the resulting `.env` out of source control.
@@ -0,0 +1,10 @@
1
+ # Disposable Docker example credentials only. Do not reuse in staging or production.
2
+ PLAN_CREDIT_POSTGRES_READ_URL=postgresql://synapsor_reader:synapsor_reader_password@127.0.0.1:55438/synapsor_runner_plan_credit
3
+ PLAN_CREDIT_POSTGRES_WRITE_URL=postgresql://synapsor_writer:synapsor_writer_password@127.0.0.1:55438/synapsor_runner_plan_credit
4
+ SYNAPSOR_TENANT_ID=acme
5
+ SYNAPSOR_PRINCIPAL=local_support_agent
6
+
7
+ # Optional Cloud registry upload. Keep real values outside git.
8
+ SYNAPSOR_CLOUD_BASE_URL=
9
+ SYNAPSOR_CLOUD_TOKEN=
10
+ SYNAPSOR_WORKSPACE_ID=
@@ -12,15 +12,46 @@ This example shows three enforcement tiers on one support action:
12
12
  - Node 22.5+
13
13
  - Port `55438` available
14
14
 
15
+ Install the stable CLI once for the commands below:
16
+
17
+ ```bash
18
+ npm install --global @synapsor/runner
19
+ synapsor-runner --version
20
+ ```
21
+
22
+ When working from this source checkout, use `corepack pnpm runner` in place of
23
+ `synapsor-runner`.
24
+
25
+ ## No-Database Check
26
+
27
+ Validate the authored boundary before starting Docker:
28
+
29
+ ```bash
30
+ synapsor-runner dsl compile examples/support-plan-credit/contract.synapsor \
31
+ --out /tmp/support-plan-credit.contract.json \
32
+ --strict
33
+ synapsor-runner contract validate /tmp/support-plan-credit.contract.json
34
+ synapsor-runner config validate \
35
+ --config examples/support-plan-credit/synapsor.runner.json
36
+ synapsor-runner cloud push /tmp/support-plan-credit.contract.json \
37
+ --dry-run \
38
+ --workspace local-preview \
39
+ --name support-plan-credit
40
+ ```
41
+
42
+ This compiles, validates, and previews the Cloud payload without opening a
43
+ network connection or connecting to a database. From a source checkout,
44
+ `corepack pnpm verify:adoption` runs this boundary check plus the no-database
45
+ quick demo and MCP config validation.
46
+
15
47
  ## Quick Start
16
48
 
17
49
  ```bash
18
50
  docker compose -f examples/support-plan-credit/docker-compose.yml up -d
19
51
 
20
- export PLAN_CREDIT_POSTGRES_READ_URL="postgresql://synapsor_reader:synapsor_reader_password@localhost:55438/synapsor_runner_plan_credit"
21
- export PLAN_CREDIT_POSTGRES_WRITE_URL="postgresql://synapsor_writer:synapsor_writer_password@localhost:55438/synapsor_runner_plan_credit"
22
- export SYNAPSOR_TENANT_ID="acme"
23
- export SYNAPSOR_PRINCIPAL="local_support_agent"
52
+ set -a
53
+ . examples/support-plan-credit/.env.example
54
+ set +a
24
55
 
25
56
  synapsor-runner tools preview \
26
57
  --config examples/support-plan-credit/synapsor.runner.json \
@@ -32,6 +63,9 @@ synapsor-runner mcp serve \
32
63
  --store ./tmp/support-plan-credit/local.db
33
64
  ```
34
65
 
66
+ The checked-in `.env.example` contains disposable localhost Docker credentials
67
+ only. Never reuse them for staging or production.
68
+
35
69
  ## Walkthrough
36
70
 
37
71
  Inspect the customer first:
@@ -98,6 +132,13 @@ synapsor-runner apply latest --config examples/support-plan-credit/synapsor.runn
98
132
  The live smoke test mutates `updated_at` before apply and proves stale proposals
99
133
  return `VERSION_CONFLICT` without changing the source row.
100
134
 
135
+ Run the complete Docker-backed scenario, including all three policy tiers and
136
+ the stale-row conflict:
137
+
138
+ ```bash
139
+ corepack pnpm test:live-apply
140
+ ```
141
+
101
142
  ## What The Agent Never Sees
102
143
 
103
144
  The contract keeps these fields out:
@@ -118,6 +159,37 @@ auto-approval: enabled
118
159
  No raw SQL, approval tools, commit tools, write credentials, or model-controlled
119
160
  tenant authority are exposed to MCP.
120
161
 
162
+ Representative outputs are checked in under [`expected-output/`](expected-output/)
163
+ so you can compare the tool boundary, proposal, receipt, replay, and Cloud push
164
+ shape without guessing which state should change.
165
+
166
+ ## Connect An MCP Client
167
+
168
+ Copy the matching template from [`mcp-client-examples/`](mcp-client-examples/):
169
+
170
+ - Claude Desktop: `claude-desktop.json`
171
+ - Cursor project/global: `cursor-project.mcp.json`, `cursor-global.mcp.json`
172
+ - OpenAI Agents SDK: stdio and Streamable HTTP TypeScript examples
173
+ - generic MCP: stdio and Streamable HTTP JSON examples
174
+
175
+ For Streamable HTTP, run:
176
+
177
+ ```bash
178
+ synapsor-runner mcp serve \
179
+ --transport streamable-http \
180
+ --alias-mode openai \
181
+ --host 127.0.0.1 \
182
+ --port 8766 \
183
+ --config examples/support-plan-credit/synapsor.runner.json \
184
+ --store ./tmp/support-plan-credit/local.db
185
+ ```
186
+
187
+ The OpenAI client receives `support__inspect_customer` and
188
+ `support__propose_plan_credit`; Runner preserves the dotted canonical names in
189
+ tool metadata and results. For Claude, Cursor, or generic MCP clients, omit
190
+ `--alias-mode openai` to expose `support.inspect_customer` and
191
+ `support.propose_plan_credit`. Approval and apply remain outside MCP.
192
+
121
193
  ## How The Policy Is Governed
122
194
 
123
195
  The auto-approval policy lives in `contract.synapsor`:
@@ -153,11 +225,11 @@ synapsor-runner cloud push examples/support-plan-credit/synapsor.contract.json -
153
225
  Real push uses your Cloud env vars:
154
226
 
155
227
  ```bash
156
- export SYNAPSOR_CONTROL_PLANE_URL="https://api.synapsor.ai"
157
- export SYNAPSOR_RUNNER_TOKEN="syn_wbr_..."
228
+ export SYNAPSOR_CLOUD_BASE_URL="https://api.synapsor.ai"
229
+ export SYNAPSOR_CLOUD_TOKEN="<workspace-scoped-token>"
230
+ export SYNAPSOR_WORKSPACE_ID="<workspace_id>"
158
231
 
159
232
  synapsor-runner cloud push examples/support-plan-credit/synapsor.contract.json \
160
- --workspace <workspace_id> \
161
233
  --name support-plan-credit
162
234
  ```
163
235
 
@@ -166,11 +238,36 @@ placeholder env names:
166
238
 
167
239
  ```bash
168
240
  curl -H "Authorization: Bearer $SYNAPSOR_CLOUD_TOKEN" \
169
- "$SYNAPSOR_CONTROL_PLANE_URL/v1/control/projects/<workspace_id>/agent-contracts/support-plan-credit/versions/latest"
241
+ "$SYNAPSOR_CLOUD_BASE_URL/v1/control/projects/$SYNAPSOR_WORKSPACE_ID/agent-contracts/<contract_id>/versions/<version_id>"
170
242
 
171
243
  curl -H "Authorization: Bearer $SYNAPSOR_CLOUD_TOKEN" \
172
- "$SYNAPSOR_CONTROL_PLANE_URL/v1/control/projects/<workspace_id>/agent-contracts/support-plan-credit/runner-bundle" \
173
- -o support-plan-credit-runner-bundle.json
244
+ "$SYNAPSOR_CLOUD_BASE_URL/v1/control/projects/$SYNAPSOR_WORKSPACE_ID/agent-contracts/<contract_id>/versions/<version_id>/runner-bundle?download=1" \
245
+ -o support-plan-credit-runner-bundle.zip
174
246
  ```
175
247
 
248
+ The push response supplies `<contract_id>` and `<version_id>`. The Cloud
249
+ workspace also exposes the same download from **Contract registry**.
250
+
176
251
  No Cloud account is needed to run this local example.
252
+
253
+ ## Clean Up
254
+
255
+ ```bash
256
+ docker compose -f examples/support-plan-credit/docker-compose.yml down -v
257
+ rm -rf ./tmp/support-plan-credit
258
+ ```
259
+
260
+ ## Troubleshooting
261
+
262
+ - `synapsor-runner: command not found`: install `@synapsor/runner` globally or
263
+ use `corepack pnpm runner` from this repository.
264
+ - port `55438` is busy: stop the previous example container or change the
265
+ published port and both URLs in `.env.example` together.
266
+ - missing table/connection: wait for the Docker health check, then rerun the
267
+ command from the repository root with the `.env.example` values exported.
268
+ - OpenAI rejects dotted tool names: start the MCP server with
269
+ `--alias-mode openai` and use the OpenAI template.
270
+ - proposal stays pending: `$100` intentionally requires
271
+ `proposals approve`; only the `$25` tier is policy-approved.
272
+ - apply reports a conflict: the row changed after the proposal read. Inspect
273
+ the new row, create a fresh proposal, and do not bypass the version guard.
@@ -0,0 +1,9 @@
1
+ {
2
+ "ok": true,
3
+ "contract_id": "act_support_plan_credit_example",
4
+ "contract_version_id": "act_support_plan_credit_example_v1",
5
+ "version_number": 1,
6
+ "status": "draft",
7
+ "digest": "sha256:<server-computed-digest>",
8
+ "registry_url": "/workspace/contracts?contract=<contract_id>"
9
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "proposal_id": "wrp_example_low_risk_credit",
3
+ "capability": "support.propose_plan_credit",
4
+ "status": "approved",
5
+ "approval_actor": "policy:support_propose_plan_credit_auto_approval",
6
+ "target": {
7
+ "table": "customers",
8
+ "id": "CUS-3001",
9
+ "tenant_id": "acme"
10
+ },
11
+ "change_set": {
12
+ "plan_credit_cents": {
13
+ "before": 0,
14
+ "after": 2500
15
+ },
16
+ "credit_reason": {
17
+ "before": null,
18
+ "after": "SLA outage ticket SUP-481"
19
+ }
20
+ },
21
+ "source_database_changed": false,
22
+ "evidence_handle": "evidence://local/example-plan-credit"
23
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "receipt_id": "rct_example_plan_credit",
3
+ "proposal_id": "wrp_example_low_risk_credit",
4
+ "status": "applied",
5
+ "rows_affected": 1,
6
+ "guards": {
7
+ "tenant": "passed",
8
+ "primary_key": "passed",
9
+ "allowed_columns": "passed",
10
+ "expected_version": "passed",
11
+ "idempotency": "passed"
12
+ }
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "proposal_id": "wrp_example_low_risk_credit",
3
+ "events": [
4
+ "scoped_read",
5
+ "evidence_saved",
6
+ "proposal_created",
7
+ "policy_approved",
8
+ "guarded_writeback_applied",
9
+ "receipt_recorded"
10
+ ],
11
+ "source_database_changed_before_approval": false,
12
+ "final_status": "applied"
13
+ }
@@ -0,0 +1,15 @@
1
+ Synapsor tools preview: ok
2
+
3
+ Exposed to MCP:
4
+ - support.inspect_customer
5
+ - support.propose_plan_credit
6
+
7
+ Not exposed to MCP:
8
+ - execute_sql / raw query tools
9
+ - approval tools
10
+ - commit/apply tools
11
+ - database URLs
12
+ - write credentials
13
+ - model-controlled tenant authority
14
+
15
+ auto-approval: enabled
@@ -0,0 +1,20 @@
1
+ {
2
+ "mcpServers": {
3
+ "synapsor-runner": {
4
+ "command": "npx",
5
+ "args": [
6
+ "-y",
7
+ "-p",
8
+ "@synapsor/runner",
9
+ "synapsor-runner",
10
+ "mcp",
11
+ "serve",
12
+ "--config",
13
+ "examples/support-plan-credit/synapsor.runner.json",
14
+ "--store",
15
+ "./tmp/support-plan-credit/local.db"
16
+ ],
17
+ "cwd": "<absolute-path-to-Synapsor-Runner>"
18
+ }
19
+ }
20
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "mcpServers": {
3
+ "synapsor-runner": {
4
+ "type": "stdio",
5
+ "command": "npx",
6
+ "args": [
7
+ "-y",
8
+ "-p",
9
+ "@synapsor/runner",
10
+ "synapsor-runner",
11
+ "mcp",
12
+ "serve",
13
+ "--config",
14
+ "<absolute-path-to-Synapsor-Runner>/examples/support-plan-credit/synapsor.runner.json",
15
+ "--store",
16
+ "<absolute-path-to-Synapsor-Runner>/tmp/support-plan-credit/local.db"
17
+ ]
18
+ }
19
+ }
20
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "mcpServers": {
3
+ "synapsor-runner": {
4
+ "type": "stdio",
5
+ "command": "npx",
6
+ "args": [
7
+ "-y",
8
+ "-p",
9
+ "@synapsor/runner",
10
+ "synapsor-runner",
11
+ "mcp",
12
+ "serve",
13
+ "--config",
14
+ "examples/support-plan-credit/synapsor.runner.json",
15
+ "--store",
16
+ "./tmp/support-plan-credit/local.db"
17
+ ]
18
+ }
19
+ }
20
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "synapsor-runner",
3
+ "transport": "stdio",
4
+ "command": "npx",
5
+ "args": [
6
+ "-y",
7
+ "-p",
8
+ "@synapsor/runner",
9
+ "synapsor-runner",
10
+ "mcp",
11
+ "serve",
12
+ "--config",
13
+ "examples/support-plan-credit/synapsor.runner.json",
14
+ "--store",
15
+ "./tmp/support-plan-credit/local.db"
16
+ ]
17
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "name": "synapsor-runner",
3
+ "transport": "streamable-http",
4
+ "url": "http://127.0.0.1:8766/mcp"
5
+ }
@@ -0,0 +1,19 @@
1
+ import { Agent, MCPServerStdio, run } from "@openai/agents";
2
+
3
+ const synapsor = new MCPServerStdio({
4
+ name: "Synapsor Runner",
5
+ fullCommand: "npx -y -p @synapsor/runner synapsor-runner mcp serve --config examples/support-plan-credit/synapsor.runner.json --store ./tmp/support-plan-credit/local.db --alias-mode openai",
6
+ });
7
+
8
+ await synapsor.connect();
9
+ try {
10
+ const agent = new Agent({
11
+ name: "Support operations agent",
12
+ instructions: "Use only Synapsor business tools. Inspect evidence before proposing a plan credit.",
13
+ mcpServers: [synapsor],
14
+ });
15
+ const result = await run(agent, "Inspect customer CUS-3001 and propose a $25 plan credit for SLA outage ticket SUP-481.");
16
+ console.log(result.finalOutput);
17
+ } finally {
18
+ await synapsor.close();
19
+ }