@synapsor/runner 1.5.3 → 1.6.0
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 +82 -2
- package/README.md +131 -130
- package/dist/authoring.mjs +405 -9
- package/dist/cli.d.ts.map +1 -1
- package/dist/local-ui.d.ts +2 -0
- package/dist/local-ui.d.ts.map +1 -1
- package/dist/runner.mjs +19532 -14246
- package/dist/runtime.mjs +10856 -8495
- package/dist/shadow.mjs +101 -1
- package/docs/README.md +14 -6
- package/docs/aggregate-reads.md +22 -0
- package/docs/auto-boundary-and-scoped-explore.md +338 -0
- package/docs/capability-authoring.md +36 -1
- package/docs/cloud-mode.md +18 -0
- package/docs/conformance.md +16 -0
- package/docs/current-scope.md +55 -28
- package/docs/cursor-plugin.md +20 -3
- package/docs/database-enforced-scope.md +8 -0
- package/docs/dsl-reference.md +123 -4
- package/docs/getting-started-own-database.md +42 -35
- package/docs/guarded-crud-writeback.md +10 -1
- package/docs/http-mcp.md +222 -207
- package/docs/limitations.md +33 -9
- package/docs/local-mode.md +5 -2
- package/docs/mcp-client-setup.md +24 -11
- package/docs/mcp-clients.md +10 -4
- package/docs/openai-agents-sdk.md +16 -2
- package/docs/production.md +72 -7
- package/docs/release-notes.md +77 -3
- package/docs/runner-bundles.md +7 -2
- package/docs/runner-config-reference.md +96 -6
- package/docs/running-a-runner-fleet.md +42 -13
- package/docs/schema-api-candidates.md +28 -1
- package/docs/security-boundary.md +38 -3
- package/docs/store-lifecycle.md +93 -5
- package/docs/troubleshooting-first-run.md +98 -0
- package/examples/auto-boundary-churn/README.md +23 -0
- package/examples/auto-boundary-churn/app/page.tsx +8 -0
- package/examples/auto-boundary-churn/docker-compose.yml +16 -0
- package/examples/auto-boundary-churn/package.json +18 -0
- package/examples/auto-boundary-churn/prisma/schema.prisma +36 -0
- package/examples/auto-boundary-churn/seed/postgres.sql +126 -0
- package/examples/openai-agents-http/README.md +10 -4
- package/examples/openai-agents-http/agent.py +2 -2
- package/examples/runner-fleet/Dockerfile +7 -2
- package/examples/runner-fleet/README.md +11 -7
- package/examples/runner-fleet/docker-compose.yml +4 -4
- package/examples/runner-fleet/mint-dev-token.mjs +1 -1
- package/examples/runner-fleet/start-tls-runner.sh +21 -0
- package/examples/runner-fleet/synapsor.runner.json +27 -1
- package/examples/support-plan-credit/README.md +6 -1
- package/examples/support-plan-credit/mcp-client-examples/generic-streamable-http.json +4 -1
- package/examples/support-plan-credit/mcp-client-examples/openai-agents-streamable-http.ts +4 -0
- package/examples/support-plan-credit/synapsor.contract.json +0 -3
- package/fixtures/compatibility/published-1.5.4/manifest.json +76 -0
- package/fixtures/compatibility/published-1.5.4/sources/packages/dsl/examples/aggregate-read.synapsor.sql +21 -0
- package/fixtures/compatibility/published-1.5.4/sources/packages/dsl/examples/billing-late-fee.synapsor.sql +56 -0
- package/fixtures/compatibility/published-1.5.4/sources/packages/dsl/examples/bounded-set-multi-term.synapsor.sql +30 -0
- package/fixtures/compatibility/published-1.5.4/sources/packages/dsl/examples/principal-row-scope.synapsor.sql +23 -0
- package/fixtures/compatibility/published-1.5.4/sources/packages/spec/fixtures/conformance/aggregate-read/contract.json +119 -0
- package/fixtures/compatibility/published-1.5.4/sources/packages/spec/fixtures/conformance/approval-quorum/contract.json +44 -0
- package/fixtures/compatibility/published-1.5.4/sources/packages/spec/fixtures/conformance/bounded-set-threats/contract.json +115 -0
- package/fixtures/compatibility/published-1.5.4/sources/packages/spec/fixtures/conformance/principal-row-scope/contract.json +78 -0
- package/fixtures/compatibility/published-1.5.4/sources/packages/spec/fixtures/conformance/proposal-capability/contract.json +101 -0
- package/fixtures/compatibility/published-1.5.4/sources/packages/spec/fixtures/conformance/reversible-change-sets/contract.json +98 -0
- package/fixtures/compatibility/published-1.5.4/sources/packages/spec/fixtures/valid/basic-read.contract.json +60 -0
- package/llms.txt +37 -0
- package/package.json +7 -4
- package/schemas/synapsor.runner.schema.json +98 -1
package/docs/http-mcp.md
CHANGED
|
@@ -1,44 +1,55 @@
|
|
|
1
1
|
# HTTP MCP
|
|
2
2
|
|
|
3
|
-
Use HTTP
|
|
4
|
-
|
|
3
|
+
Use HTTP when an application, server-side agent, container, or remote MCP client
|
|
4
|
+
connects to a long-running Synapsor Runner. Prefer stdio when one local desktop
|
|
5
|
+
client can launch Runner directly: stdio opens no network socket and needs no
|
|
6
|
+
HTTP credential, TLS setup, OAuth flow, or MCP HTTP session.
|
|
5
7
|
|
|
6
|
-
|
|
7
|
-
local agent tool can launch Synapsor Runner directly.
|
|
8
|
+
Runner provides:
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
- `mcp serve-streamable-http`: standard MCP Streamable HTTP using the official
|
|
11
|
+
MCP SDK. This is the normal HTTP endpoint.
|
|
12
|
+
- `mcp serve-http`: a legacy JSON-RPC bridge with `tools/list`, `tools/call`, and
|
|
13
|
+
`resources/read`. It has the same network-channel hardening but no standard
|
|
14
|
+
MCP session and therefore cannot use per-session `http_claims` identity.
|
|
10
15
|
|
|
11
|
-
|
|
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.
|
|
16
|
+
## Authentication Concepts
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
These are separate controls:
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
| Control | Meaning |
|
|
21
|
+
| --- | --- |
|
|
22
|
+
| TLS | Encrypts the network channel and authenticates the server certificate. |
|
|
23
|
+
| mTLS | Also authenticates a client workload certificate. It supplements Bearer auth in Runner. |
|
|
24
|
+
| HTTP Bearer | The HTTP presentation scheme: `Authorization: Bearer <credential>`. It does not imply that the credential is a JWT. |
|
|
25
|
+
| Opaque endpoint token | One high-entropy service credential for loopback or an explicitly single-tenant service. It is not user or tenant identity. |
|
|
26
|
+
| Signed JWT | A short-lived identity-provider-issued access token whose signature, algorithm, issuer, audience/resource, time, scope, tenant, and principal claims Runner verifies. |
|
|
27
|
+
| MCP session ID | Routes requests to initialized MCP state. It is not authentication. |
|
|
28
|
+
| Trusted context | The tenant and principal Runner binds after authentication. Model arguments, arbitrary headers, query strings, forwarded headers, and MCP metadata are never trusted context. |
|
|
22
29
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
+
Runner does not issue endpoint tokens, JWTs, refresh tokens, or end-user
|
|
31
|
+
passwords. An operator generates and distributes an opaque token out of band.
|
|
32
|
+
For a shared deployment, an external identity provider or authorization server
|
|
33
|
+
issues JWT access tokens; Runner is only the protected resource that verifies
|
|
34
|
+
them.
|
|
35
|
+
|
|
36
|
+
## Deployment Profiles
|
|
30
37
|
|
|
31
|
-
|
|
32
|
-
|
|
38
|
+
### Local loopback with an opaque token
|
|
39
|
+
|
|
40
|
+
Generate at least 32 random bytes. The same environment variable must be
|
|
41
|
+
available to Runner and the authorized local client; the value is never placed
|
|
42
|
+
in config JSON or a generated client file.
|
|
33
43
|
|
|
34
44
|
```bash
|
|
45
|
+
export SYNAPSOR_RUNNER_HTTP_TOKEN="$(node -e 'process.stdout.write(require("node:crypto").randomBytes(32).toString("base64url"))')"
|
|
46
|
+
|
|
35
47
|
synapsor-runner mcp serve-streamable-http \
|
|
36
48
|
--host 127.0.0.1 \
|
|
37
49
|
--port 8766 \
|
|
38
50
|
--config ./synapsor.runner.json \
|
|
39
51
|
--store ./.synapsor/local.db \
|
|
40
|
-
--auth-token-env SYNAPSOR_RUNNER_HTTP_TOKEN
|
|
41
|
-
--alias-mode openai
|
|
52
|
+
--auth-token-env SYNAPSOR_RUNNER_HTTP_TOKEN
|
|
42
53
|
```
|
|
43
54
|
|
|
44
55
|
Equivalent unified command:
|
|
@@ -50,34 +61,57 @@ synapsor-runner mcp serve \
|
|
|
50
61
|
--port 8766 \
|
|
51
62
|
--config ./synapsor.runner.json \
|
|
52
63
|
--store ./.synapsor/local.db \
|
|
53
|
-
--auth-token-env SYNAPSOR_RUNNER_HTTP_TOKEN
|
|
54
|
-
--alias-mode openai
|
|
64
|
+
--auth-token-env SYNAPSOR_RUNNER_HTTP_TOKEN
|
|
55
65
|
```
|
|
56
66
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
the canonical Synapsor capability such as `billing.inspect_invoice`. Use
|
|
60
|
-
`--alias-mode both` only during migrations where some clients still need
|
|
61
|
-
canonical dotted names.
|
|
67
|
+
`--dev-no-auth` is accepted only for an explicit loopback development run. It
|
|
68
|
+
is refused for wildcard, private-network, and public binds.
|
|
62
69
|
|
|
63
|
-
|
|
70
|
+
### Remote single-tenant service
|
|
64
71
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
72
|
+
Declare the service and channel in Runner deployment config. This wiring is not
|
|
73
|
+
part of the portable Synapsor contract:
|
|
74
|
+
|
|
75
|
+
```json
|
|
76
|
+
{
|
|
77
|
+
"http_security": {
|
|
78
|
+
"deployment": "single_tenant",
|
|
79
|
+
"channel": "trusted_tls_proxy",
|
|
80
|
+
"static_token": {
|
|
81
|
+
"active_env": "SYNAPSOR_RUNNER_HTTP_TOKEN",
|
|
82
|
+
"previous_env": "SYNAPSOR_RUNNER_HTTP_TOKEN_PREVIOUS"
|
|
83
|
+
},
|
|
84
|
+
"allowed_hosts": ["runner.internal.example"],
|
|
85
|
+
"allowed_origins": ["https://agent-console.example"]
|
|
86
|
+
}
|
|
87
|
+
}
|
|
71
88
|
```
|
|
72
89
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
90
|
+
The supported protected channels are:
|
|
91
|
+
|
|
92
|
+
1. Runner-owned TLS, selected by supplying certificate and key env references.
|
|
93
|
+
2. `trusted_tls_proxy`, where a trusted proxy terminates TLS and a firewall or
|
|
94
|
+
private network prevents direct client access to Runner.
|
|
95
|
+
3. `insecure_http_break_glass`, an authenticated but interceptable emergency
|
|
96
|
+
mode. It emits a security warning and is not appropriate for normal use.
|
|
76
97
|
|
|
77
|
-
|
|
98
|
+
A non-loopback listener with no explicit channel refuses to start before it
|
|
99
|
+
binds. Break glass never disables authentication.
|
|
78
100
|
|
|
79
|
-
|
|
80
|
-
|
|
101
|
+
Trusted TLS proxy:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
synapsor-runner mcp serve-streamable-http \
|
|
105
|
+
--host 0.0.0.0 \
|
|
106
|
+
--port 8766 \
|
|
107
|
+
--config ./synapsor.runner.json \
|
|
108
|
+
--store ./.synapsor/local.db \
|
|
109
|
+
--trusted-tls-proxy \
|
|
110
|
+
--auth-token-env SYNAPSOR_RUNNER_HTTP_TOKEN \
|
|
111
|
+
--previous-auth-token-env SYNAPSOR_RUNNER_HTTP_TOKEN_PREVIOUS
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Runner-owned TLS:
|
|
81
115
|
|
|
82
116
|
```bash
|
|
83
117
|
export SYNAPSOR_TLS_CERT_PEM="$(cat ./server.crt)"
|
|
@@ -93,7 +127,7 @@ synapsor-runner mcp serve-streamable-http \
|
|
|
93
127
|
--tls-key-env SYNAPSOR_TLS_KEY_PEM
|
|
94
128
|
```
|
|
95
129
|
|
|
96
|
-
|
|
130
|
+
For mTLS, add a protected client CA bundle:
|
|
97
131
|
|
|
98
132
|
```bash
|
|
99
133
|
export SYNAPSOR_TLS_CA_PEM="$(cat ./client-ca.crt)"
|
|
@@ -110,211 +144,192 @@ synapsor-runner mcp serve-streamable-http \
|
|
|
110
144
|
--require-client-cert
|
|
111
145
|
```
|
|
112
146
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
app-owned `http_handler` executors, terminate mTLS in your service mesh/proxy
|
|
116
|
-
or handler process and keep bearer/signature checks enabled in the handler.
|
|
147
|
+
mTLS authenticates a workload certificate in addition to the Bearer credential.
|
|
148
|
+
It does not turn a shared opaque token into per-user or per-tenant identity.
|
|
117
149
|
|
|
118
|
-
|
|
150
|
+
### Shared multi-user or multi-tenant service
|
|
119
151
|
|
|
120
|
-
|
|
121
|
-
|
|
152
|
+
Use verified signed session identity. A static endpoint token is intentionally
|
|
153
|
+
insufficient as trusted tenant/principal authority.
|
|
122
154
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
155
|
+
```json
|
|
156
|
+
{
|
|
157
|
+
"trusted_context": {
|
|
158
|
+
"provider": "http_claims",
|
|
159
|
+
"values": {
|
|
160
|
+
"tenant_id_key": "tenant_id",
|
|
161
|
+
"principal_key": "sub"
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
"session_auth": {
|
|
165
|
+
"provider": "jwt_asymmetric",
|
|
166
|
+
"algorithms": ["ES256"],
|
|
167
|
+
"jwks_url_env": "SYNAPSOR_SESSION_JWKS_URL",
|
|
168
|
+
"issuer": "https://identity.example",
|
|
169
|
+
"audience": "https://runner.example/mcp",
|
|
170
|
+
"tenant_claim": "tenant_id",
|
|
171
|
+
"principal_claim": "sub",
|
|
172
|
+
"clock_skew_seconds": 30
|
|
173
|
+
},
|
|
174
|
+
"http_security": {
|
|
175
|
+
"deployment": "shared",
|
|
176
|
+
"channel": "trusted_tls_proxy",
|
|
177
|
+
"oauth_resource": {
|
|
178
|
+
"resource": "https://runner.example/mcp",
|
|
179
|
+
"authorization_servers": ["https://identity.example"],
|
|
180
|
+
"scopes_supported": ["synapsor:mcp"],
|
|
181
|
+
"required_scopes": ["synapsor:mcp"],
|
|
182
|
+
"resource_name": "Synapsor Runner"
|
|
183
|
+
},
|
|
184
|
+
"allowed_hosts": ["runner.example"],
|
|
185
|
+
"allowed_origins": ["https://agent-console.example"]
|
|
186
|
+
}
|
|
187
|
+
}
|
|
129
188
|
```
|
|
130
189
|
|
|
131
|
-
|
|
190
|
+
The identity provider publishes the public JWKS URL stored in
|
|
191
|
+
`SYNAPSOR_SESSION_JWKS_URL`. The client obtains a short-lived access token from
|
|
192
|
+
that provider through the provider-supported OAuth/OIDC flow and sends it in the
|
|
193
|
+
Bearer header. Runner then validates, on every request including requests for an
|
|
194
|
+
existing MCP session:
|
|
132
195
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
196
|
+
- allowed `RS256` or `ES256` algorithm and signature;
|
|
197
|
+
- public `kid` selection and bounded JWKS refresh/cache behavior;
|
|
198
|
+
- exact issuer and audience/resource;
|
|
199
|
+
- expiry, not-before, and configured clock skew;
|
|
200
|
+
- configured required scopes;
|
|
201
|
+
- bounded scalar tenant and principal claims.
|
|
139
202
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
203
|
+
The audience must exactly equal `http_security.oauth_resource.resource`.
|
|
204
|
+
Unverified headers such as `X-Tenant-Id` and all `Forwarded`/`X-Forwarded-*`
|
|
205
|
+
values never become trusted identity.
|
|
143
206
|
|
|
144
|
-
|
|
145
|
-
variable name. It does not print token values or database URLs.
|
|
207
|
+
Runner exposes RFC 9728 protected-resource metadata at the current MCP path:
|
|
146
208
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
```bash
|
|
150
|
-
curl -i http://127.0.0.1:8766/healthz
|
|
151
|
-
curl -i http://127.0.0.1:8765/healthz
|
|
152
|
-
curl -i http://127.0.0.1:8766/readyz
|
|
209
|
+
```text
|
|
210
|
+
/.well-known/oauth-protected-resource/mcp
|
|
153
211
|
```
|
|
154
212
|
|
|
155
|
-
|
|
213
|
+
An unauthenticated MCP request receives a `401` Bearer challenge containing the
|
|
214
|
+
`resource_metadata` URL. A valid token missing a required scope receives `403`
|
|
215
|
+
with `insufficient_scope`. Runner does not implement a proprietary login or
|
|
216
|
+
refresh-token service.
|
|
156
217
|
|
|
157
|
-
|
|
158
|
-
{
|
|
159
|
-
"ok": true,
|
|
160
|
-
"transport": "streamable-http",
|
|
161
|
-
"tools": 1,
|
|
162
|
-
"mode": "read_only"
|
|
163
|
-
}
|
|
164
|
-
```
|
|
218
|
+
## Opaque Token Rotation
|
|
165
219
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
Unauthorized requests fail:
|
|
220
|
+
Runner accepts one active token and, only when configured, one previous token:
|
|
169
221
|
|
|
170
222
|
```bash
|
|
171
|
-
|
|
172
|
-
-H "Content-Type: application/json" \
|
|
173
|
-
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' \
|
|
174
|
-
http://127.0.0.1:8765/mcp
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
Authorized requests include the bearer token:
|
|
178
|
-
|
|
179
|
-
```bash
|
|
180
|
-
curl -i \
|
|
181
|
-
-H "Authorization: Bearer dev-local-token" \
|
|
182
|
-
-H "Content-Type: application/json" \
|
|
183
|
-
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' \
|
|
184
|
-
http://127.0.0.1:8765/mcp
|
|
223
|
+
export SYNAPSOR_RUNNER_HTTP_TOKEN="$(node -e 'process.stdout.write(require("node:crypto").randomBytes(32).toString("base64url"))')"
|
|
185
224
|
```
|
|
186
225
|
|
|
187
|
-
|
|
226
|
+
1. Move the old active value to the previous secret slot.
|
|
227
|
+
2. Have the secret manager inject that old value as
|
|
228
|
+
`SYNAPSOR_RUNNER_HTTP_TOKEN_PREVIOUS`, then put a new random value in the
|
|
229
|
+
active slot.
|
|
230
|
+
3. Restart/roll Runner instances and update authorized clients.
|
|
231
|
+
4. Remove `previous_env` and its secret after the bounded rollout window.
|
|
188
232
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
```
|
|
233
|
+
Runner never accepts an unbounded key history. Existing MCP sessions are pinned
|
|
234
|
+
to the exact credential used at initialization, so swapping active and previous
|
|
235
|
+
tokens cannot take over another session.
|
|
193
236
|
|
|
194
|
-
|
|
237
|
+
## Origin, Host, CORS, And Request Bounds
|
|
195
238
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
arbitrary table or column names
|
|
205
|
-
```
|
|
239
|
+
- Every present browser `Origin` must exactly match `allowed_origins`; otherwise
|
|
240
|
+
Runner returns `403`. Native MCP clients may omit `Origin`.
|
|
241
|
+
- Wildcard CORS and the `null` origin are rejected.
|
|
242
|
+
- Every request `Host` must match `allowed_hosts` (or the safe loopback default).
|
|
243
|
+
This is independent of tenant identity and limits DNS-rebinding-style access.
|
|
244
|
+
- Forwarded host and identity headers are never trusted automatically.
|
|
245
|
+
- Request body, header, connection, request-time, session-count, and idle-session
|
|
246
|
+
limits have bounded defaults and can be tightened under `http_security.limits`.
|
|
206
247
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
"
|
|
219
|
-
"arguments": { "invoice_id": "INV-3001" }
|
|
248
|
+
```json
|
|
249
|
+
{
|
|
250
|
+
"http_security": {
|
|
251
|
+
"limits": {
|
|
252
|
+
"max_request_bytes": 65536,
|
|
253
|
+
"max_header_bytes": 8192,
|
|
254
|
+
"max_sessions": 500,
|
|
255
|
+
"session_idle_timeout_seconds": 300,
|
|
256
|
+
"request_timeout_ms": 15000,
|
|
257
|
+
"headers_timeout_ms": 5000,
|
|
258
|
+
"keep_alive_timeout_ms": 5000,
|
|
259
|
+
"max_connections": 1000
|
|
220
260
|
}
|
|
221
|
-
}
|
|
222
|
-
|
|
261
|
+
}
|
|
262
|
+
}
|
|
223
263
|
```
|
|
224
264
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
265
|
+
Session and connection limits are per Runner process. Capability rate limits and
|
|
266
|
+
ledger state become fleet-wide only when the shared PostgreSQL runtime store is
|
|
267
|
+
configured.
|
|
228
268
|
|
|
229
|
-
##
|
|
269
|
+
## Health, Readiness, And Metrics
|
|
230
270
|
|
|
231
|
-
|
|
271
|
+
`/healthz` is unauthenticated and intentionally minimal:
|
|
232
272
|
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
-
|
|
238
|
-
|
|
239
|
-
"id": 3,
|
|
240
|
-
"method": "resources/read",
|
|
241
|
-
"params": { "uri": "synapsor://evidence/ev_..." }
|
|
242
|
-
}' \
|
|
243
|
-
http://127.0.0.1:8765/mcp
|
|
273
|
+
```json
|
|
274
|
+
{
|
|
275
|
+
"ok": true,
|
|
276
|
+
"status": "live",
|
|
277
|
+
"transport": "streamable-http"
|
|
278
|
+
}
|
|
244
279
|
```
|
|
245
280
|
|
|
246
|
-
|
|
281
|
+
`/readyz` reports bounded dependency status codes without credentials or raw
|
|
282
|
+
infrastructure errors. `/metrics` is disabled unless separately configured and
|
|
283
|
+
uses its own authorization; the MCP endpoint credential does not implicitly
|
|
284
|
+
grant metrics access.
|
|
247
285
|
|
|
248
|
-
|
|
249
|
-
development, allow one explicit origin:
|
|
286
|
+
## Legacy JSON-RPC Bridge
|
|
250
287
|
|
|
251
288
|
```bash
|
|
252
289
|
synapsor-runner mcp serve-http \
|
|
290
|
+
--host 127.0.0.1 \
|
|
291
|
+
--port 8765 \
|
|
253
292
|
--config ./synapsor.runner.json \
|
|
254
293
|
--store ./.synapsor/local.db \
|
|
255
|
-
--
|
|
294
|
+
--auth-token-env SYNAPSOR_RUNNER_HTTP_TOKEN
|
|
256
295
|
```
|
|
257
296
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
297
|
+
The bridge has equivalent remote channel, TLS/mTLS, static-token rotation,
|
|
298
|
+
Origin/Host, and request-bound enforcement. It rejects `http_claims` because it
|
|
299
|
+
does not implement standard MCP sessions. Use Streamable HTTP for a shared
|
|
300
|
+
identity deployment and for standard MCP SDK clients.
|
|
261
301
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
If you explicitly bind to all interfaces:
|
|
302
|
+
An authorized bridge request references the environment value at runtime:
|
|
265
303
|
|
|
266
304
|
```bash
|
|
267
|
-
|
|
305
|
+
curl -i \
|
|
306
|
+
-H "Authorization: Bearer ${SYNAPSOR_RUNNER_HTTP_TOKEN}" \
|
|
307
|
+
-H "Content-Type: application/json" \
|
|
308
|
+
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' \
|
|
309
|
+
http://127.0.0.1:8765/mcp
|
|
268
310
|
```
|
|
269
311
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
- keep bearer auth enabled;
|
|
273
|
-
- use TLS or a trusted reverse proxy;
|
|
274
|
-
- prefer private networking;
|
|
275
|
-
- add rate limits and request-size limits at the edge;
|
|
276
|
-
- do not log request bodies by default;
|
|
277
|
-
- rotate the bearer token if it is exposed.
|
|
278
|
-
|
|
279
|
-
`--dev-no-auth` is accepted only on `localhost` or `127.0.0.1`. It fails closed
|
|
280
|
-
with `--host 0.0.0.0`.
|
|
312
|
+
## Diagnose Before Serving
|
|
281
313
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
```text
|
|
289
|
-
tenant_id
|
|
290
|
-
principal
|
|
291
|
-
principal_id
|
|
292
|
-
project_id
|
|
293
|
-
source_id
|
|
294
|
-
allowed_columns
|
|
295
|
-
approval_identity
|
|
314
|
+
```bash
|
|
315
|
+
synapsor-runner doctor \
|
|
316
|
+
--config ./synapsor.runner.json \
|
|
317
|
+
--transport streamable-http \
|
|
318
|
+
--host 127.0.0.1 \
|
|
319
|
+
--auth-token-env SYNAPSOR_RUNNER_HTTP_TOKEN
|
|
296
320
|
```
|
|
297
321
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
See:
|
|
305
|
-
|
|
306
|
-
```text
|
|
307
|
-
examples/openai-agents-http/
|
|
308
|
-
examples/openai-agents-stdio/
|
|
309
|
-
```
|
|
322
|
+
For a remote proxy deployment add `--host 0.0.0.0 --trusted-tls-proxy`; for
|
|
323
|
+
Runner-owned TLS add the same TLS env-name flags used at startup. Doctor reports
|
|
324
|
+
the transport, bind scope, channel, auth/identity mode, issuer/audience/resource,
|
|
325
|
+
key readiness, token strength/rotation, Origin/Host policy, limits, rate-limit
|
|
326
|
+
scope, and database isolation assurance without printing credential values.
|
|
310
327
|
|
|
311
|
-
|
|
312
|
-
is available. The stdio example launches Runner as a child process. The HTTP
|
|
313
|
-
example connects to `synapsor-runner mcp serve-streamable-http` through
|
|
314
|
-
`MCPServerStreamableHttp`. Use the JSON-RPC bridge only when you intentionally
|
|
315
|
-
want a small app-owned wrapper instead of standard HTTP MCP.
|
|
328
|
+
## Model-Facing Boundary
|
|
316
329
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
330
|
+
HTTP transport does not change authority. MCP clients receive reviewed semantic
|
|
331
|
+
capabilities, never raw SQL, database credentials, endpoint credentials,
|
|
332
|
+
approval/apply/reconcile/revert tools, token minting, or token refresh. Keep
|
|
333
|
+
least-privilege DB roles and PostgreSQL RLS or tenant-bound credentials under
|
|
334
|
+
Runner where practical; transport authentication does not replace database or
|
|
335
|
+
operator authorization.
|
package/docs/limitations.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# Limitations
|
|
2
2
|
|
|
3
|
-
Synapsor Runner is intentionally narrow. Version 1.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
enterprise SLA.
|
|
3
|
+
Synapsor Runner is intentionally narrow. Version 1.6 adds deterministic
|
|
4
|
+
whole-application boundary drafting and a local authoring-only Explore ->
|
|
5
|
+
Protect path on top of guarded writes. It does not turn Runner into a generic
|
|
6
|
+
database query tool, claim Synapsor Cloud scale, or claim an enterprise SLA.
|
|
7
7
|
|
|
8
8
|
## Supported
|
|
9
9
|
|
|
@@ -41,12 +41,27 @@ enterprise SLA.
|
|
|
41
41
|
- Primary-key guard.
|
|
42
42
|
- Tenant guard.
|
|
43
43
|
- Allowed-column validation.
|
|
44
|
-
-
|
|
44
|
+
- Exact version-column conflict guards, plus an explicit legacy
|
|
45
|
+
`CONFLICT GUARD WEAK ROW HASH ACKNOWLEDGED` escape hatch for ordinary
|
|
46
|
+
single-row source-DB UPDATE only.
|
|
45
47
|
- Idempotency receipts.
|
|
46
48
|
- Named local trusted contexts for capability configs.
|
|
47
49
|
- Capability recipes that generate reviewed starter configs.
|
|
48
50
|
- Shadow-mode proposal-vs-human-action comparison.
|
|
49
51
|
- Static MCP database risk review.
|
|
52
|
+
- Deterministic whole-schema Auto Boundary drafting from database metadata,
|
|
53
|
+
statically parsed Prisma/Drizzle schema artifacts, OpenAPI documents, and
|
|
54
|
+
existing Synapsor definitions. Generated authority starts disabled.
|
|
55
|
+
- Local development/staging Scoped Explore through exactly
|
|
56
|
+
`app.describe_data` and `app.explore_data`, with no SQL-string argument.
|
|
57
|
+
- Reviewed PM-style aggregate Explore with `count`, `count_distinct`, `sum`,
|
|
58
|
+
`avg`, categorical dimensions, fixed time buckets, typed filters, bounded
|
|
59
|
+
top-N, optional one-hop proven many-to-one relationships, cohort suppression,
|
|
60
|
+
and durable extraction/differencing budgets.
|
|
61
|
+
- Protect This Query to public DSL, canonical JSON, tests, and a disabled named
|
|
62
|
+
capability that survives Explore shutdown after exact-digest activation.
|
|
63
|
+
- Generation-lock drift detection for generated authority. Manually authored
|
|
64
|
+
projects without a lock retain their previous behavior.
|
|
50
65
|
- Local indexed search for proposals, evidence bundles, query audit, writeback
|
|
51
66
|
receipts, and proposal replay.
|
|
52
67
|
- DSL enum arguments and fixed, tenant-scoped aggregate count/sum/avg tools
|
|
@@ -87,8 +102,12 @@ truth for the model-facing tools.
|
|
|
87
102
|
- Prompt-injection prevention.
|
|
88
103
|
- Unbounded/high-throughput or multi-region ledger scale.
|
|
89
104
|
- Managed fleet, SLA, compliance certification, or production support guarantee.
|
|
90
|
-
-
|
|
91
|
-
|
|
105
|
+
- Production, shared HTTP, remote, or non-loopback Scoped Explore.
|
|
106
|
+
- Arbitrary aggregate expressions, dynamic identifiers, unrestricted joins,
|
|
107
|
+
many-to-many joins, formulas, window functions, subqueries, `HAVING`,
|
|
108
|
+
user-defined functions, or a statistical privacy guarantee. Version 1.6
|
|
109
|
+
supports only the explicitly reviewed authoring cube described above and
|
|
110
|
+
fixed protected named capabilities produced from it.
|
|
92
111
|
- Automatic policy widening or activation from graduated-trust metrics.
|
|
93
112
|
- Immutable/WORM compliance storage from the local report exporter.
|
|
94
113
|
|
|
@@ -118,7 +137,7 @@ not a hosted central evidence service, organization RBAC/SSO, compliance
|
|
|
118
137
|
retention system, or unbounded search engine. Each bridge operation serializes
|
|
119
138
|
through an advisory lock and fails above configured `max_entries`.
|
|
120
139
|
|
|
121
|
-
Only homogeneous 1.
|
|
140
|
+
Only homogeneous 1.x fleet operation is claimed for protocol-v4 compensation
|
|
122
141
|
jobs. Mixed-minor v3/v4 rolling compensation is not claimed.
|
|
123
142
|
See [Running A Small Runner
|
|
124
143
|
Fleet](running-a-runner-fleet.md).
|
|
@@ -134,7 +153,12 @@ Do not describe external approval as merge.
|
|
|
134
153
|
|
|
135
154
|
## Weak Conflict Guards
|
|
136
155
|
|
|
137
|
-
A version/timestamp column is the preferred conflict guard.
|
|
156
|
+
A version/timestamp column is the preferred conflict guard. UPDATE authoring
|
|
157
|
+
fails if no guard is declared. A weak row-hash guard can be selected only with
|
|
158
|
+
the reviewer-visible `CONFLICT GUARD WEAK ROW HASH ACKNOWLEDGED` clause for a
|
|
159
|
+
narrow ordinary single-row source-DB UPDATE. It hashes the captured projection,
|
|
160
|
+
may miss concurrent changes outside that projection, and must not be presented
|
|
161
|
+
as equivalent to a durable version column.
|
|
138
162
|
|
|
139
163
|
Runner-ledger UPDATE and DELETE require an exact guard; UPDATE must advance it
|
|
140
164
|
inside the source transaction. INSERT requires a reviewed source-unique dedup
|
package/docs/local-mode.md
CHANGED
|
@@ -85,7 +85,7 @@ Use Streamable HTTP when your app/server agent connects through a standard HTTP
|
|
|
85
85
|
MCP client:
|
|
86
86
|
|
|
87
87
|
```bash
|
|
88
|
-
export SYNAPSOR_RUNNER_HTTP_TOKEN="
|
|
88
|
+
export SYNAPSOR_RUNNER_HTTP_TOKEN="$(node -e 'process.stdout.write(require("node:crypto").randomBytes(32).toString("base64url"))')"
|
|
89
89
|
|
|
90
90
|
npx -y -p @synapsor/runner synapsor-runner mcp serve-streamable-http \
|
|
91
91
|
--config ./synapsor.runner.json \
|
|
@@ -94,7 +94,10 @@ npx -y -p @synapsor/runner synapsor-runner mcp serve-streamable-http \
|
|
|
94
94
|
```
|
|
95
95
|
|
|
96
96
|
Streamable HTTP defaults to `127.0.0.1:8766`, requires bearer auth by default,
|
|
97
|
-
and
|
|
97
|
+
and uses an opaque endpoint token only as shared service access, not user or
|
|
98
|
+
tenant identity. Non-loopback serving requires direct TLS, an explicitly
|
|
99
|
+
trusted TLS proxy, or authenticated emergency break glass; shared deployments
|
|
100
|
+
require verified signed claims.
|
|
98
101
|
Use `synapsor-runner mcp serve-http` only when you explicitly want the smaller
|
|
99
102
|
JSON-RPC bridge. Details: [HTTP MCP](http-mcp.md).
|
|
100
103
|
|