@synapsor/runner 1.5.0 → 1.5.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.
- package/CHANGELOG.md +92 -3
- package/README.md +96 -109
- package/dist/authoring.d.ts +23 -0
- package/dist/authoring.d.ts.map +1 -0
- package/dist/authoring.mjs +1318 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +4 -5
- package/dist/local-ui.d.ts +14 -0
- package/dist/local-ui.d.ts.map +1 -1
- package/dist/runner.mjs +10845 -5598
- package/dist/runtime.mjs +29 -1
- package/dist/shadow.d.ts +36 -0
- package/dist/shadow.d.ts.map +1 -0
- package/dist/shadow.mjs +5262 -0
- package/docs/README.md +25 -2
- package/docs/alternatives.md +122 -0
- package/docs/capability-authoring.md +43 -0
- package/docs/client-recipes.md +218 -0
- package/docs/contract-testing.md +9 -7
- package/docs/cursor-plugin.md +78 -0
- package/docs/effect-regression.md +39 -2
- package/docs/fresh-developer-usability.md +110 -0
- package/docs/getting-started-own-database.md +96 -2
- package/docs/host-compatibility.md +59 -0
- package/docs/local-mode.md +6 -5
- package/docs/mcp-audit.md +166 -2
- package/docs/mcp-client-setup.md +4 -0
- package/docs/mcp-clients.md +33 -4
- package/docs/oss-vs-cloud.md +3 -0
- package/docs/release-notes.md +90 -4
- package/docs/security-boundary.md +20 -5
- package/docs/shadow-studies.md +47 -4
- package/docs/troubleshooting-first-run.md +46 -0
- package/examples/support-billing-agent/README.md +18 -0
- package/examples/support-billing-agent/app/README.md +6 -0
- package/examples/support-billing-agent/app/contract.ts +28 -0
- package/examples/support-billing-agent/app/effect-adapter.mjs +23 -0
- package/examples/support-billing-agent/app/record-shadow-outcomes.mjs +44 -0
- package/examples/support-billing-agent/scripts/run-evaluation.sh +6 -5
- package/examples/support-plan-credit/README.md +48 -2
- package/examples/support-plan-credit/mcp-client-examples/README.md +23 -0
- package/examples/support-plan-credit/mcp-client-examples/claude-code.sh +34 -0
- package/examples/support-plan-credit/mcp-client-examples/codex.config.toml +24 -0
- package/examples/support-plan-credit/mcp-client-examples/generic-stdio.mjs +35 -0
- package/examples/support-plan-credit/mcp-client-examples/generic-streamable-http.mjs +31 -0
- package/examples/support-plan-credit/mcp-client-examples/google-adk.py +40 -0
- package/examples/support-plan-credit/mcp-client-examples/langchain.mjs +29 -0
- package/examples/support-plan-credit/mcp-client-examples/llamaindex.py +36 -0
- package/examples/support-plan-credit/mcp-client-examples/openai-agents-stdio.ts +1 -1
- package/examples/support-plan-credit/mcp-client-examples/openai-agents-streamable-http.ts +1 -1
- package/examples/support-plan-credit/mcp-client-examples/vscode.mcp.json +20 -0
- package/examples/support-plan-credit/synapsor/actions/support.propose_plan_credit.contract-tests.generated.json +221 -0
- package/examples/support-plan-credit/synapsor/actions/support.propose_plan_credit.ts +34 -0
- package/fixtures/mcp-audit/README.md +14 -0
- package/fixtures/mcp-audit/cursor-bypass-config.json +38 -0
- package/fixtures/mcp-audit/dangerous-tools-list.json +33 -0
- package/fixtures/mcp-audit/reviewed-proposal-tools-list.json +60 -0
- package/package.json +18 -3
- package/schemas/mcp-audit-report.schema.json +100 -1
- package/schemas/synapsor.contract-tests.schema.json +1 -1
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# Fresh-Developer Usability Protocol
|
|
2
|
+
|
|
3
|
+
Use this protocol with five developers who have not previously used Synapsor.
|
|
4
|
+
It is a launch gate, not an automated test. A maintainer may rehearse the
|
|
5
|
+
protocol, but must not report a participant result unless that person actually
|
|
6
|
+
completed the session.
|
|
7
|
+
|
|
8
|
+
## Goal
|
|
9
|
+
|
|
10
|
+
Measure whether a developer can connect an existing supported staging project,
|
|
11
|
+
draft one disabled Safe Action with a coding agent, receive an exact Data PR,
|
|
12
|
+
approve outside the agent, and find the guarded receipt without learning the
|
|
13
|
+
canonical JSON or SQL-like DSL first.
|
|
14
|
+
|
|
15
|
+
Measure product time separately from the initial package download. Start the
|
|
16
|
+
product timer only after `synapsor-runner --version` succeeds.
|
|
17
|
+
|
|
18
|
+
## Participant Setup
|
|
19
|
+
|
|
20
|
+
Provide each participant with:
|
|
21
|
+
|
|
22
|
+
- a fresh clone of their application or the support-plan-credit reference app;
|
|
23
|
+
- Node 22.13 or newer;
|
|
24
|
+
- a disposable Postgres staging database and least-privilege read/write roles;
|
|
25
|
+
- exported database URLs and trusted tenant/principal values;
|
|
26
|
+
- current stable Cursor, with no existing Synapsor configuration;
|
|
27
|
+
- the README only. Do not give verbal product-architecture instruction.
|
|
28
|
+
|
|
29
|
+
Never use production credentials or data. Record the OS, Node version, Cursor
|
|
30
|
+
version, package-install method, database engine, and whether the package was
|
|
31
|
+
already cached.
|
|
32
|
+
|
|
33
|
+
## Tasks
|
|
34
|
+
|
|
35
|
+
Ask the participant to complete these tasks without a maintainer taking control:
|
|
36
|
+
|
|
37
|
+
1. Run the four-second synthetic proof and identify whether the model can call
|
|
38
|
+
`approve`, `apply`, `commit`, or raw SQL.
|
|
39
|
+
2. Connect the staging project and confirm the trusted organization scope.
|
|
40
|
+
3. Tell Cursor one business action to make safe and use the generated
|
|
41
|
+
`/synapsor-protect` path or exact fallback prompt.
|
|
42
|
+
4. Find the disabled action file and explain why editing it does not activate a
|
|
43
|
+
tool.
|
|
44
|
+
5. Open the Workbench effect preview and confirm the source row is unchanged.
|
|
45
|
+
6. Explicitly activate the reviewed digest through the operator-controlled UI.
|
|
46
|
+
7. Reconnect Cursor if instructed and create one proposal through the semantic
|
|
47
|
+
tool.
|
|
48
|
+
8. Review the exact before/after Data PR, approve outside Cursor, and apply it.
|
|
49
|
+
9. Locate the receipt/replay record and explain what happens on retry.
|
|
50
|
+
10. Draft a second disabled action without changing the active tool surface.
|
|
51
|
+
|
|
52
|
+
Do not rescue a participant until they have been blocked for two minutes. Record
|
|
53
|
+
the exact screen, command, wording, or missing prerequisite that blocked them.
|
|
54
|
+
|
|
55
|
+
## Measurements
|
|
56
|
+
|
|
57
|
+
For each participant, record:
|
|
58
|
+
|
|
59
|
+
| Measure | Target |
|
|
60
|
+
| --- | --- |
|
|
61
|
+
| Installed CLI to first own-data Data PR | under 5 minutes |
|
|
62
|
+
| Installed CLI to first guarded receipt | under 8 minutes |
|
|
63
|
+
| Second disabled action draft after setup | under 2 minutes |
|
|
64
|
+
| Second action ready for explicit activation | under 5 minutes |
|
|
65
|
+
| Handwritten canonical JSON or DSL | none on the happy path |
|
|
66
|
+
| Extra CLI command after Cursor proposal call | none |
|
|
67
|
+
| Unsafe authority exposed to Cursor | none |
|
|
68
|
+
|
|
69
|
+
Also record every wrong turn, maintainer intervention, misunderstood trust
|
|
70
|
+
boundary, and request for a model-provider key or Synapsor account.
|
|
71
|
+
|
|
72
|
+
## Pass Criteria
|
|
73
|
+
|
|
74
|
+
The launch gate passes only when all five participants:
|
|
75
|
+
|
|
76
|
+
- complete the first Data PR without handwritten JSON or DSL;
|
|
77
|
+
- correctly identify that activation, approval, and apply are outside the
|
|
78
|
+
model-facing MCP surface;
|
|
79
|
+
- observe unchanged source data before approval;
|
|
80
|
+
- produce one guarded receipt; and
|
|
81
|
+
- expose only the intended semantic read/proposal tools in Cursor.
|
|
82
|
+
|
|
83
|
+
At least four of five must meet every timing target. Any cross-tenant result,
|
|
84
|
+
hidden-field exposure, pre-approval mutation, automatic activation, raw SQL
|
|
85
|
+
tool, or model-visible commit authority is a release blocker regardless of
|
|
86
|
+
timing.
|
|
87
|
+
|
|
88
|
+
## Reporting Template
|
|
89
|
+
|
|
90
|
+
Record one row per real participant:
|
|
91
|
+
|
|
92
|
+
```text
|
|
93
|
+
Participant:
|
|
94
|
+
Date:
|
|
95
|
+
Environment:
|
|
96
|
+
Cold package download:
|
|
97
|
+
Product timer start:
|
|
98
|
+
First Data PR:
|
|
99
|
+
First receipt:
|
|
100
|
+
Second draft:
|
|
101
|
+
Second activation-ready action:
|
|
102
|
+
Interventions:
|
|
103
|
+
Tool surface observed:
|
|
104
|
+
Safety-boundary explanation:
|
|
105
|
+
Outcome: pass | fail
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Until five real sessions are recorded, report this gate as **owner verification
|
|
109
|
+
pending**. Do not infer usability from unit tests, protocol tests, or a
|
|
110
|
+
maintainer-run demo.
|
|
@@ -28,11 +28,11 @@ inspect your schema
|
|
|
28
28
|
-> choose one table/view
|
|
29
29
|
-> choose trusted scope and visible fields
|
|
30
30
|
-> optionally choose proposal/writeback rules
|
|
31
|
-
-> generate synapsor.runner.json
|
|
31
|
+
-> generate synapsor.runner.json + canonical synapsor.contract.json
|
|
32
32
|
-> preview MCP tools exposed to the model
|
|
33
33
|
-> run a local smoke check of the tool boundary
|
|
34
34
|
-> optionally write .synapsor/smoke-input.json for one real row
|
|
35
|
-
->
|
|
35
|
+
-> open the secured localhost first-action workbench in an interactive terminal
|
|
36
36
|
```
|
|
37
37
|
|
|
38
38
|
It does not print your database URL, put the URL in MCP client config, expose
|
|
@@ -43,6 +43,11 @@ credentials.
|
|
|
43
43
|
`onboard db --from-env DATABASE_URL` is the same explicit path if you prefer the
|
|
44
44
|
older command name in scripts.
|
|
45
45
|
|
|
46
|
+
Interactive `start` opens the focused local workbench after config validation
|
|
47
|
+
and an MCP boundary handshake. Use `--no-open` for CI or scripts. That handshake
|
|
48
|
+
proves the reviewed tool surface; the workbench's **Test** step remains pending
|
|
49
|
+
until a real scoped read is recorded in the local ledger.
|
|
50
|
+
|
|
46
51
|
During the wizard, provide the optional sample object id if you know one safe
|
|
47
52
|
row in the selected table. Runner writes `./.synapsor/smoke-input.json` with
|
|
48
53
|
that id and prints the exact `smoke call` command. If you skip it, use
|
|
@@ -186,6 +191,95 @@ The wizard:
|
|
|
186
191
|
- writes the generated config, `.env.example`, and MCP client snippets only
|
|
187
192
|
after final confirmation.
|
|
188
193
|
|
|
194
|
+
The generated action is explicit about its activation state. Read-only and
|
|
195
|
+
shadow actions cannot commit. Review/writeback generation requires final
|
|
196
|
+
confirmation (`--yes` in a noninteractive command) and still gives the model no
|
|
197
|
+
approval or apply tool.
|
|
198
|
+
|
|
199
|
+
### Draft another Safe Action with a coding agent
|
|
200
|
+
|
|
201
|
+
After a reviewed read capability exists, describe one business action instead
|
|
202
|
+
of hand-authoring a complete contract:
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
synapsor-runner start \
|
|
206
|
+
--action plan_credit \
|
|
207
|
+
--description "Propose one reviewed customer plan credit" \
|
|
208
|
+
--based-on support.inspect_customer
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Runner writes `synapsor/actions/support.propose_plan_credit.ts` and scoped
|
|
212
|
+
agent instructions. The file is an inert scaffold. It contains explicit
|
|
213
|
+
authority questions for trusted scope, visible and kept-out fields, allowed
|
|
214
|
+
effect, conflict guard, bounds, approval, and executor. Creating or editing it
|
|
215
|
+
does not change the active contract or MCP tool list.
|
|
216
|
+
|
|
217
|
+
Give the exact prompt printed by the command to Cursor or another coding
|
|
218
|
+
agent. The agent may inspect project/schema evidence, complete the restricted
|
|
219
|
+
TypeScript object, and run deterministic validation:
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
synapsor-runner action validate \
|
|
223
|
+
./synapsor/actions/support.propose_plan_credit.ts
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
Runner statically parses rather than imports the file. A successful validation
|
|
227
|
+
writes a digest-addressed **disabled draft**, a plain-language explanation,
|
|
228
|
+
and exact static allow/deny/effect tests under `.synapsor/drafts/`. It cannot
|
|
229
|
+
activate a tool.
|
|
230
|
+
|
|
231
|
+
In the secured Workbench, run **Preview exact staging Data PR**. The preview
|
|
232
|
+
may perform the reviewed scoped read and write proposal evidence to the local
|
|
233
|
+
ledger, but it cannot mutate the source. Review the exact effect, type
|
|
234
|
+
`ACTIVATE` plus the complete displayed digest, and confirm activation yourself.
|
|
235
|
+
There is intentionally no CLI or MCP command a coding agent can use to
|
|
236
|
+
activate the draft. If the host does not refresh `tools/list`, reconnect the
|
|
237
|
+
MCP server after activation as the Workbench instructs.
|
|
238
|
+
|
|
239
|
+
## 5. Add the reviewed tools to Cursor
|
|
240
|
+
|
|
241
|
+
After setting trusted environment values, preview and install a project-scoped
|
|
242
|
+
entry without hand-editing `.cursor/mcp.json`:
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
synapsor-runner mcp install cursor --project --dry-run \
|
|
246
|
+
--config ./synapsor.runner.json \
|
|
247
|
+
--store ./.synapsor/local.db
|
|
248
|
+
synapsor-runner mcp install cursor --project --yes \
|
|
249
|
+
--config ./synapsor.runner.json \
|
|
250
|
+
--store ./.synapsor/local.db
|
|
251
|
+
synapsor-runner mcp status cursor --project --check-launch
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
Runner merges rather than replaces existing MCP servers, creates a backup,
|
|
255
|
+
records an integrity marker, and is idempotent. The entry uses an exact Runner
|
|
256
|
+
version and contains no database URL, trusted tenant/principal value, approval,
|
|
257
|
+
apply, or revert authority. Remove only the Runner-owned entry with:
|
|
258
|
+
|
|
259
|
+
```bash
|
|
260
|
+
synapsor-runner mcp uninstall cursor --project --yes
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
See the [host compatibility matrix](host-compatibility.md) for the precise
|
|
264
|
+
Cursor evidence and MCP Apps limitation.
|
|
265
|
+
|
|
266
|
+
## 6. Inspect local activation evidence
|
|
267
|
+
|
|
268
|
+
Runner records bounded timing milestones locally. It does not transmit them:
|
|
269
|
+
|
|
270
|
+
```bash
|
|
271
|
+
synapsor-runner activation show \
|
|
272
|
+
--config ./synapsor.runner.json \
|
|
273
|
+
--store ./.synapsor/local.db
|
|
274
|
+
synapsor-runner activation export \
|
|
275
|
+
--out ./.synapsor/activation-report.json
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
Product activation time begins after package installation; initial npm
|
|
279
|
+
resolution/download/cache time is measured separately when evaluating cold
|
|
280
|
+
`npx` behavior. The report contains milestone timing/status only, not source
|
|
281
|
+
rows, object IDs, tenant IDs, credentials, or project paths.
|
|
282
|
+
|
|
189
283
|
For proposal modes, the current runner supports explicit field-update mappings such as:
|
|
190
284
|
|
|
191
285
|
```text
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# MCP Host Compatibility
|
|
2
|
+
|
|
3
|
+
This matrix separates host evidence from protocol evidence. It was last
|
|
4
|
+
reviewed on 2026-07-20. A working MCP SDK handshake is not presented as proof
|
|
5
|
+
that a specific editor renders an extension or protects app-only controls.
|
|
6
|
+
|
|
7
|
+
| Host/surface | Status | Evidence and boundary |
|
|
8
|
+
| --- | --- | --- |
|
|
9
|
+
| Cursor project `.cursor/mcp.json` lifecycle | Tested | Runner install/status/uninstall tests cover preview, merge, backup, idempotency, ownership, tamper refusal, paths with spaces, and exact-version `npx` wiring. Local Cursor version observed: 3.7.21 (`517f696d8ab6c53eb04fbfdaae705cd146bf3460`, x64). |
|
|
10
|
+
| Cursor stdio Runner launch and `tools/list` | Protocol-tested | `mcp status cursor --project --check-launch` executes the generated command and checks the exact reviewed tools through the official MCP client transport. A final manual Cursor UI pass is still required for a release claim tied to that host version. |
|
|
11
|
+
| Cursor MCP Apps inline proposal card | Unknown | Runner advertises the standard display-only resource metadata, but current stable Cursor rendering and app-only authority guarantees have not been reproduced. Use the secured localhost workbench or operator CLI. |
|
|
12
|
+
| Cursor approval/apply/revert through MCP | Unsupported | Intentionally absent. Cursor may auto-run model-facing tools; commit authority therefore stays outside MCP regardless of host settings. |
|
|
13
|
+
| Generic Add to Cursor deep link | Unsupported | Runner does not generate a link because no current documented generic server payload has been verified end to end. Project install is the supported path. |
|
|
14
|
+
| Generic stdio MCP client | Protocol-tested | Official MCP SDK initialization, tool listing, calls, resources, and display-only Apps metadata are covered in the suite. |
|
|
15
|
+
| Generic Streamable HTTP MCP client | Protocol-tested | Official MCP SDK sessions, signed context, secret rotation, JWKS, mTLS, aliases, and session isolation are covered. |
|
|
16
|
+
| Claude Desktop | Protocol-tested | Packaged stdio configuration and MCP transport are tested; manual host UI behavior varies by version and remains a release checklist item. |
|
|
17
|
+
| Claude Code | Configuration-tested and protocol-tested | Claude Code 2.1.216 accepted the secret-free stdio configuration through `mcp add-json`; the same command completed MCP `tools/list`. A manual model-driven proposal call remains a release gate. |
|
|
18
|
+
| Codex | Configuration-tested and protocol-tested | Codex CLI 0.144.6 accepted the secret-free stdio configuration through `codex mcp add`; the same command completed MCP `tools/list`. A manual model-driven proposal call remains a release gate. |
|
|
19
|
+
| VS Code | Protocol-tested | The checked `.vscode/mcp.json` shape is parsed and the same stdio command completes MCP `tools/list`; manual editor UI behavior is not claimed. |
|
|
20
|
+
| OpenAI Agents SDK | Recipe-checked and protocol-tested | Packaged stdio/Streamable HTTP examples are syntax/safety checked and OpenAI-safe aliases are protocol-tested. The exact SDK agent call remains protocol-only until run with an owner-supplied API key. |
|
|
21
|
+
| LangChain/LangGraph | Recipe-checked, protocol-only | The current `@langchain/mcp-adapters` recipe lists tools, rejects unsafe authority, and calls the proposal tool. The framework runtime has not been executed in this release environment. |
|
|
22
|
+
| Google ADK | Recipe-checked, protocol-only | The current `McpToolset`/`StdioConnectionParams` recipe exposes only the two reviewed tools. The framework runtime has not been executed in this release environment. |
|
|
23
|
+
| LlamaIndex | Recipe-checked, protocol-only | The current `BasicMCPClient` recipe lists tools and calls the proposal tool. The framework runtime has not been executed in this release environment. |
|
|
24
|
+
|
|
25
|
+
## Cursor Project Setup
|
|
26
|
+
|
|
27
|
+
Current Cursor documentation supports project MCP configuration in
|
|
28
|
+
`.cursor/mcp.json`. Runner manages only its `synapsor` entry:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
synapsor-runner mcp install cursor --project --dry-run
|
|
32
|
+
synapsor-runner mcp install cursor --project --yes
|
|
33
|
+
synapsor-runner mcp status cursor --project --check-launch
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The generated entry contains command paths only. Database credentials and
|
|
37
|
+
trusted tenant/principal values must come from the environment that launches
|
|
38
|
+
Runner. Other Cursor MCP servers and settings are preserved.
|
|
39
|
+
|
|
40
|
+
Primary references:
|
|
41
|
+
|
|
42
|
+
- [Cursor MCP documentation](https://cursor.com/docs/context/mcp)
|
|
43
|
+
- [MCP TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk)
|
|
44
|
+
- [MCP Apps specification](https://github.com/modelcontextprotocol/ext-apps/blob/main/specification/2026-01-26/apps.mdx)
|
|
45
|
+
|
|
46
|
+
All adjacent-host source links, runnable snippets, shared proposal input, and
|
|
47
|
+
verification commands are in [Client And Framework Recipes](client-recipes.md).
|
|
48
|
+
|
|
49
|
+
## Authority Fallback
|
|
50
|
+
|
|
51
|
+
Hosts without a verified app-only human-control boundary receive the same
|
|
52
|
+
structured/text proposal result and can open the secured loopback workbench.
|
|
53
|
+
Approval, rejection, apply, compensation, policy activation, trusted identity,
|
|
54
|
+
and credentials never enter model-visible `tools/list`. Runner does not infer
|
|
55
|
+
host safety from a product name or user-agent string.
|
|
56
|
+
|
|
57
|
+
Runner currently exposes tools, not MCP prompts or an elicitation-based
|
|
58
|
+
approval flow. First-run setup and approval do not depend on optional host
|
|
59
|
+
prompt/elicitation support.
|
package/docs/local-mode.md
CHANGED
|
@@ -32,11 +32,12 @@ Current local-mode foundation:
|
|
|
32
32
|
|
|
33
33
|
Runtime requirement:
|
|
34
34
|
|
|
35
|
-
The stable package requires Node >= 22.
|
|
36
|
-
ledger uses Node's `node:sqlite` runtime.
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
The stable package requires Node >= 22.13.0 because the local evidence/replay
|
|
36
|
+
ledger uses Node's unflagged `node:sqlite` runtime. Earlier Node 22 releases
|
|
37
|
+
require an experimental flag and are not supported. The published package
|
|
38
|
+
declares that engine requirement and the CLI exits early with a clear message
|
|
39
|
+
on older Node versions. The Docker-backed demo remains the recommended path
|
|
40
|
+
when you do not want to change your host Node version.
|
|
40
41
|
|
|
41
42
|
## Initialize a config
|
|
42
43
|
|
package/docs/mcp-audit.md
CHANGED
|
@@ -8,7 +8,10 @@ available for users who look for the command under the MCP namespace.
|
|
|
8
8
|
From a source checkout, use `./bin/synapsor-runner ...` if the global binary is not
|
|
9
9
|
linked yet.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Static mode does not launch configured MCP servers or call business tools. It
|
|
12
|
+
only inspects names, descriptions, input schemas, output schemas, annotations,
|
|
13
|
+
and examples when those are present. An explicitly consented live check calls
|
|
14
|
+
only `initialize` and `tools/list` on one named server.
|
|
12
15
|
|
|
13
16
|
Every report includes this disclaimer:
|
|
14
17
|
|
|
@@ -86,6 +89,36 @@ Markdown output for issues, PRs, or security review notes:
|
|
|
86
89
|
npx -y -p @synapsor/runner synapsor-runner audit --example dangerous-db-mcp --format markdown
|
|
87
90
|
```
|
|
88
91
|
|
|
92
|
+
Inspect a project-scoped Cursor configuration without launching anything:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
npx -y -p @synapsor/runner synapsor-runner audit \
|
|
96
|
+
--mcp-config ./.cursor/mcp.json \
|
|
97
|
+
--format markdown
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Static client-config output marks every server without supplied tool metadata
|
|
101
|
+
as `requires_operator_verification`. To query one reviewed stdio command, name
|
|
102
|
+
that exact server and give explicit consent:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
npx -y -p @synapsor/runner synapsor-runner audit \
|
|
106
|
+
--mcp-config ./.cursor/mcp.json \
|
|
107
|
+
--live-server synapsor \
|
|
108
|
+
--yes \
|
|
109
|
+
--format json
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Runner does not use a shell and refuses unresolved interpolation. For Cursor's
|
|
113
|
+
documented `${workspaceFolder}` token, a config under `.cursor/mcp.json`
|
|
114
|
+
resolves against the project root. Live mode executes no business, approval,
|
|
115
|
+
apply, commit, or revert tool. It cannot prove the selected server is secure.
|
|
116
|
+
|
|
117
|
+
The bypass check matters after installing Runner: another model-visible MCP
|
|
118
|
+
server may still expose `execute_sql` or a direct write. Synapsor cannot govern
|
|
119
|
+
calls routed around Runner. Audit reports the server and observed tool names,
|
|
120
|
+
but never removes or rewrites unrelated MCP configuration automatically.
|
|
121
|
+
|
|
89
122
|
During local development, the repo-local wrapper can run the same command:
|
|
90
123
|
|
|
91
124
|
```bash
|
|
@@ -104,6 +137,19 @@ npx -y -p @synapsor/runner synapsor-runner audit generate \
|
|
|
104
137
|
--output ./synapsor-audit-candidates
|
|
105
138
|
```
|
|
106
139
|
|
|
140
|
+
Open the same blocked candidate directly in the secured local review
|
|
141
|
+
workbench:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
npx -y -p @synapsor/runner synapsor-runner audit generate \
|
|
145
|
+
./tools-list.json \
|
|
146
|
+
--output ./synapsor-audit-candidates \
|
|
147
|
+
--open-ui
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
This does not activate the candidate. The generated Runner config has no source
|
|
151
|
+
and every proposal writeback is `none`.
|
|
152
|
+
|
|
107
153
|
The generator uses the same parser and findings as `audit`. It writes:
|
|
108
154
|
|
|
109
155
|
- a canonical `@synapsor/spec` contract;
|
|
@@ -147,7 +193,33 @@ The audit accepts common exported shapes:
|
|
|
147
193
|
|
|
148
194
|
It also scans nested `adapter`, `mcpServers`, and `servers` blocks when they include tool metadata.
|
|
149
195
|
|
|
150
|
-
For live targets, the audit
|
|
196
|
+
For live stdio targets, the audit performs MCP `initialize`, then calls only
|
|
197
|
+
JSON-RPC `tools/list`. Remote URL mode calls `tools/list`. It does not call
|
|
198
|
+
business tools, approval tools, commit tools, or writeback tools.
|
|
199
|
+
|
|
200
|
+
Checked-in deterministic fixtures live under
|
|
201
|
+
[`fixtures/mcp-audit`](../fixtures/mcp-audit). The repository's
|
|
202
|
+
[`mcp-audit` GitHub Actions workflow](https://github.com/Synapsor/Synapsor-Runner/blob/main/.github/workflows/mcp-audit.yml)
|
|
203
|
+
builds the package, proves the dangerous fixture is detected, emits SARIF for
|
|
204
|
+
the reviewed proposal fixture, validates the SARIF shape, and uploads the
|
|
205
|
+
artifacts. Code-scanning upload runs only outside pull requests so forks do not
|
|
206
|
+
receive write authority.
|
|
207
|
+
|
|
208
|
+
## Model-authority map
|
|
209
|
+
|
|
210
|
+
Every text, JSON, Markdown, and SARIF report records structural evidence for:
|
|
211
|
+
|
|
212
|
+
- semantic reads and semantic proposals;
|
|
213
|
+
- direct writes and raw SQL/query authority;
|
|
214
|
+
- arbitrary identifier and model-controlled trust inputs;
|
|
215
|
+
- model-visible approval/apply/commit/revert authority;
|
|
216
|
+
- structured output and observable conflict/idempotency signals;
|
|
217
|
+
- controls that require an operator or sit outside static audit visibility.
|
|
218
|
+
|
|
219
|
+
Statuses are `observed`, `not_observed`, `requires_operator_verification`, or
|
|
220
|
+
`outside_static_audit_visibility`. These are evidence labels, not a numerical
|
|
221
|
+
security score. `not_observed` means only that the supplied metadata did not
|
|
222
|
+
show the authority. It is not proof of absence at runtime.
|
|
151
223
|
|
|
152
224
|
## Findings
|
|
153
225
|
|
|
@@ -164,6 +236,85 @@ The audit flags database-commit risks such as:
|
|
|
164
236
|
- ambiguous read/write tool boundaries;
|
|
165
237
|
- missing business descriptions, annotations, or fixture examples.
|
|
166
238
|
|
|
239
|
+
### Finding remediation index
|
|
240
|
+
|
|
241
|
+
The report carries one stable remediation URL for every finding. These anchors
|
|
242
|
+
are intentionally durable for JSON, Markdown, SARIF, pull requests, and code
|
|
243
|
+
scanning.
|
|
244
|
+
|
|
245
|
+
<a id="finding-generic-sql-tool"></a>
|
|
246
|
+
<a id="finding-write-tool-accepts-arbitrary-sql"></a>
|
|
247
|
+
<a id="finding-arbitrary-identifier-input"></a>
|
|
248
|
+
<a id="finding-arbitrary-predicate-input"></a>
|
|
249
|
+
|
|
250
|
+
#### Raw SQL, arbitrary identifiers, and free-form predicates
|
|
251
|
+
|
|
252
|
+
Replace generic SQL/query tools and model-selected schemas, tables, databases,
|
|
253
|
+
columns, filters, predicates, or WHERE clauses with a reviewed semantic
|
|
254
|
+
capability. Fixed identifiers and row-selection rules belong in the contract;
|
|
255
|
+
model inputs carry bounded business values only.
|
|
256
|
+
|
|
257
|
+
<a id="finding-model-controlled-trust-scope"></a>
|
|
258
|
+
|
|
259
|
+
#### Model-controlled trust scope
|
|
260
|
+
|
|
261
|
+
Bind tenant, principal, source, allowed fields, approval identity, and conflict
|
|
262
|
+
authority from verified context outside model arguments. Retain database RLS,
|
|
263
|
+
restricted views, and least-privilege roles underneath Runner.
|
|
264
|
+
|
|
265
|
+
<a id="finding-model-callable-commit-or-approval"></a>
|
|
266
|
+
<a id="finding-write-without-proposal-boundary"></a>
|
|
267
|
+
<a id="finding-mcp-bypass-direct-authority"></a>
|
|
268
|
+
|
|
269
|
+
#### Missing review boundary or bypass
|
|
270
|
+
|
|
271
|
+
Expose an immutable proposal rather than direct mutation. Keep activation,
|
|
272
|
+
approval, apply, commit, and revert outside MCP. Disable or independently
|
|
273
|
+
constrain another model-visible server that bypasses Runner; Synapsor cannot
|
|
274
|
+
govern calls made through that server.
|
|
275
|
+
|
|
276
|
+
<a id="finding-no-idempotency-field"></a>
|
|
277
|
+
<a id="finding-no-conflict-guard"></a>
|
|
278
|
+
<a id="finding-ambiguous-read-write-tool"></a>
|
|
279
|
+
|
|
280
|
+
#### Retry, stale-state, and mixed-authority gaps
|
|
281
|
+
|
|
282
|
+
Separate reads from proposals and require stable operation identity,
|
|
283
|
+
idempotency receipts, an exact conflict/version guard, and an affected-row
|
|
284
|
+
bound before trusted writeback.
|
|
285
|
+
|
|
286
|
+
<a id="finding-no-structured-output-schema"></a>
|
|
287
|
+
|
|
288
|
+
#### Missing structured output
|
|
289
|
+
|
|
290
|
+
Publish typed results that distinguish reads, pending proposals, conflicts,
|
|
291
|
+
failures, receipts, evidence, replay, and retry guidance without parsing prose.
|
|
292
|
+
|
|
293
|
+
<a id="finding-missing-business-description"></a>
|
|
294
|
+
<a id="finding-missing-risk-annotations"></a>
|
|
295
|
+
<a id="finding-missing-test-fixture"></a>
|
|
296
|
+
|
|
297
|
+
#### Reviewability gaps
|
|
298
|
+
|
|
299
|
+
Add a reviewer-readable business description, honest read/destructive hints,
|
|
300
|
+
and a non-production fixture. Annotations are vocabulary for clients, not an
|
|
301
|
+
enforcement boundary.
|
|
302
|
+
|
|
303
|
+
<a id="finding-mcp-server-tool-surface-unverified"></a>
|
|
304
|
+
|
|
305
|
+
#### Unverified configured server
|
|
306
|
+
|
|
307
|
+
Export that server's `tools/list`, or run the exact named `--live-server` check
|
|
308
|
+
after reviewing its configured command. Static client configuration does not
|
|
309
|
+
reveal the actual tool catalog.
|
|
310
|
+
|
|
311
|
+
<a id="finding-no-tools-found"></a>
|
|
312
|
+
|
|
313
|
+
#### No tools found
|
|
314
|
+
|
|
315
|
+
Provide an exported `tools/list` response, a supported manifest, a Runner
|
|
316
|
+
config, or an explicitly consented live target.
|
|
317
|
+
|
|
167
318
|
## Recommended target shape
|
|
168
319
|
|
|
169
320
|
A safer model-facing database MCP tool should look like a reviewed semantic proposal capability:
|
|
@@ -205,6 +356,19 @@ A safer model-facing database MCP tool should look like a reviewed semantic prop
|
|
|
205
356
|
|
|
206
357
|
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.
|
|
207
358
|
|
|
359
|
+
To turn an identified business write into a disabled reviewed action, continue
|
|
360
|
+
with the Safe Action Composer:
|
|
361
|
+
|
|
362
|
+
```bash
|
|
363
|
+
synapsor-runner start \
|
|
364
|
+
--action refund_order \
|
|
365
|
+
--description "Propose one reviewed order refund"
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
The generated TypeScript action remains disabled. A coding agent may complete
|
|
369
|
+
and validate it; only a human can activate its exact digest in the secured
|
|
370
|
+
localhost Workbench.
|
|
371
|
+
|
|
208
372
|
## Related Fixture Benchmark
|
|
209
373
|
|
|
210
374
|
`synapsor-runner benchmark mcp-efficiency` compares a fixed generic database
|
package/docs/mcp-client-setup.md
CHANGED
|
@@ -11,6 +11,10 @@ or SDK. The simplest local-client contract is stdio. Standard HTTP MCP is
|
|
|
11
11
|
available through Streamable HTTP when your agent connects to a long-running
|
|
12
12
|
Runner service.
|
|
13
13
|
|
|
14
|
+
The checked [Client And Framework Recipes](client-recipes.md) use one shared
|
|
15
|
+
`support.propose_plan_credit` flow and distinguish host evidence from standard
|
|
16
|
+
MCP protocol evidence.
|
|
17
|
+
|
|
14
18
|
Proposal tools also advertise a standard display-only
|
|
15
19
|
[MCP App](mcp-apps.md). Supporting hosts discover it from tool metadata;
|
|
16
20
|
other clients keep the same text/JSON proposal result. Approval and apply
|
package/docs/mcp-clients.md
CHANGED
|
@@ -15,6 +15,11 @@ The complete copy-paste templates live in:
|
|
|
15
15
|
- every local `synapsor-runner contract bundle` output;
|
|
16
16
|
- every downloadable Synapsor Cloud runner bundle.
|
|
17
17
|
|
|
18
|
+
For one shared proposal call across Claude Code, Codex, VS Code, OpenAI Agents,
|
|
19
|
+
LangChain/LangGraph, Google ADK, LlamaIndex, and generic MCP clients, see
|
|
20
|
+
[Client And Framework Recipes](client-recipes.md). Each recipe states whether
|
|
21
|
+
it is host-tested, configuration-tested, protocol-tested, or recipe-only.
|
|
22
|
+
|
|
18
23
|
Before connecting a client, validate the local boundary:
|
|
19
24
|
|
|
20
25
|
```bash
|
|
@@ -62,15 +67,39 @@ repository file.
|
|
|
62
67
|
|
|
63
68
|
### Cursor
|
|
64
69
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
70
|
+
Prefer Runner's owned project lifecycle for one repository:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
synapsor-runner mcp install cursor --project --dry-run \
|
|
74
|
+
--config ./synapsor.runner.json \
|
|
75
|
+
--store ./.synapsor/local.db
|
|
76
|
+
synapsor-runner mcp install cursor --project --yes \
|
|
77
|
+
--config ./synapsor.runner.json \
|
|
78
|
+
--store ./.synapsor/local.db
|
|
79
|
+
synapsor-runner mcp status cursor --project --check-launch
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Runner previews the merge, backs up an existing `.cursor/mcp.json`, preserves
|
|
83
|
+
other MCP servers/settings, writes an exact-version `npx` invocation, and
|
|
84
|
+
tracks only its own entry with an integrity marker. Repeating install is
|
|
85
|
+
idempotent. `mcp uninstall cursor --project --yes` removes only that intact,
|
|
86
|
+
Runner-owned entry and also creates a backup.
|
|
87
|
+
|
|
88
|
+
For global setup, merge `cursor-global.mcp.json` through Cursor's MCP settings
|
|
89
|
+
and replace every `<absolute-path-to-bundle>` marker. Restart the MCP server
|
|
90
|
+
from Cursor settings after editing.
|
|
69
91
|
|
|
70
92
|
The model-facing list should contain only the contract's inspect/propose tools.
|
|
71
93
|
If Cursor reports a missing config or store, use absolute paths and rerun
|
|
72
94
|
`tools preview` from the same working directory.
|
|
73
95
|
|
|
96
|
+
Cursor can be configured to auto-run model-facing tools. Synapsor therefore
|
|
97
|
+
never exposes approval, apply, revert, policy activation, trusted identity, or
|
|
98
|
+
credentials as MCP tools. Inline MCP App review is not assumed for Cursor; use
|
|
99
|
+
the secured localhost workbench or operator CLI. No Add to Cursor deep link is
|
|
100
|
+
generated because Runner has not verified a currently documented generic
|
|
101
|
+
payload for this server. See [Host Compatibility](host-compatibility.md).
|
|
102
|
+
|
|
74
103
|
### OpenAI Agents SDK
|
|
75
104
|
|
|
76
105
|
Install the SDK in your agent project and run either TypeScript template:
|
package/docs/oss-vs-cloud.md
CHANGED
|
@@ -22,6 +22,7 @@ runtime stay local.
|
|
|
22
22
|
| Contract source | Local files reviewed in Git | Shared registry with immutable versions and digests |
|
|
23
23
|
| Trusted context | Local environment/session bindings | Registered bindings plus deployment-specific Cloud session context |
|
|
24
24
|
| Capabilities | Local semantic MCP tools | Registry, version history, and capability inspection |
|
|
25
|
+
| Safe Action activation | Explicit digest-confirmed local Workbench activation after a source-unchanged staging Data PR | Governed Cloud activation and immutable registry version; local coding agents still cannot activate |
|
|
25
26
|
| Evidence and replay | Local SQLite ledger by default; optional shared Postgres runtime store | Redacted shared chronology and references; full evidence payload stays local by default |
|
|
26
27
|
| Approval | Local CLI or localhost UI | Human-authenticated shared approval inbox; unavailable to MCP/Runner tokens |
|
|
27
28
|
| Writeback | Guarded one-row CRUD, fixed/frozen bounded sets, or app-owned executor | Durable approval/job/lease coordination; the local Runner rechecks and executes |
|
|
@@ -36,6 +37,8 @@ runtime stay local.
|
|
|
36
37
|
- direct access to Postgres or MySQL;
|
|
37
38
|
- the process that executes guarded writeback;
|
|
38
39
|
- local development ledgers when Cloud linkage is not enabled.
|
|
40
|
+
- local disabled Safe Action drafts, project agent instructions, and source
|
|
41
|
+
database preview/writeback execution.
|
|
39
42
|
|
|
40
43
|
Cloud contract registration does not require uploading database credentials or
|
|
41
44
|
business rows. A Runner bundle contains the normalized contract, placeholder
|