@absolutejs/mcp 0.23.0 → 0.25.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 +12 -0
- package/README.md +20 -0
- package/changelog.json +24 -0
- package/dist/index.js +72 -0
- package/dist/src/backgroundWork.d.ts +28 -0
- package/dist/src/index.d.ts +2 -0
- package/docs/commerce-host-rules.md +15 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,18 @@ 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.25.0 — 2026-09-13
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- **Add estimate-based background work admission while preserving exact-ID recovery and hard charge caps.** (`McpBackgroundWorkEstimate`, `createBackgroundWorkTools`)
|
|
14
|
+
|
|
15
|
+
## 0.24.0 — 2026-09-13
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- **Add durable background work launch and read-only recovery tools with matching text and structured progress.**
|
|
20
|
+
|
|
9
21
|
## 0.23.0 — 2026-09-13
|
|
10
22
|
|
|
11
23
|
### 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,30 @@
|
|
|
2
2
|
"contract": 1,
|
|
3
3
|
"name": "@absolutejs/mcp",
|
|
4
4
|
"releases": [
|
|
5
|
+
{
|
|
6
|
+
"changes": [
|
|
7
|
+
{
|
|
8
|
+
"kind": "added",
|
|
9
|
+
"summary": "Add estimate-based background work admission while preserving exact-ID recovery and hard charge caps.",
|
|
10
|
+
"symbols": [
|
|
11
|
+
"McpBackgroundWorkEstimate",
|
|
12
|
+
"createBackgroundWorkTools"
|
|
13
|
+
]
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
"date": "2026-09-13",
|
|
17
|
+
"version": "0.25.0"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"changes": [
|
|
21
|
+
{
|
|
22
|
+
"kind": "added",
|
|
23
|
+
"summary": "Add durable background work launch and read-only recovery tools with matching text and structured progress."
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
"date": "2026-09-13",
|
|
27
|
+
"version": "0.24.0"
|
|
28
|
+
},
|
|
5
29
|
{
|
|
6
30
|
"changes": [
|
|
7
31
|
{
|
package/dist/index.js
CHANGED
|
@@ -2882,6 +2882,76 @@ 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 estimate = options.estimate;
|
|
2921
|
+
if (estimate)
|
|
2922
|
+
tools.estimate_background_work = {
|
|
2923
|
+
description: "Estimate service credits for a background plan without reserving credits or starting work. The minimum admits one step; the total estimates the whole plan. Actual usage varies. Get the user's approval for the maximum before starting; never silently increase it.",
|
|
2924
|
+
annotations: { readOnlyHint: true },
|
|
2925
|
+
commerce: { action: "paid_access", categories: ["usage_credits"] },
|
|
2926
|
+
inputSchema: options.inputSchema,
|
|
2927
|
+
handler: async (input) => {
|
|
2928
|
+
const value = await estimate(input);
|
|
2929
|
+
if (![value.minimumCredits, value.estimatedCredits, value.totalSteps].every(Number.isSafeInteger) || value.minimumCredits < 1 || value.estimatedCredits < value.minimumCredits || value.totalSteps < 1 || typeof value.assumptions !== "string" || !value.assumptions)
|
|
2930
|
+
throw new Error("Invalid background work estimate");
|
|
2931
|
+
const summary = {
|
|
2932
|
+
minimumCredits: value.minimumCredits,
|
|
2933
|
+
estimatedCredits: value.estimatedCredits,
|
|
2934
|
+
totalSteps: value.totalSteps,
|
|
2935
|
+
assumptions: value.assumptions,
|
|
2936
|
+
message: "Estimate only, not a quote or guarantee. No credits reserved and no work started. Admission is checked again at start and before each step; work can stop with partial results. The approved maximum charge is never increased."
|
|
2937
|
+
};
|
|
2938
|
+
return { content: [{ type: "text", text: JSON.stringify(summary) }], structuredContent: summary };
|
|
2939
|
+
}
|
|
2940
|
+
};
|
|
2941
|
+
const start = options.start;
|
|
2942
|
+
if (start)
|
|
2943
|
+
tools.start_background_work = budgetedMcpTool({
|
|
2944
|
+
tool: {
|
|
2945
|
+
description: `${options.description} Use estimate_background_work when available before asking for a budget. 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.`,
|
|
2946
|
+
inputSchema: options.inputSchema,
|
|
2947
|
+
handler: async () => {
|
|
2948
|
+
throw new Error("Background work must use durable dispatch");
|
|
2949
|
+
}
|
|
2950
|
+
},
|
|
2951
|
+
execute: async (request) => createBackgroundWorkResult(request.requestId, await start(request))
|
|
2952
|
+
});
|
|
2953
|
+
return tools;
|
|
2954
|
+
};
|
|
2885
2955
|
export {
|
|
2886
2956
|
COMMERCE_POLICY_SOURCES,
|
|
2887
2957
|
COMMERCE_POLICY_VERSION,
|
|
@@ -2892,6 +2962,8 @@ export {
|
|
|
2892
2962
|
budgetedMcpTool,
|
|
2893
2963
|
clientSupportsMcpApps,
|
|
2894
2964
|
createActionWorkflowTools,
|
|
2965
|
+
createBackgroundWorkResult,
|
|
2966
|
+
createBackgroundWorkTools,
|
|
2895
2967
|
createBillingApps,
|
|
2896
2968
|
createBillingManagementTool,
|
|
2897
2969
|
createBillingReportTools,
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type McpCreditWorkRequest } from "./budgetedTool";
|
|
2
|
+
import type { McpTool, McpToolRegistry, McpToolResult } from "./types";
|
|
3
|
+
export type McpBackgroundWorkEstimate = {
|
|
4
|
+
minimumCredits: number;
|
|
5
|
+
estimatedCredits: number;
|
|
6
|
+
totalSteps: number;
|
|
7
|
+
assumptions: string;
|
|
8
|
+
};
|
|
9
|
+
/** Public output only. Adapters must scope reads to the authenticated account. */
|
|
10
|
+
export type McpBackgroundWorkSnapshot = {
|
|
11
|
+
status: "queued" | "running" | "completed" | "stopped" | "failed" | "unknown";
|
|
12
|
+
budget: number;
|
|
13
|
+
charged: number;
|
|
14
|
+
settled: boolean;
|
|
15
|
+
totalSteps: number;
|
|
16
|
+
results: unknown[];
|
|
17
|
+
};
|
|
18
|
+
export declare const createBackgroundWorkResult: (requestId: string, work: McpBackgroundWorkSnapshot) => McpToolResult;
|
|
19
|
+
/** Durable dispatch is the adapter's responsibility: atomically reserve, bind
|
|
20
|
+
* and enqueue before returning. Start must deduplicate exact IDs/input/budget.
|
|
21
|
+
* Omit start to expose account recovery without allowing new paid work. */
|
|
22
|
+
export declare const createBackgroundWorkTools: (options: {
|
|
23
|
+
description: string;
|
|
24
|
+
inputSchema: McpTool["inputSchema"];
|
|
25
|
+
estimate?: (input: unknown) => Promise<McpBackgroundWorkEstimate>;
|
|
26
|
+
start?: (request: McpCreditWorkRequest) => Promise<McpBackgroundWorkSnapshot>;
|
|
27
|
+
read: (requestId: string) => Promise<McpBackgroundWorkSnapshot | null>;
|
|
28
|
+
}) => McpToolRegistry;
|
package/dist/src/index.d.ts
CHANGED
|
@@ -54,3 +54,5 @@ 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";
|
|
58
|
+
export type { McpBackgroundWorkEstimate } from "./backgroundWork";
|
|
@@ -368,3 +368,18 @@ bounded work until their reservation and recovery lifecycle is implemented.
|
|
|
368
368
|
This documentation update changes no runtime API, profile, feature flag or
|
|
369
369
|
published package version. It is available in the shared repository and will
|
|
370
370
|
ship with the next package release through the existing documentation allowlist.
|
|
371
|
+
|
|
372
|
+
### Background research estimates
|
|
373
|
+
|
|
374
|
+
`createBackgroundWorkTools({ estimate, start, read, ... })` optionally exposes
|
|
375
|
+
`estimate_background_work`. Its adapter returns minimum credits for one step,
|
|
376
|
+
estimated total credits, total steps and explicit assumptions. Public output is
|
|
377
|
+
identical in text and structured hosts, and omits adapter-private fields. No
|
|
378
|
+
provider work or reservation belongs in the estimate adapter.
|
|
379
|
+
|
|
380
|
+
Estimates use `paid_access` commerce policy, so a restricted host cannot use this
|
|
381
|
+
as a pricing/purchase workaround. Obtain user agreement to the exact plan and
|
|
382
|
+
maximum before start. Server-side start must reevaluate admission atomically;
|
|
383
|
+
never silently raise a maximum. Saved-work reads remain separate and credit-free.
|
|
384
|
+
An estimate is advisory, not an expiring quote or guaranteed cost. Bind input,
|
|
385
|
+
account and maximum durably; exact-ID recovery must not depend on current pricing.
|
package/package.json
CHANGED