@absolutejs/mcp 0.23.0 → 0.24.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 CHANGED
@@ -6,6 +6,12 @@ This file is generated by `absolute-changelog` from the entries in
6
6
  `changelog/`. Edit an entry, not this file — and add new ones under
7
7
  `changelog/unreleased/`.
8
8
 
9
+ ## 0.24.0 — 2026-09-13
10
+
11
+ ### Added
12
+
13
+ - **Add durable background work launch and read-only recovery tools with matching text and structured progress.**
14
+
9
15
  ## 0.23.0 — 2026-09-13
10
16
 
11
17
  ### Added
package/README.md CHANGED
@@ -461,3 +461,23 @@ a string, and serialized MCP results remain nested without discarding content.
461
461
  The formatter never retries work. A missing saved result carries a same-ID polling
462
462
  instruction. Bind account identity and authorization before retrieving the saved
463
463
  work; this helper does not authorize access or filter the tool's saved payload.
464
+
465
+ ## Budgeted background work
466
+
467
+ `createBackgroundWorkTools({ description, inputSchema, start, read })` exposes
468
+ `start_background_work` with a stable requestId and maximum service credits, plus
469
+ read-only `get_background_work` recovery. Omit `start` to support recovery at zero
470
+ credits or while rollout is disabled. Account ownership must come from the
471
+ authenticated caller, never tool arguments.
472
+
473
+ The start adapter must atomically reserve credits, bind immutable work and enqueue
474
+ a durable job; duplicate IDs must return existing work and reject changed input or
475
+ budget. The read adapter returns public results and accounting only, without
476
+ starting, settling or retrying work. `createBackgroundWorkResult` projects the
477
+ same progress, results and spend in text and structured content for broad host
478
+ support. In uncertain states, retain the reservation and do not create a new ID
479
+ to repeat work.
480
+
481
+ Start is classified as `paid_access`; recovery is `entitlement_status`. Existing
482
+ commerce host reviews and account/client restrictions still apply. These tools
483
+ do not enable embedded checkout or override any host's commerce rules.
package/changelog.json CHANGED
@@ -2,6 +2,16 @@
2
2
  "contract": 1,
3
3
  "name": "@absolutejs/mcp",
4
4
  "releases": [
5
+ {
6
+ "changes": [
7
+ {
8
+ "kind": "added",
9
+ "summary": "Add durable background work launch and read-only recovery tools with matching text and structured progress."
10
+ }
11
+ ],
12
+ "date": "2026-09-13",
13
+ "version": "0.24.0"
14
+ },
5
15
  {
6
16
  "changes": [
7
17
  {
package/dist/index.js CHANGED
@@ -2882,6 +2882,55 @@ var createCreditWorkResult = (requestId, work) => {
2882
2882
  isError: work.status === "failed"
2883
2883
  };
2884
2884
  };
2885
+ // src/backgroundWork.ts
2886
+ var createBackgroundWorkResult = (requestId, work) => {
2887
+ if (!requestId || requestId.length > 128 || !Number.isSafeInteger(work.budget) || work.budget < 1 || !Number.isSafeInteger(work.charged) || work.charged < 0 || work.charged > work.budget || !Number.isSafeInteger(work.totalSteps) || work.totalSteps < 1 || !Array.isArray(work.results) || work.results.length > work.totalSteps || typeof work.settled !== "boolean" || !["queued", "running", "completed", "stopped", "failed", "unknown"].includes(work.status))
2888
+ throw new Error("Invalid background work snapshot");
2889
+ const summary = {
2890
+ requestId,
2891
+ status: work.status,
2892
+ maxCredits: work.budget,
2893
+ creditsCharged: work.charged,
2894
+ settled: work.settled,
2895
+ totalSteps: work.totalSteps,
2896
+ completedSteps: work.results.length,
2897
+ results: work.results,
2898
+ message: work.status === "unknown" ? "A step has an uncertain outcome. Saved results remain available; credits stay held pending reconciliation. Do not start another job to retry it." : "Read get_background_work with this requestId to recover saved progress and spend. Reading never starts or repeats work."
2899
+ };
2900
+ return { content: [{ type: "text", text: JSON.stringify(summary) }], structuredContent: summary, isError: work.status === "failed" || work.status === "unknown" };
2901
+ };
2902
+ var createBackgroundWorkTools = (options) => {
2903
+ const tools = {
2904
+ get_background_work: {
2905
+ description: "Recover this account's saved background work, partial results and credit spend. Read-only; available without credits. Never restarts a provider call.",
2906
+ annotations: { readOnlyHint: true },
2907
+ commerce: { action: "entitlement_status", categories: ["usage_credits"] },
2908
+ inputSchema: { type: "object", additionalProperties: false, required: ["requestId"], properties: { requestId: { type: "string", minLength: 1, maxLength: 128 } } },
2909
+ handler: async (args) => {
2910
+ const requestId = args && typeof args === "object" && !Array.isArray(args) ? Reflect.get(args, "requestId") : undefined;
2911
+ if (typeof requestId !== "string" || !requestId || requestId.length > 128)
2912
+ throw new Error("A request ID is required");
2913
+ const work = await options.read(requestId);
2914
+ if (!work)
2915
+ return { content: [{ type: "text", text: "No background work found for this account and request ID." }], isError: true };
2916
+ return createBackgroundWorkResult(requestId, work);
2917
+ }
2918
+ }
2919
+ };
2920
+ const start = options.start;
2921
+ if (start)
2922
+ tools.start_background_work = budgetedMcpTool({
2923
+ tool: {
2924
+ description: `${options.description} Launch bounded background work only after the user agrees to the plan and maximum credits. Return the requestId promptly; poll get_background_work for progress.`,
2925
+ inputSchema: options.inputSchema,
2926
+ handler: async () => {
2927
+ throw new Error("Background work must use durable dispatch");
2928
+ }
2929
+ },
2930
+ execute: async (request) => createBackgroundWorkResult(request.requestId, await start(request))
2931
+ });
2932
+ return tools;
2933
+ };
2885
2934
  export {
2886
2935
  COMMERCE_POLICY_SOURCES,
2887
2936
  COMMERCE_POLICY_VERSION,
@@ -2892,6 +2941,8 @@ export {
2892
2941
  budgetedMcpTool,
2893
2942
  clientSupportsMcpApps,
2894
2943
  createActionWorkflowTools,
2944
+ createBackgroundWorkResult,
2945
+ createBackgroundWorkTools,
2895
2946
  createBillingApps,
2896
2947
  createBillingManagementTool,
2897
2948
  createBillingReportTools,
@@ -0,0 +1,21 @@
1
+ import { type McpCreditWorkRequest } from "./budgetedTool";
2
+ import type { McpTool, McpToolRegistry, McpToolResult } from "./types";
3
+ /** Public output only. Adapters must scope reads to the authenticated account. */
4
+ export type McpBackgroundWorkSnapshot = {
5
+ status: "queued" | "running" | "completed" | "stopped" | "failed" | "unknown";
6
+ budget: number;
7
+ charged: number;
8
+ settled: boolean;
9
+ totalSteps: number;
10
+ results: unknown[];
11
+ };
12
+ export declare const createBackgroundWorkResult: (requestId: string, work: McpBackgroundWorkSnapshot) => McpToolResult;
13
+ /** Durable dispatch is the adapter's responsibility: atomically reserve, bind
14
+ * and enqueue before returning. Start must deduplicate exact IDs/input/budget.
15
+ * Omit start to expose account recovery without allowing new paid work. */
16
+ export declare const createBackgroundWorkTools: (options: {
17
+ description: string;
18
+ inputSchema: McpTool["inputSchema"];
19
+ start?: (request: McpCreditWorkRequest) => Promise<McpBackgroundWorkSnapshot>;
20
+ read: (requestId: string) => Promise<McpBackgroundWorkSnapshot | null>;
21
+ }) => McpToolRegistry;
@@ -54,3 +54,4 @@ export { createWorkflowTools, projectSetupStatus, projectWorkPreview, type McpSe
54
54
  export { createSetupSelectionTools, projectSetupSelection, type SetupSelection, type SetupConfirmation, type SetupOption, } from "./setupSelection";
55
55
  export { createActionWorkflowTools, projectActionReview, projectActionJob, type ActionReview, type ActionConfirmation, type ActionJob, } from "./actionWorkflow";
56
56
  export { createCreditWorkResult, type McpCreditWorkSnapshot, } from "./creditWorkResult";
57
+ export { createBackgroundWorkTools, createBackgroundWorkResult, type McpBackgroundWorkSnapshot } from "./backgroundWork";
package/package.json CHANGED
@@ -90,5 +90,5 @@
90
90
  "canary:checkout": "bun canary/checkout.ts"
91
91
  },
92
92
  "types": "./dist/src/index.d.ts",
93
- "version": "0.23.0"
93
+ "version": "0.24.0"
94
94
  }