mcp-usage-control-cloudflare 1.0.0 → 1.1.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/README.md CHANGED
@@ -40,6 +40,8 @@ For zero-downtime rotation, first copy the current token into the previous-token
40
40
 
41
41
  For applications that need to recover an ambiguous `reserve()` after a timeout/network failure, the optional `mcp-usage-control-cloudflare/reconciliation` subpath provides an authenticated read-only lookup. Use `createReconciliableCloudflareUsageStoreGateway()` and the v0.8 `reconcileRemoteCloudflareOperation()` entry point explicitly; `reconcileRemoteCloudflareReserve()` remains as a v0.7-compatible alias. Do not hide ambiguous reserve results behind generic retry middleware.
42
42
 
43
+ For scalar post-reserve transitions only, `mcp-usage-control-cloudflare/exact-retry` provides an explicit bounded wrapper that may exact-replay `markLiable()`, `renew()`, or `settle()` after timeout/network/408/429/5xx transport failures. Eligible retries use bounded exponential equal-jitter backoff (100ms base / 1000ms cap by default). An optional privacy-bounded retry observer exposes scheduled/recovered/failed operational events without raw usage identities, endpoints, or error text. Initial reserve, growth, vector reserve, and vector settlement remain single-attempt.
44
+
43
45
  Historical window cleanup is also explicit. The optional `mcp-usage-control-cloudflare/maintenance` subpath exposes a separate authenticated endpoint that prunes only application-selected historical budget keys in bounded batches. Protected/current keys and budgets referenced by active reservations are not deleted.
44
46
 
45
47
  ### Cost behavior
@@ -49,6 +51,7 @@ The adapter does not schedule alarms or intentionally keep a Durable Object acti
49
51
  - [Cloudflare adapter guide](https://github.com/git-ksk/mcp-usage-control/blob/main/docs/cloudflare.md)
50
52
  - [Deployed E2E / credential rotation](https://github.com/git-ksk/mcp-usage-control/blob/main/docs/cloudflare-deployed-e2e.md)
51
53
  - [Reserve ACK reconciliation](https://github.com/git-ksk/mcp-usage-control/blob/main/docs/cloudflare-reserve-reconciliation.md)
54
+ - [Exact post-reserve retry](https://github.com/git-ksk/mcp-usage-control/blob/main/docs/cloudflare-exact-retry.md)
52
55
  - [Historical budget pruning](https://github.com/git-ksk/mcp-usage-control/blob/main/docs/cloudflare-budget-pruning.md)
53
56
  - [SQLite schema migrations](https://github.com/git-ksk/mcp-usage-control/blob/main/docs/cloudflare-schema-migrations.md)
54
57
  - [Observability](https://github.com/git-ksk/mcp-usage-control/blob/main/docs/observability.md)
@@ -91,6 +94,8 @@ const authorize = createCloudflareBearerTokenAuthorizer({
91
94
 
92
95
  `reserve()` のtimeout / network failure後にambiguous resultを復元する必要があるapplication向けに、optionalな `mcp-usage-control-cloudflare/reconciliation` subpathがauthenticated read-only lookupを提供します。`createReconciliableCloudflareUsageStoreGateway()` とv0.8の `reconcileRemoteCloudflareOperation()` を明示的に利用してください。`reconcileRemoteCloudflareReserve()` はv0.7互換aliasとして維持します。ambiguous reserveをgeneric retry middlewareで隠さないでください。
93
96
 
97
+ scalar post-reserve transitionに限り、`mcp-usage-control-cloudflare/exact-retry` はtimeout / network / 408 / 429 / 5xx transport failure後に `markLiable()` / `renew()` / `settle()` のexact replayだけをboundedに行うexplicit wrapperを提供します。eligible retryはbounded exponential equal-jitter backoff(default base 100ms / cap 1000ms)を使います。optionalなprivacy-bounded retry observerでscheduled / recovered / failedの運用eventを取得でき、raw usage identity、endpoint、error textは出しません。initial reserve、growth、vector reserve、vector settlementはsingle-attemptのままです。
98
+
94
99
  historical window cleanupも明示操作です。optionalな `mcp-usage-control-cloudflare/maintenance` subpathは、applicationがhistoricalとして選択したbudget keyだけをbounded batchでpruneする別authenticated endpointを提供します。protected/current keyとactive reservationが参照中のbudgetは削除しません。
95
100
 
96
101
  ### Cost behavior
@@ -100,6 +105,7 @@ adapterはalarmをscheduleせず、Durable Objectを意図的に常駐させま
100
105
  - [Cloudflare adapter guide](https://github.com/git-ksk/mcp-usage-control/blob/main/docs/cloudflare.ja.md)
101
106
  - [実環境E2E / credential rotation](https://github.com/git-ksk/mcp-usage-control/blob/main/docs/cloudflare-deployed-e2e.ja.md)
102
107
  - [Reserve ACK reconciliation](https://github.com/git-ksk/mcp-usage-control/blob/main/docs/cloudflare-reserve-reconciliation.ja.md)
108
+ - [Exact post-reserve retry](https://github.com/git-ksk/mcp-usage-control/blob/main/docs/cloudflare-exact-retry.ja.md)
103
109
  - [Historical budget pruning](https://github.com/git-ksk/mcp-usage-control/blob/main/docs/cloudflare-budget-pruning.ja.md)
104
110
  - [SQLite schema migration](https://github.com/git-ksk/mcp-usage-control/blob/main/docs/cloudflare-schema-migrations.ja.md)
105
111
  - [Observability](https://github.com/git-ksk/mcp-usage-control/blob/main/docs/observability.ja.md)
@@ -0,0 +1,49 @@
1
+ import type { ProgressiveUsageStore, VectorUsageStore } from 'mcp-usage-control';
2
+ import { type RemoteCloudflareUsageStore } from './index.js';
3
+ export type RemoteCloudflareExactRetryPhase = 'mark_liable' | 'renew' | 'settle';
4
+ export type RemoteCloudflareExactRetryTransportClass = 'timeout' | 'network' | 'http_408' | 'http_429' | 'http_5xx';
5
+ export type RemoteCloudflareExactRetryEvent = {
6
+ type: 'retry.scheduled';
7
+ timestamp: number;
8
+ phase: RemoteCloudflareExactRetryPhase;
9
+ attempt: number;
10
+ maxAttempts: number;
11
+ transportClass: RemoteCloudflareExactRetryTransportClass;
12
+ delayMs: number;
13
+ } | {
14
+ type: 'retry.recovered';
15
+ timestamp: number;
16
+ phase: RemoteCloudflareExactRetryPhase;
17
+ attempts: number;
18
+ } | {
19
+ type: 'retry.failed';
20
+ timestamp: number;
21
+ phase: RemoteCloudflareExactRetryPhase;
22
+ attempts: number;
23
+ reason: 'attempts_exhausted' | 'non_retryable_after_retry';
24
+ transportClass?: RemoteCloudflareExactRetryTransportClass;
25
+ };
26
+ export interface RemoteCloudflareExactRetryObserver {
27
+ onEvent(event: RemoteCloudflareExactRetryEvent): void | Promise<void>;
28
+ }
29
+ export interface RemoteCloudflareExactRetryOptions {
30
+ /**
31
+ * Total attempts for eligible exact post-reserve replays, including the initial call.
32
+ * Defaults to 2 (one retry) and is capped at 4. Set to 1 to disable retries.
33
+ */
34
+ maxAttempts?: number;
35
+ /** Base delay before the first retry. Defaults to 100ms. */
36
+ initialBackoffMs?: number;
37
+ /** Cap for exponential retry delay. Defaults to 1000ms. */
38
+ maxBackoffMs?: number;
39
+ /** Optional best-effort, privacy-bounded retry lifecycle observer. */
40
+ observer?: RemoteCloudflareExactRetryObserver;
41
+ }
42
+ /**
43
+ * Wraps one RemoteCloudflareUsageStore with a narrowly scoped exact-replay policy.
44
+ *
45
+ * Only scalar markLiable(), renew(), and settle() are retried. Initial reserve(),
46
+ * vector reserve/settlement, and scalar/vector growth remain single-attempt.
47
+ */
48
+ export declare function createExactRetryingRemoteCloudflareUsageStore(store: RemoteCloudflareUsageStore, options?: RemoteCloudflareExactRetryOptions): ProgressiveUsageStore & VectorUsageStore;
49
+ //# sourceMappingURL=exact-retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exact-retry.d.ts","sourceRoot":"","sources":["../src/exact-retry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACjF,OAAO,EAEL,KAAK,0BAA0B,EAChC,MAAM,YAAY,CAAC;AAQpB,MAAM,MAAM,+BAA+B,GAAG,aAAa,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEjF,MAAM,MAAM,wCAAwC,GAChD,SAAS,GACT,SAAS,GACT,UAAU,GACV,UAAU,GACV,UAAU,CAAC;AAEf,MAAM,MAAM,+BAA+B,GACvC;IACE,IAAI,EAAE,iBAAiB,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,+BAA+B,CAAC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,wCAAwC,CAAC;IACzD,OAAO,EAAE,MAAM,CAAC;CACjB,GACD;IACE,IAAI,EAAE,iBAAiB,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,+BAA+B,CAAC;IACvC,QAAQ,EAAE,MAAM,CAAC;CAClB,GACD;IACE,IAAI,EAAE,cAAc,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,+BAA+B,CAAC;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,oBAAoB,GAAG,2BAA2B,CAAC;IAC3D,cAAc,CAAC,EAAE,wCAAwC,CAAC;CAC3D,CAAC;AAEN,MAAM,WAAW,kCAAkC;IACjD,OAAO,CAAC,KAAK,EAAE,+BAA+B,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvE;AAED,MAAM,WAAW,iCAAiC;IAChD;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4DAA4D;IAC5D,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,2DAA2D;IAC3D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sEAAsE;IACtE,QAAQ,CAAC,EAAE,kCAAkC,CAAC;CAC/C;AAED;;;;;GAKG;AACH,wBAAgB,6CAA6C,CAC3D,KAAK,EAAE,0BAA0B,EACjC,OAAO,GAAE,iCAAsC,GAC9C,qBAAqB,GAAG,gBAAgB,CAgD1C"}
@@ -0,0 +1,146 @@
1
+ import { CloudflareUsageTransportError, } from './index.js';
2
+ const DEFAULT_MAX_ATTEMPTS = 2;
3
+ const MAX_MAX_ATTEMPTS = 4;
4
+ const DEFAULT_INITIAL_BACKOFF_MS = 100;
5
+ const DEFAULT_MAX_BACKOFF_MS = 1_000;
6
+ const MAX_CONFIGURED_BACKOFF_MS = 60_000;
7
+ /**
8
+ * Wraps one RemoteCloudflareUsageStore with a narrowly scoped exact-replay policy.
9
+ *
10
+ * Only scalar markLiable(), renew(), and settle() are retried. Initial reserve(),
11
+ * vector reserve/settlement, and scalar/vector growth remain single-attempt.
12
+ */
13
+ export function createExactRetryingRemoteCloudflareUsageStore(store, options = {}) {
14
+ const maxAttempts = normalizeMaxAttempts(options.maxAttempts);
15
+ const backoff = normalizeBackoff(options);
16
+ return {
17
+ reserve: input => store.reserve(input),
18
+ reserveVector: input => store.reserveVector(input),
19
+ growReservation: input => store.growReservation(input),
20
+ growVectorReservation: input => store.growVectorReservation(input),
21
+ settleVector: input => store.settleVector(input),
22
+ markLiable: input => {
23
+ const exactInput = { reservationId: input.reservationId };
24
+ return runExactPostReserveReplay('mark_liable', () => store.markLiable(exactInput), maxAttempts, backoff, options.observer);
25
+ },
26
+ renew: input => {
27
+ const exactInput = { reservationId: input.reservationId, ttlMs: input.ttlMs };
28
+ return runExactPostReserveReplay('renew', () => store.renew(exactInput), maxAttempts, backoff, options.observer);
29
+ },
30
+ settle: input => {
31
+ const exactInput = {
32
+ reservationId: input.reservationId,
33
+ actualUnits: input.actualUnits,
34
+ outcome: input.outcome,
35
+ };
36
+ return runExactPostReserveReplay('settle', () => store.settle(exactInput), maxAttempts, backoff, options.observer);
37
+ },
38
+ };
39
+ }
40
+ async function runExactPostReserveReplay(phase, operation, maxAttempts, backoff, observer) {
41
+ let retryStarted = false;
42
+ for (let attempt = 1;; attempt += 1) {
43
+ try {
44
+ const result = await operation();
45
+ if (retryStarted) {
46
+ emitExactRetryEvent(observer, {
47
+ type: 'retry.recovered',
48
+ timestamp: Date.now(),
49
+ phase,
50
+ attempts: attempt,
51
+ });
52
+ }
53
+ return result;
54
+ }
55
+ catch (error) {
56
+ const transportClass = classifyRetryableExactReplayTransportError(error);
57
+ const retryable = transportClass !== undefined;
58
+ if (attempt >= maxAttempts || !retryable) {
59
+ if (retryStarted) {
60
+ emitExactRetryEvent(observer, {
61
+ type: 'retry.failed',
62
+ timestamp: Date.now(),
63
+ phase,
64
+ attempts: attempt,
65
+ reason: retryable ? 'attempts_exhausted' : 'non_retryable_after_retry',
66
+ ...(transportClass === undefined ? {} : { transportClass }),
67
+ });
68
+ }
69
+ throw error;
70
+ }
71
+ const delayMs = equalJitterBackoffMs(attempt, backoff);
72
+ emitExactRetryEvent(observer, {
73
+ type: 'retry.scheduled',
74
+ timestamp: Date.now(),
75
+ phase,
76
+ attempt: attempt + 1,
77
+ maxAttempts,
78
+ transportClass,
79
+ delayMs,
80
+ });
81
+ retryStarted = true;
82
+ await delay(delayMs);
83
+ }
84
+ }
85
+ }
86
+ function classifyRetryableExactReplayTransportError(error) {
87
+ if (!(error instanceof CloudflareUsageTransportError))
88
+ return undefined;
89
+ if (error.code === 'timeout' || error.code === 'network') {
90
+ return error.code;
91
+ }
92
+ if (error.code !== 'remote' || error.status === undefined) {
93
+ return undefined;
94
+ }
95
+ if (error.status === 408)
96
+ return 'http_408';
97
+ if (error.status === 429)
98
+ return 'http_429';
99
+ if (error.status >= 500 && error.status <= 599)
100
+ return 'http_5xx';
101
+ return undefined;
102
+ }
103
+ function normalizeMaxAttempts(value) {
104
+ const resolved = value ?? DEFAULT_MAX_ATTEMPTS;
105
+ if (!Number.isSafeInteger(resolved) || resolved < 1 || resolved > MAX_MAX_ATTEMPTS) {
106
+ throw new RangeError(`maxAttempts must be a safe integer between 1 and ${MAX_MAX_ATTEMPTS}`);
107
+ }
108
+ return resolved;
109
+ }
110
+ function normalizeBackoff(options) {
111
+ const initialMs = options.initialBackoffMs ?? DEFAULT_INITIAL_BACKOFF_MS;
112
+ const maxMs = options.maxBackoffMs ?? DEFAULT_MAX_BACKOFF_MS;
113
+ assertBackoffMs(initialMs, 'initialBackoffMs');
114
+ assertBackoffMs(maxMs, 'maxBackoffMs');
115
+ if (maxMs < initialMs) {
116
+ throw new RangeError('maxBackoffMs must be greater than or equal to initialBackoffMs');
117
+ }
118
+ return { initialMs, maxMs };
119
+ }
120
+ function assertBackoffMs(value, name) {
121
+ if (!Number.isSafeInteger(value) || value < 1 || value > MAX_CONFIGURED_BACKOFF_MS) {
122
+ throw new RangeError(`${name} must be a safe integer between 1 and ${MAX_CONFIGURED_BACKOFF_MS}`);
123
+ }
124
+ }
125
+ function equalJitterBackoffMs(failedAttempt, backoff) {
126
+ const exponential = Math.min(backoff.maxMs, backoff.initialMs * 2 ** (failedAttempt - 1));
127
+ const floor = Math.ceil(exponential / 2);
128
+ return floor + Math.floor(Math.random() * (exponential - floor + 1));
129
+ }
130
+ function delay(ms) {
131
+ return new Promise(resolve => setTimeout(resolve, ms));
132
+ }
133
+ function emitExactRetryEvent(observer, event) {
134
+ if (!observer)
135
+ return;
136
+ try {
137
+ const result = observer.onEvent(event);
138
+ if (result && typeof result.catch === 'function') {
139
+ void result.catch(() => undefined);
140
+ }
141
+ }
142
+ catch {
143
+ // Retry telemetry is best-effort and never part of accounting/enforcement.
144
+ }
145
+ }
146
+ //# sourceMappingURL=exact-retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exact-retry.js","sourceRoot":"","sources":["../src/exact-retry.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-usage-control-cloudflare",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Cloudflare Durable Objects usage store for mcp-usage-control.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -28,6 +28,11 @@
28
28
  "import": "./dist/reconciliation.js",
29
29
  "default": "./dist/reconciliation.js"
30
30
  },
31
+ "./exact-retry": {
32
+ "types": "./dist/exact-retry.d.ts",
33
+ "import": "./dist/exact-retry.js",
34
+ "default": "./dist/exact-retry.js"
35
+ },
31
36
  "./maintenance": {
32
37
  "types": "./dist/maintenance.d.ts",
33
38
  "import": "./dist/maintenance.js",
@@ -59,6 +64,10 @@
59
64
  "dist/reconciliation.js.map",
60
65
  "dist/reconciliation.d.ts",
61
66
  "dist/reconciliation.d.ts.map",
67
+ "dist/exact-retry.js",
68
+ "dist/exact-retry.js.map",
69
+ "dist/exact-retry.d.ts",
70
+ "dist/exact-retry.d.ts.map",
62
71
  "dist/reconciliation-protocol.js",
63
72
  "dist/reconciliation-protocol.js.map",
64
73
  "dist/reconciliation-protocol.d.ts",
@@ -100,9 +109,9 @@
100
109
  },
101
110
  "scripts": {
102
111
  "build": "tsc -p tsconfig.json",
103
- "test": "vitest run"
112
+ "test": "vitest run src"
104
113
  },
105
114
  "dependencies": {
106
- "mcp-usage-control": "^1.0.0"
115
+ "mcp-usage-control": "^1.1.0"
107
116
  }
108
117
  }