@plitzi/sdk-shared 0.32.10 → 0.32.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.
- package/CHANGELOG.md +16 -0
- package/dist/types/ServerTypes.d.ts +146 -19
- package/package.json +2 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @plitzi/sdk-shared
|
|
2
2
|
|
|
3
|
+
## 0.32.12
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- v0.32.12
|
|
8
|
+
- Updated dependencies
|
|
9
|
+
- @plitzi/nexus@0.32.12
|
|
10
|
+
|
|
11
|
+
## 0.32.11
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- v0.32.11
|
|
16
|
+
- Updated dependencies
|
|
17
|
+
- @plitzi/nexus@0.32.11
|
|
18
|
+
|
|
3
19
|
## 0.32.10
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
|
@@ -193,27 +193,61 @@ export type SSRRscConfig = {
|
|
|
193
193
|
/** Server-side cache TTL for RSC responses in milliseconds. Defaults to 30 000. Set to 0 to disable. */
|
|
194
194
|
cacheTtlMs?: number;
|
|
195
195
|
};
|
|
196
|
-
/**
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
export type McpLogEvent = {
|
|
200
|
-
/** 'tool' for a plitzi_* tool call, 'resource' for a plitzi:// resource read. */
|
|
201
|
-
kind: 'tool' | 'resource';
|
|
202
|
-
/** The tool name (e.g. 'plitzi_apply') or the resource URI that was read. */
|
|
203
|
-
name: string;
|
|
204
|
-
/** Wall-clock duration of the handler, in milliseconds. */
|
|
196
|
+
/** What every log event carries, whatever layer it came from. */
|
|
197
|
+
type ServerLogEventBase = {
|
|
198
|
+
/** Wall-clock duration of the work the event describes, in milliseconds. */
|
|
205
199
|
durationMs: number;
|
|
206
|
-
/**
|
|
200
|
+
/** False when the work threw or answered an error status. */
|
|
207
201
|
ok: boolean;
|
|
208
|
-
/** The error message when `ok` is false. */
|
|
202
|
+
/** The error message when `ok` is false — never the request payload. */
|
|
209
203
|
error?: string;
|
|
210
|
-
/** A compact, truncated JSON summary of the tool arguments (tool events only). */
|
|
211
|
-
argsSummary?: string;
|
|
212
204
|
/** ISO-8601 timestamp of when the event was emitted. */
|
|
213
205
|
timestamp: string;
|
|
214
206
|
};
|
|
215
|
-
/**
|
|
216
|
-
|
|
207
|
+
/** One HTTP request served by ANY Plitzi server — SSR pages, RSC, plugin assets, the preview endpoint, MCP —
|
|
208
|
+
* emitted by the dispatcher once the request is answered, including the ones that failed or were rejected. */
|
|
209
|
+
export type ServerRequestLogEvent = ServerLogEventBase & {
|
|
210
|
+
kind: 'request';
|
|
211
|
+
/** Which server answered — the dispatcher label, e.g. 'SSR' or 'MCP'. */
|
|
212
|
+
server: string;
|
|
213
|
+
method: string;
|
|
214
|
+
/** Request path with query VALUES stripped and only the keys kept, e.g. '/search?q&page'. */
|
|
215
|
+
path: string;
|
|
216
|
+
/** The operation inside the request, when the answering stage names one — e.g. the MCP JSON-RPC method. */
|
|
217
|
+
operation?: string;
|
|
218
|
+
/** The HTTP status the server answered with. */
|
|
219
|
+
status: number;
|
|
220
|
+
/** The client the request came from, resolved through the proxies the deployment sits behind. Empty when no
|
|
221
|
+
* address could be determined. It IS personal data — see the note on {@link ServerLogEvent}. */
|
|
222
|
+
clientIp?: string;
|
|
223
|
+
};
|
|
224
|
+
/** One plitzi_* tool call inside an MCP request. Reported separately from the request because a failing tool
|
|
225
|
+
* still answers HTTP 200 — the failure lives in the JSON-RPC payload, so only this event exposes it. */
|
|
226
|
+
export type McpToolLogEvent = ServerLogEventBase & {
|
|
227
|
+
kind: 'tool';
|
|
228
|
+
/** The tool name, e.g. 'plitzi_apply'. */
|
|
229
|
+
name: string;
|
|
230
|
+
/** A compact SHAPE summary of the arguments — keys, value types and array lengths, never values. Set
|
|
231
|
+
* `MCP_LOG_ARGS=1` to dump the real arguments instead; they may carry user content, so it stays opt-in. */
|
|
232
|
+
argsSummary?: string;
|
|
233
|
+
};
|
|
234
|
+
/** One plitzi:// resource read inside an MCP request, named by the URI the request asked for. */
|
|
235
|
+
export type McpResourceLogEvent = ServerLogEventBase & {
|
|
236
|
+
kind: 'resource';
|
|
237
|
+
/** The resource URI that was read, e.g. 'plitzi://element/hero_1'. */
|
|
238
|
+
name: string;
|
|
239
|
+
};
|
|
240
|
+
/** Everything a Plitzi server reports about the work it does, as ONE stream: the HTTP requests it answers, plus
|
|
241
|
+
* the MCP tool calls and resource reads that happen inside them. Wire a single sink via `SSRServerConfig.logger`
|
|
242
|
+
* and switch on `kind` — a consumer can render it, ship it to a dashboard or drop the kinds it does not want.
|
|
243
|
+
*
|
|
244
|
+
* Payload-free by construction: no headers, cookies, tokens nor request body ever reach an event, query values
|
|
245
|
+
* are stripped from paths and tool arguments are reduced to their shape. Two fields are NOT anonymous and a
|
|
246
|
+
* consumer shipping these events must handle them accordingly: `clientIp` on a request event, and the request
|
|
247
|
+
* path, which is kept verbatim because it is what makes the log usable. */
|
|
248
|
+
export type ServerLogEvent = ServerRequestLogEvent | McpToolLogEvent | McpResourceLogEvent;
|
|
249
|
+
/** The sink a consumer provides to receive every {@link ServerLogEvent} (see `SSRServerConfig.logger`). */
|
|
250
|
+
export type ServerLogger = (event: ServerLogEvent) => void;
|
|
217
251
|
export type SSRServerConfig = {
|
|
218
252
|
port?: number;
|
|
219
253
|
host?: string;
|
|
@@ -257,10 +291,10 @@ export type SSRServerConfig = {
|
|
|
257
291
|
enabled?: boolean;
|
|
258
292
|
path?: string;
|
|
259
293
|
};
|
|
260
|
-
/** Receives a
|
|
261
|
-
*
|
|
262
|
-
* `MCP_DEBUG=1
|
|
263
|
-
|
|
294
|
+
/** Receives a {@link ServerLogEvent} for every HTTP request this server answers — whatever stage answered it
|
|
295
|
+
* and whatever the outcome — plus every MCP tool call and resource read inside those requests. Without it the
|
|
296
|
+
* server reports nothing per request (the MCP events still reach the console when `MCP_DEBUG=1`). */
|
|
297
|
+
logger?: ServerLogger;
|
|
264
298
|
adapters: SSRAdapters;
|
|
265
299
|
/** Draft-preview endpoint for the MCP visual-preview tools (the RENDERER side). Off unless `enabled`. */
|
|
266
300
|
preview?: SSRPreviewConfig;
|
|
@@ -300,6 +334,8 @@ export type SSRServerConfig = {
|
|
|
300
334
|
};
|
|
301
335
|
/** Cache-buster appended as ?v=<assetVersion> to all default SDK asset URLs (jsPath, cssPath, react vendor). Compute from file mtime or package version at startup. */
|
|
302
336
|
assetVersion?: string;
|
|
337
|
+
/** OAuth 2.1 authorization for the MCP server. Omit to keep the server anonymous — see {@link OAuthConfig}. */
|
|
338
|
+
oauth?: OAuthConfig;
|
|
303
339
|
};
|
|
304
340
|
export type ServerServices = {
|
|
305
341
|
ssr?: boolean;
|
|
@@ -333,6 +369,96 @@ export type SSRServer = {
|
|
|
333
369
|
readonly cache: CacheManager | null;
|
|
334
370
|
readonly plugins: PluginRegistry;
|
|
335
371
|
};
|
|
372
|
+
/** A key/value store with per-entry expiry, backing the OAuth layer's short-lived protocol state (registered
|
|
373
|
+
* clients, authorization codes, refresh grants). Values are opaque strings the SDK serialises itself. A
|
|
374
|
+
* multi-replica deployment MUST inject a shared implementation — a code minted on one replica is redeemed on
|
|
375
|
+
* whichever replica the token request lands on. */
|
|
376
|
+
export type OAuthStore = {
|
|
377
|
+
put: (key: string, value: string, ttlSeconds: number) => void | Promise<void>;
|
|
378
|
+
get: (key: string) => (string | undefined) | Promise<string | undefined>;
|
|
379
|
+
drop: (key: string) => void | Promise<void>;
|
|
380
|
+
};
|
|
381
|
+
/** Someone who got through {@link OAuthAdapters.authenticate}. `id` is what the other adapters key off; `label`
|
|
382
|
+
* is shown back on the consent screen so the user can see who they are about to grant access as. */
|
|
383
|
+
export type OAuthUser = {
|
|
384
|
+
id: string;
|
|
385
|
+
label: string;
|
|
386
|
+
};
|
|
387
|
+
/** One thing the user may grant the client access to — a Plitzi space, or whatever else a deployment scopes its
|
|
388
|
+
* tokens by. `value` is the opaque handle the SDK round-trips back to {@link OAuthAdapters.issueToken}; only the
|
|
389
|
+
* consumer interprets it. A deployment whose public surface is useful on its own (plitzi_render needs no space)
|
|
390
|
+
* can offer a target that grants nothing, so the user is never forced to pick one. */
|
|
391
|
+
export type OAuthGrantTarget = {
|
|
392
|
+
value: string;
|
|
393
|
+
label: string;
|
|
394
|
+
description?: string;
|
|
395
|
+
};
|
|
396
|
+
/** What the OAuth layer cannot resolve on its own: who the user is, what they may grant, and the bearer to mint
|
|
397
|
+
* for them. The SDK owns the protocol (discovery, registration, PKCE, code exchange); the consumer owns identity
|
|
398
|
+
* and issues a token its own `adapters.getSpaceId` will accept back. */
|
|
399
|
+
export type OAuthAdapters = {
|
|
400
|
+
/** Verify the credentials typed into the consent screen. Return undefined to re-show the form with an error —
|
|
401
|
+
* never throw for a wrong password. */
|
|
402
|
+
authenticate: (credentials: {
|
|
403
|
+
username: string;
|
|
404
|
+
password: string;
|
|
405
|
+
}) => Promise<OAuthUser | undefined>;
|
|
406
|
+
/** What this user may grant access to. An empty list ends the flow with `access_denied`. */
|
|
407
|
+
grantTargets: (user: OAuthUser) => Promise<OAuthGrantTarget[]>;
|
|
408
|
+
/** Mint the bearer the client will send on every MCP request. Return undefined to deny the grant. */
|
|
409
|
+
issueToken: (user: OAuthUser, target: OAuthGrantTarget) => Promise<{
|
|
410
|
+
token: string;
|
|
411
|
+
expiresInSeconds?: number;
|
|
412
|
+
} | undefined>;
|
|
413
|
+
store: OAuthStore;
|
|
414
|
+
};
|
|
415
|
+
/** What the built-in consent screen shows around the form. Ignored when `renderConsent` replaces the page. */
|
|
416
|
+
export type OAuthBranding = {
|
|
417
|
+
/** Shown as the heading, e.g. 'Plitzi'. Defaults to 'Plitzi'. */
|
|
418
|
+
productName?: string;
|
|
419
|
+
/** Absolute or same-origin URL of a logo to show above the heading. */
|
|
420
|
+
logoUrl?: string;
|
|
421
|
+
/** Extra CSS appended to the page's own, for a deployment that wants its own look without replacing the page. */
|
|
422
|
+
css?: string;
|
|
423
|
+
};
|
|
424
|
+
/** Everything the consent screen needs to render itself, for a deployment that replaces the built-in page. Return
|
|
425
|
+
* a full HTML document; the SDK serves it as-is and reads the same form fields back. */
|
|
426
|
+
export type OAuthConsentView = {
|
|
427
|
+
/** 'credentials' asks for username + password; 'target' asks which space to grant, after a successful login. */
|
|
428
|
+
step: 'credentials' | 'target';
|
|
429
|
+
/** Where the form must POST to (the authorize endpoint). */
|
|
430
|
+
action: string;
|
|
431
|
+
/** Hidden fields the form MUST round-trip verbatim, or the flow cannot be resumed. */
|
|
432
|
+
hidden: Record<string, string>;
|
|
433
|
+
/** Offered on the 'target' step only. */
|
|
434
|
+
targets: OAuthGrantTarget[];
|
|
435
|
+
/** Who logged in, on the 'target' step. */
|
|
436
|
+
user?: OAuthUser;
|
|
437
|
+
/** A message to show the user, e.g. after a failed login. */
|
|
438
|
+
error?: string;
|
|
439
|
+
branding: OAuthBranding;
|
|
440
|
+
};
|
|
441
|
+
/** OAuth 2.1 authorization for the MCP server (RFC 9728 discovery + RFC 7591 dynamic client registration +
|
|
442
|
+
* authorization code with PKCE). ENTIRELY OPTIONAL: without this config no endpoint is mounted, discovery keeps
|
|
443
|
+
* answering 404 and the server stays anonymous, which is a working setup — the public surface (handshake, tool
|
|
444
|
+
* and resource listing, the guide, plitzi_render) never needed a token. Configure it only to let a remote host
|
|
445
|
+
* that cannot send custom headers — Claude Desktop, ChatGPT — obtain a space-scoped one. */
|
|
446
|
+
export type OAuthConfig = {
|
|
447
|
+
adapters: OAuthAdapters;
|
|
448
|
+
/** The issuer/resource identifier published in the metadata documents. Defaults to the origin the request came
|
|
449
|
+
* in on, which is correct whenever the server owns its sub-domain; set it when a proxy rewrites the host. */
|
|
450
|
+
issuer?: string;
|
|
451
|
+
/** Scope names advertised and echoed back on the token. Defaults to ['plitzi']. */
|
|
452
|
+
scopes?: string[];
|
|
453
|
+
/** How long an authorization code stays redeemable, in seconds. Default 60 — codes are one-shot and redeemed
|
|
454
|
+
* immediately. */
|
|
455
|
+
codeTtlSeconds?: number;
|
|
456
|
+
/** How long a refresh grant lives, in seconds. Default 30 days. Set 0 to issue no refresh tokens. */
|
|
457
|
+
refreshTtlSeconds?: number;
|
|
458
|
+
branding?: OAuthBranding;
|
|
459
|
+
/** Replaces the built-in consent screen — return a full HTML document for the given step. */
|
|
460
|
+
renderConsent?: (view: OAuthConsentView) => string | Promise<string>;
|
|
461
|
+
};
|
|
336
462
|
/** A short-TTL, one-shot store for unsaved draft offline-data behind a preview token. The SDK ships an
|
|
337
463
|
* in-memory default (fine for a single replica); a multi-replica deployment injects a shared (e.g. Redis)
|
|
338
464
|
* implementation so a preview URL resolves on whichever replica the browser lands on. `take` consumes the
|
|
@@ -353,3 +479,4 @@ export type SSRPreviewConfig = {
|
|
|
353
479
|
/** Token time-to-live in milliseconds. Default 60000. */
|
|
354
480
|
ttlMs?: number;
|
|
355
481
|
};
|
|
482
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plitzi/sdk-shared",
|
|
3
|
-
"version": "0.32.
|
|
3
|
+
"version": "0.32.12",
|
|
4
4
|
"license": "AGPL-3.0",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -1184,9 +1184,6 @@
|
|
|
1184
1184
|
"./types/SegmentTypes": {
|
|
1185
1185
|
"types": "./dist/types/SegmentTypes.d.ts"
|
|
1186
1186
|
},
|
|
1187
|
-
"./types/ServerTypes": {
|
|
1188
|
-
"types": "./dist/types/ServerTypes.d.ts"
|
|
1189
|
-
},
|
|
1190
1187
|
"./types/SpaceTypes": {
|
|
1191
1188
|
"types": "./dist/types/SpaceTypes.d.ts"
|
|
1192
1189
|
},
|
|
@@ -1233,7 +1230,7 @@
|
|
|
1233
1230
|
},
|
|
1234
1231
|
"dependencies": {
|
|
1235
1232
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
1236
|
-
"@plitzi/nexus": "0.32.
|
|
1233
|
+
"@plitzi/nexus": "0.32.12",
|
|
1237
1234
|
"@plitzi/plitzi-ui": "^1.6.18",
|
|
1238
1235
|
"date-fns": "^4.4.0",
|
|
1239
1236
|
"date-fns-tz": "^3.2.0",
|