@plitzi/sdk-shared 0.32.11 → 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 +8 -0
- package/dist/types/ServerTypes.d.ts +99 -4
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -217,6 +217,9 @@ export type ServerRequestLogEvent = ServerLogEventBase & {
|
|
|
217
217
|
operation?: string;
|
|
218
218
|
/** The HTTP status the server answered with. */
|
|
219
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;
|
|
220
223
|
};
|
|
221
224
|
/** One plitzi_* tool call inside an MCP request. Reported separately from the request because a failing tool
|
|
222
225
|
* still answers HTTP 200 — the failure lives in the JSON-RPC payload, so only this event exposes it. */
|
|
@@ -238,10 +241,10 @@ export type McpResourceLogEvent = ServerLogEventBase & {
|
|
|
238
241
|
* the MCP tool calls and resource reads that happen inside them. Wire a single sink via `SSRServerConfig.logger`
|
|
239
242
|
* and switch on `kind` — a consumer can render it, ship it to a dashboard or drop the kinds it does not want.
|
|
240
243
|
*
|
|
241
|
-
*
|
|
242
|
-
*
|
|
243
|
-
*
|
|
244
|
-
*
|
|
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. */
|
|
245
248
|
export type ServerLogEvent = ServerRequestLogEvent | McpToolLogEvent | McpResourceLogEvent;
|
|
246
249
|
/** The sink a consumer provides to receive every {@link ServerLogEvent} (see `SSRServerConfig.logger`). */
|
|
247
250
|
export type ServerLogger = (event: ServerLogEvent) => void;
|
|
@@ -331,6 +334,8 @@ export type SSRServerConfig = {
|
|
|
331
334
|
};
|
|
332
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. */
|
|
333
336
|
assetVersion?: string;
|
|
337
|
+
/** OAuth 2.1 authorization for the MCP server. Omit to keep the server anonymous — see {@link OAuthConfig}. */
|
|
338
|
+
oauth?: OAuthConfig;
|
|
334
339
|
};
|
|
335
340
|
export type ServerServices = {
|
|
336
341
|
ssr?: boolean;
|
|
@@ -364,6 +369,96 @@ export type SSRServer = {
|
|
|
364
369
|
readonly cache: CacheManager | null;
|
|
365
370
|
readonly plugins: PluginRegistry;
|
|
366
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
|
+
};
|
|
367
462
|
/** A short-TTL, one-shot store for unsaved draft offline-data behind a preview token. The SDK ships an
|
|
368
463
|
* in-memory default (fine for a single replica); a multi-replica deployment injects a shared (e.g. Redis)
|
|
369
464
|
* implementation so a preview URL resolves on whichever replica the browser lands on. `take` consumes the
|
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",
|
|
@@ -1230,7 +1230,7 @@
|
|
|
1230
1230
|
},
|
|
1231
1231
|
"dependencies": {
|
|
1232
1232
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
1233
|
-
"@plitzi/nexus": "0.32.
|
|
1233
|
+
"@plitzi/nexus": "0.32.12",
|
|
1234
1234
|
"@plitzi/plitzi-ui": "^1.6.18",
|
|
1235
1235
|
"date-fns": "^4.4.0",
|
|
1236
1236
|
"date-fns-tz": "^3.2.0",
|