@revealui/mcp 0.1.1 → 0.1.5
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/LICENSE.commercial +2 -3
- package/dist/adapters/db.d.ts +1 -1
- package/dist/adapters/db.d.ts.map +1 -1
- package/dist/adapters/db.js.map +1 -1
- package/dist/auth.d.ts +42 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +73 -0
- package/dist/auth.js.map +1 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js.map +1 -1
- package/dist/contracts.d.ts +36 -0
- package/dist/contracts.d.ts.map +1 -1
- package/dist/contracts.js +44 -0
- package/dist/contracts.js.map +1 -1
- package/dist/hypervisor.d.ts +63 -0
- package/dist/hypervisor.d.ts.map +1 -1
- package/dist/hypervisor.js +287 -4
- package/dist/hypervisor.js.map +1 -1
- package/dist/index.d.ts +22 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +26 -5
- package/dist/index.js.map +1 -1
- package/dist/pipeline.d.ts +62 -0
- package/dist/pipeline.d.ts.map +1 -0
- package/dist/pipeline.js +230 -0
- package/dist/pipeline.js.map +1 -0
- package/dist/rate-limiter.d.ts +53 -0
- package/dist/rate-limiter.d.ts.map +1 -0
- package/dist/rate-limiter.js +96 -0
- package/dist/rate-limiter.js.map +1 -0
- package/dist/servers/_launcher-utils.d.ts +28 -0
- package/dist/servers/_launcher-utils.d.ts.map +1 -0
- package/dist/servers/_launcher-utils.js +45 -0
- package/dist/servers/_launcher-utils.js.map +1 -0
- package/dist/servers/adapter.d.ts +22 -6
- package/dist/servers/adapter.d.ts.map +1 -1
- package/dist/servers/adapter.js +53 -22
- package/dist/servers/adapter.js.map +1 -1
- package/dist/servers/neon.d.ts +15 -0
- package/dist/servers/neon.d.ts.map +1 -0
- package/dist/servers/neon.js +89 -0
- package/dist/servers/neon.js.map +1 -0
- package/dist/servers/next-devtools.d.ts +15 -0
- package/dist/servers/next-devtools.d.ts.map +1 -0
- package/dist/servers/next-devtools.js +220 -0
- package/dist/servers/next-devtools.js.map +1 -0
- package/dist/servers/playwright.d.ts +15 -0
- package/dist/servers/playwright.d.ts.map +1 -0
- package/dist/servers/playwright.js +73 -0
- package/dist/servers/playwright.js.map +1 -0
- package/dist/servers/revealui-content.d.ts +5 -1
- package/dist/servers/revealui-content.d.ts.map +1 -1
- package/dist/servers/revealui-content.js +62 -20
- package/dist/servers/revealui-content.js.map +1 -1
- package/dist/servers/revealui-email.d.ts +5 -1
- package/dist/servers/revealui-email.d.ts.map +1 -1
- package/dist/servers/revealui-email.js +47 -12
- package/dist/servers/revealui-email.js.map +1 -1
- package/dist/servers/revealui-stripe.d.ts +5 -1
- package/dist/servers/revealui-stripe.d.ts.map +1 -1
- package/dist/servers/revealui-stripe.js +68 -33
- package/dist/servers/revealui-stripe.js.map +1 -1
- package/dist/servers/stripe.d.ts +15 -0
- package/dist/servers/stripe.d.ts.map +1 -0
- package/dist/servers/stripe.js +85 -0
- package/dist/servers/stripe.js.map +1 -0
- package/dist/servers/supabase.d.ts +15 -0
- package/dist/servers/supabase.d.ts.map +1 -0
- package/dist/servers/supabase.js +143 -0
- package/dist/servers/supabase.js.map +1 -0
- package/dist/servers/vercel.d.ts +15 -0
- package/dist/servers/vercel.d.ts.map +1 -0
- package/dist/servers/vercel.js +86 -0
- package/dist/servers/vercel.js.map +1 -0
- package/dist/stores/postgres-idempotency.d.ts +32 -0
- package/dist/stores/postgres-idempotency.d.ts.map +1 -0
- package/dist/stores/postgres-idempotency.js +63 -0
- package/dist/stores/postgres-idempotency.js.map +1 -0
- package/dist/telemetry.d.ts +75 -0
- package/dist/telemetry.d.ts.map +1 -0
- package/dist/telemetry.js +110 -0
- package/dist/telemetry.js.map +1 -0
- package/package.json +47 -27
package/dist/pipeline.js
ADDED
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool Pipeline
|
|
3
|
+
*
|
|
4
|
+
* Lightweight tool composition that lets agents chain MCP tool calls
|
|
5
|
+
* declaratively. Steps execute sequentially, with data flowing between
|
|
6
|
+
* them via `$ref` parameter references.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* const result = await executePipeline(hypervisor, ctx, [
|
|
11
|
+
* {
|
|
12
|
+
* label: 'customer',
|
|
13
|
+
* tool: '@@mcp_stripe_create_customer',
|
|
14
|
+
* params: { email: 'user@example.com' },
|
|
15
|
+
* },
|
|
16
|
+
* {
|
|
17
|
+
* label: 'payment',
|
|
18
|
+
* tool: '@@mcp_stripe_create_payment_intent',
|
|
19
|
+
* params: {
|
|
20
|
+
* customer: { $ref: 'customer.id' },
|
|
21
|
+
* amount: 2000,
|
|
22
|
+
* currency: 'usd',
|
|
23
|
+
* },
|
|
24
|
+
* },
|
|
25
|
+
* ]);
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
// =============================================================================
|
|
29
|
+
// Constants
|
|
30
|
+
// =============================================================================
|
|
31
|
+
const MCP_TOOL_PREFIX = '@@mcp_';
|
|
32
|
+
// =============================================================================
|
|
33
|
+
// Pipeline executor
|
|
34
|
+
// =============================================================================
|
|
35
|
+
/**
|
|
36
|
+
* Execute a sequence of tool calls with data flowing between steps.
|
|
37
|
+
*
|
|
38
|
+
* Parameter references: use `{ "$ref": "step_label.path.to.value" }`
|
|
39
|
+
* to reference output from a previous step.
|
|
40
|
+
*
|
|
41
|
+
* Tools are identified by their namespaced name (`@@mcp_{server}_{tool}`)
|
|
42
|
+
* and dispatched through the hypervisor's tenant-scoped call path.
|
|
43
|
+
*/
|
|
44
|
+
export async function executePipeline(hypervisor, ctx, steps) {
|
|
45
|
+
const results = new Map();
|
|
46
|
+
const stepResults = [];
|
|
47
|
+
const pipelineStart = Date.now();
|
|
48
|
+
for (let i = 0; i < steps.length; i++) {
|
|
49
|
+
const step = steps[i];
|
|
50
|
+
if (!step)
|
|
51
|
+
continue;
|
|
52
|
+
const label = step.label ?? `step_${i}`;
|
|
53
|
+
const stepStart = Date.now();
|
|
54
|
+
// Check condition
|
|
55
|
+
if (step.when && !step.when(results)) {
|
|
56
|
+
stepResults.push({
|
|
57
|
+
label,
|
|
58
|
+
tool: step.tool,
|
|
59
|
+
success: true,
|
|
60
|
+
data: { skipped: true },
|
|
61
|
+
durationMs: 0,
|
|
62
|
+
});
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
// Resolve $ref parameters
|
|
66
|
+
const resolvedParams = resolveRefs(step.params, results);
|
|
67
|
+
try {
|
|
68
|
+
// Parse the namespaced tool name into server + tool
|
|
69
|
+
const { serverName, toolName } = parseNamespacedTool(step.tool);
|
|
70
|
+
// Call the tool through the hypervisor's tenant-scoped path
|
|
71
|
+
const response = await hypervisor.callToolForTenant(serverName, ctx.tenantId, toolName, resolvedParams);
|
|
72
|
+
// Attempt to parse text content responses as JSON
|
|
73
|
+
const data = extractResponseData(response);
|
|
74
|
+
results.set(label, data);
|
|
75
|
+
stepResults.push({
|
|
76
|
+
label,
|
|
77
|
+
tool: step.tool,
|
|
78
|
+
success: true,
|
|
79
|
+
data,
|
|
80
|
+
durationMs: Date.now() - stepStart,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
85
|
+
stepResults.push({
|
|
86
|
+
label,
|
|
87
|
+
tool: step.tool,
|
|
88
|
+
success: false,
|
|
89
|
+
error: errorMsg,
|
|
90
|
+
durationMs: Date.now() - stepStart,
|
|
91
|
+
});
|
|
92
|
+
// Pipeline fails on first error
|
|
93
|
+
return {
|
|
94
|
+
success: false,
|
|
95
|
+
steps: stepResults,
|
|
96
|
+
totalDurationMs: Date.now() - pipelineStart,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return {
|
|
101
|
+
success: true,
|
|
102
|
+
steps: stepResults,
|
|
103
|
+
totalDurationMs: Date.now() - pipelineStart,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
// =============================================================================
|
|
107
|
+
// Tool name parsing
|
|
108
|
+
// =============================================================================
|
|
109
|
+
/**
|
|
110
|
+
* Parse a namespaced tool name like `@@mcp_stripe_create_payment_intent`
|
|
111
|
+
* into `{ serverName: 'stripe', toolName: 'create_payment_intent' }`.
|
|
112
|
+
*
|
|
113
|
+
* The convention is `@@mcp_{serverName}_{toolName}` where the server name
|
|
114
|
+
* is the first segment after the prefix and the tool name is everything
|
|
115
|
+
* after it (may contain underscores).
|
|
116
|
+
*/
|
|
117
|
+
function parseNamespacedTool(namespacedName) {
|
|
118
|
+
if (!namespacedName.startsWith(MCP_TOOL_PREFIX)) {
|
|
119
|
+
throw new Error(`Invalid tool name "${namespacedName}": must start with "${MCP_TOOL_PREFIX}"`);
|
|
120
|
+
}
|
|
121
|
+
const rest = namespacedName.slice(MCP_TOOL_PREFIX.length);
|
|
122
|
+
const firstUnderscore = rest.indexOf('_');
|
|
123
|
+
if (firstUnderscore === -1 || firstUnderscore === 0) {
|
|
124
|
+
throw new Error(`Invalid tool name "${namespacedName}": expected format "${MCP_TOOL_PREFIX}{server}_{tool}"`);
|
|
125
|
+
}
|
|
126
|
+
return {
|
|
127
|
+
serverName: rest.slice(0, firstUnderscore),
|
|
128
|
+
toolName: rest.slice(firstUnderscore + 1),
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
// =============================================================================
|
|
132
|
+
// Response extraction
|
|
133
|
+
// =============================================================================
|
|
134
|
+
/**
|
|
135
|
+
* Attempt to extract structured data from an MCP tool response.
|
|
136
|
+
* If the response contains a text content block with valid JSON, parse it.
|
|
137
|
+
* Otherwise return the raw response.
|
|
138
|
+
*/
|
|
139
|
+
function extractResponseData(response) {
|
|
140
|
+
if (typeof response === 'object' &&
|
|
141
|
+
response !== null &&
|
|
142
|
+
'content' in response &&
|
|
143
|
+
Array.isArray(response.content)) {
|
|
144
|
+
const content = response.content;
|
|
145
|
+
const first = content[0];
|
|
146
|
+
if (first &&
|
|
147
|
+
typeof first === 'object' &&
|
|
148
|
+
'type' in first &&
|
|
149
|
+
first.type === 'text' &&
|
|
150
|
+
'text' in first) {
|
|
151
|
+
try {
|
|
152
|
+
return JSON.parse(first.text);
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
// Not JSON — return raw text
|
|
156
|
+
return first.text;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return response;
|
|
161
|
+
}
|
|
162
|
+
// =============================================================================
|
|
163
|
+
// $ref resolution
|
|
164
|
+
// =============================================================================
|
|
165
|
+
/**
|
|
166
|
+
* Resolve `$ref` values in params by looking up previous step results.
|
|
167
|
+
* Format: `{ "$ref": "step_label.path.to.value" }`
|
|
168
|
+
*/
|
|
169
|
+
function resolveRefs(params, results) {
|
|
170
|
+
const resolved = {};
|
|
171
|
+
for (const [key, value] of Object.entries(params)) {
|
|
172
|
+
if (isRef(value)) {
|
|
173
|
+
resolved[key] = resolveRef(value.$ref, results);
|
|
174
|
+
}
|
|
175
|
+
else if (Array.isArray(value)) {
|
|
176
|
+
resolved[key] = resolveRefsInArray(value, results);
|
|
177
|
+
}
|
|
178
|
+
else if (typeof value === 'object' && value !== null) {
|
|
179
|
+
resolved[key] = resolveRefs(value, results);
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
resolved[key] = value;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return resolved;
|
|
186
|
+
}
|
|
187
|
+
function resolveRefsInArray(items, results) {
|
|
188
|
+
return items.map((item) => {
|
|
189
|
+
if (isRef(item)) {
|
|
190
|
+
return resolveRef(item.$ref, results);
|
|
191
|
+
}
|
|
192
|
+
if (Array.isArray(item)) {
|
|
193
|
+
return resolveRefsInArray(item, results);
|
|
194
|
+
}
|
|
195
|
+
if (typeof item === 'object' && item !== null) {
|
|
196
|
+
return resolveRefs(item, results);
|
|
197
|
+
}
|
|
198
|
+
return item;
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
function isRef(value) {
|
|
202
|
+
return (typeof value === 'object' &&
|
|
203
|
+
value !== null &&
|
|
204
|
+
!Array.isArray(value) &&
|
|
205
|
+
'$ref' in value &&
|
|
206
|
+
typeof value.$ref === 'string');
|
|
207
|
+
}
|
|
208
|
+
function resolveRef(ref, results) {
|
|
209
|
+
const parts = ref.split('.');
|
|
210
|
+
const stepLabel = parts[0];
|
|
211
|
+
if (!stepLabel) {
|
|
212
|
+
throw new Error('Pipeline ref error: empty $ref string');
|
|
213
|
+
}
|
|
214
|
+
const data = results.get(stepLabel);
|
|
215
|
+
if (data === undefined) {
|
|
216
|
+
throw new Error(`Pipeline ref error: step "${stepLabel}" not found`);
|
|
217
|
+
}
|
|
218
|
+
let current = data;
|
|
219
|
+
for (let i = 1; i < parts.length; i++) {
|
|
220
|
+
if (current === null || current === undefined) {
|
|
221
|
+
throw new Error(`Pipeline ref error: cannot traverse "${ref}" — null at "${parts.slice(0, i + 1).join('.')}"`);
|
|
222
|
+
}
|
|
223
|
+
const segment = parts[i];
|
|
224
|
+
if (!segment)
|
|
225
|
+
continue;
|
|
226
|
+
current = current[segment];
|
|
227
|
+
}
|
|
228
|
+
return current;
|
|
229
|
+
}
|
|
230
|
+
//# sourceMappingURL=pipeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAkCH,gFAAgF;AAChF,YAAY;AACZ,gFAAgF;AAEhF,MAAM,eAAe,GAAG,QAAQ,CAAC;AAEjC,gFAAgF;AAChF,oBAAoB;AACpB,gFAAgF;AAEhF;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,UAAyB,EACzB,GAAqB,EACrB,KAAqB;IAErB,MAAM,OAAO,GAAG,IAAI,GAAG,EAAmB,CAAC;IAC3C,MAAM,WAAW,GAAyB,EAAE,CAAC;IAC7C,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,CAAC,IAAI;YAAE,SAAS;QAEpB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,QAAQ,CAAC,EAAE,CAAC;QACxC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE7B,kBAAkB;QAClB,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YACrC,WAAW,CAAC,IAAI,CAAC;gBACf,KAAK;gBACL,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,OAAO,EAAE,IAAI;gBACb,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE;gBACvB,UAAU,EAAE,CAAC;aACd,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QAED,0BAA0B;QAC1B,MAAM,cAAc,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAEzD,IAAI,CAAC;YACH,oDAAoD;YACpD,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAEhE,4DAA4D;YAC5D,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,iBAAiB,CACjD,UAAU,EACV,GAAG,CAAC,QAAQ,EACZ,QAAQ,EACR,cAAc,CACf,CAAC;YAEF,kDAAkD;YAClD,MAAM,IAAI,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAC;YAE3C,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YACzB,WAAW,CAAC,IAAI,CAAC;gBACf,KAAK;gBACL,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,OAAO,EAAE,IAAI;gBACb,IAAI;gBACJ,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;aACnC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,QAAQ,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACxE,WAAW,CAAC,IAAI,CAAC;gBACf,KAAK;gBACL,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,QAAQ;gBACf,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;aACnC,CAAC,CAAC;YAEH,gCAAgC;YAChC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,WAAW;gBAClB,eAAe,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,aAAa;aAC5C,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO;QACL,OAAO,EAAE,IAAI;QACb,KAAK,EAAE,WAAW;QAClB,eAAe,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,aAAa;KAC5C,CAAC;AACJ,CAAC;AAED,gFAAgF;AAChF,oBAAoB;AACpB,gFAAgF;AAEhF;;;;;;;GAOG;AACH,SAAS,mBAAmB,CAAC,cAAsB;IAIjD,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;QAChD,MAAM,IAAI,KAAK,CAAC,sBAAsB,cAAc,uBAAuB,eAAe,GAAG,CAAC,CAAC;IACjG,CAAC;IAED,MAAM,IAAI,GAAG,cAAc,CAAC,KAAK,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;IAC1D,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAE1C,IAAI,eAAe,KAAK,CAAC,CAAC,IAAI,eAAe,KAAK,CAAC,EAAE,CAAC;QACpD,MAAM,IAAI,KAAK,CACb,sBAAsB,cAAc,uBAAuB,eAAe,kBAAkB,CAC7F,CAAC;IACJ,CAAC;IAED,OAAO;QACL,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,eAAe,CAAC;QAC1C,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,eAAe,GAAG,CAAC,CAAC;KAC1C,CAAC;AACJ,CAAC;AAED,gFAAgF;AAChF,sBAAsB;AACtB,gFAAgF;AAEhF;;;;GAIG;AACH,SAAS,mBAAmB,CAAC,QAAiB;IAC5C,IACE,OAAO,QAAQ,KAAK,QAAQ;QAC5B,QAAQ,KAAK,IAAI;QACjB,SAAS,IAAI,QAAQ;QACrB,KAAK,CAAC,OAAO,CAAE,QAAiC,CAAC,OAAO,CAAC,EACzD,CAAC;QACD,MAAM,OAAO,GAAI,QAAmC,CAAC,OAAO,CAAC;QAC7D,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QACzB,IACE,KAAK;YACL,OAAO,KAAK,KAAK,QAAQ;YACzB,MAAM,IAAI,KAAK;YACd,KAA0B,CAAC,IAAI,KAAK,MAAM;YAC3C,MAAM,IAAI,KAAK,EACf,CAAC;YACD,IAAI,CAAC;gBACH,OAAO,IAAI,CAAC,KAAK,CAAE,KAA0B,CAAC,IAAI,CAAC,CAAC;YACtD,CAAC;YAAC,MAAM,CAAC;gBACP,6BAA6B;gBAC7B,OAAQ,KAA0B,CAAC,IAAI,CAAC;YAC1C,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,gFAAgF;AAChF,kBAAkB;AAClB,gFAAgF;AAEhF;;;GAGG;AACH,SAAS,WAAW,CAClB,MAA+B,EAC/B,OAA6B;IAE7B,MAAM,QAAQ,GAA4B,EAAE,CAAC;IAE7C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,IAAI,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YACjB,QAAQ,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAClD,CAAC;aAAM,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAChC,QAAQ,CAAC,GAAG,CAAC,GAAG,kBAAkB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACrD,CAAC;aAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACvD,QAAQ,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,KAAgC,EAAE,OAAO,CAAC,CAAC;QACzE,CAAC;aAAM,CAAC;YACN,QAAQ,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACxB,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAgB,EAAE,OAA6B;IACzE,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACxB,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAChB,OAAO,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACxC,CAAC;QACD,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,OAAO,kBAAkB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC3C,CAAC;QACD,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAC9C,OAAO,WAAW,CAAC,IAA+B,EAAE,OAAO,CAAC,CAAC;QAC/D,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,KAAK,CAAC,KAAc;IAC3B,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACrB,MAAM,IAAI,KAAK;QACf,OAAQ,KAAiC,CAAC,IAAI,KAAK,QAAQ,CAC5D,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,GAAW,EAAE,OAA6B;IAC5D,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC7B,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAE3B,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC3D,CAAC;IAED,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACpC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,6BAA6B,SAAS,aAAa,CAAC,CAAC;IACvE,CAAC;IAED,IAAI,OAAO,GAAY,IAAI,CAAC;IAC5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC9C,MAAM,IAAI,KAAK,CACb,wCAAwC,GAAG,gBAAgB,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAC9F,CAAC;QACJ,CAAC;QACD,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACzB,IAAI,CAAC,OAAO;YAAE,SAAS;QACvB,OAAO,GAAI,OAAmC,CAAC,OAAO,CAAC,CAAC;IAC1D,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Rate Limiter
|
|
3
|
+
*
|
|
4
|
+
* In-memory fixed-window rate limiter scoped by tenant + tier.
|
|
5
|
+
* For distributed deployments, replace with a Redis-backed implementation.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const limiter = new McpRateLimiter();
|
|
10
|
+
*
|
|
11
|
+
* const result = limiter.check('tenant-123', 'pro');
|
|
12
|
+
* if (!result.allowed) {
|
|
13
|
+
* throw new Error(`Rate limited. Retry after ${result.resetMs}ms`);
|
|
14
|
+
* }
|
|
15
|
+
* // result.remaining === requests left in window
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export interface RateLimitConfig {
|
|
19
|
+
/** Max requests per window */
|
|
20
|
+
maxRequests: number;
|
|
21
|
+
/** Window size in milliseconds */
|
|
22
|
+
windowMs: number;
|
|
23
|
+
}
|
|
24
|
+
export interface RateLimitResult {
|
|
25
|
+
allowed: boolean;
|
|
26
|
+
remaining: number;
|
|
27
|
+
limit: number;
|
|
28
|
+
resetMs: number;
|
|
29
|
+
}
|
|
30
|
+
/** Default rate limits per tier. */
|
|
31
|
+
export declare const DEFAULT_TIER_LIMITS: Record<string, RateLimitConfig>;
|
|
32
|
+
/**
|
|
33
|
+
* In-memory fixed-window rate limiter scoped by tenant + tier.
|
|
34
|
+
* For distributed deployments, replace with a Redis-backed implementation.
|
|
35
|
+
*/
|
|
36
|
+
export declare class McpRateLimiter {
|
|
37
|
+
private windows;
|
|
38
|
+
private limits;
|
|
39
|
+
private cleanupInterval;
|
|
40
|
+
constructor(limits?: Record<string, RateLimitConfig>);
|
|
41
|
+
/**
|
|
42
|
+
* Check if a request is allowed and consume one token if so.
|
|
43
|
+
* Returns quota information including remaining requests and reset time.
|
|
44
|
+
*/
|
|
45
|
+
check(tenantId: string, tier: string): RateLimitResult;
|
|
46
|
+
/** Override limits for a specific tier. */
|
|
47
|
+
setTierLimit(tier: string, config: RateLimitConfig): void;
|
|
48
|
+
/** Clean up expired window entries. */
|
|
49
|
+
private cleanup;
|
|
50
|
+
/** Dispose the rate limiter, clearing the cleanup timer and all windows. */
|
|
51
|
+
dispose(): void;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=rate-limiter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-limiter.d.ts","sourceRoot":"","sources":["../src/rate-limiter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH,MAAM,WAAW,eAAe;IAC9B,8BAA8B;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,kCAAkC;IAClC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAMD,oCAAoC;AACpC,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAK/D,CAAC;AAeF;;;GAGG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAAkC;IACjD,OAAO,CAAC,MAAM,CAAkC;IAChD,OAAO,CAAC,eAAe,CAA+C;gBAE1D,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAuB;IAOzE;;;OAGG;IACH,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,eAAe;IA4BtD,2CAA2C;IAC3C,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI;IAIzD,uCAAuC;IACvC,OAAO,CAAC,OAAO;IAWf,4EAA4E;IAC5E,OAAO,IAAI,IAAI;CAOhB"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Rate Limiter
|
|
3
|
+
*
|
|
4
|
+
* In-memory fixed-window rate limiter scoped by tenant + tier.
|
|
5
|
+
* For distributed deployments, replace with a Redis-backed implementation.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const limiter = new McpRateLimiter();
|
|
10
|
+
*
|
|
11
|
+
* const result = limiter.check('tenant-123', 'pro');
|
|
12
|
+
* if (!result.allowed) {
|
|
13
|
+
* throw new Error(`Rate limited. Retry after ${result.resetMs}ms`);
|
|
14
|
+
* }
|
|
15
|
+
* // result.remaining === requests left in window
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
// =============================================================================
|
|
19
|
+
// Default tier limits
|
|
20
|
+
// =============================================================================
|
|
21
|
+
/** Default rate limits per tier. */
|
|
22
|
+
export const DEFAULT_TIER_LIMITS = {
|
|
23
|
+
free: { maxRequests: 60, windowMs: 60_000 },
|
|
24
|
+
pro: { maxRequests: 300, windowMs: 60_000 },
|
|
25
|
+
max: { maxRequests: 1000, windowMs: 60_000 },
|
|
26
|
+
enterprise: { maxRequests: 5000, windowMs: 60_000 },
|
|
27
|
+
};
|
|
28
|
+
// =============================================================================
|
|
29
|
+
// Rate limiter
|
|
30
|
+
// =============================================================================
|
|
31
|
+
/**
|
|
32
|
+
* In-memory fixed-window rate limiter scoped by tenant + tier.
|
|
33
|
+
* For distributed deployments, replace with a Redis-backed implementation.
|
|
34
|
+
*/
|
|
35
|
+
export class McpRateLimiter {
|
|
36
|
+
windows = new Map();
|
|
37
|
+
limits;
|
|
38
|
+
cleanupInterval = null;
|
|
39
|
+
constructor(limits = DEFAULT_TIER_LIMITS) {
|
|
40
|
+
this.limits = limits;
|
|
41
|
+
// Clean up expired windows every 60s
|
|
42
|
+
this.cleanupInterval = setInterval(() => this.cleanup(), 60_000);
|
|
43
|
+
if (this.cleanupInterval.unref)
|
|
44
|
+
this.cleanupInterval.unref();
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Check if a request is allowed and consume one token if so.
|
|
48
|
+
* Returns quota information including remaining requests and reset time.
|
|
49
|
+
*/
|
|
50
|
+
check(tenantId, tier) {
|
|
51
|
+
const config = this.limits[tier] ?? this.limits.free ?? { maxRequests: 60, windowMs: 60_000 };
|
|
52
|
+
const key = `${tenantId}:${tier}`;
|
|
53
|
+
const now = Date.now();
|
|
54
|
+
let entry = this.windows.get(key);
|
|
55
|
+
// New window or expired window
|
|
56
|
+
if (!entry || now - entry.windowStart >= config.windowMs) {
|
|
57
|
+
entry = { count: 0, windowStart: now };
|
|
58
|
+
this.windows.set(key, entry);
|
|
59
|
+
}
|
|
60
|
+
const resetMs = config.windowMs - (now - entry.windowStart);
|
|
61
|
+
if (entry.count >= config.maxRequests) {
|
|
62
|
+
return { allowed: false, remaining: 0, limit: config.maxRequests, resetMs };
|
|
63
|
+
}
|
|
64
|
+
entry.count++;
|
|
65
|
+
return {
|
|
66
|
+
allowed: true,
|
|
67
|
+
remaining: Math.max(0, config.maxRequests - entry.count),
|
|
68
|
+
limit: config.maxRequests,
|
|
69
|
+
resetMs,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/** Override limits for a specific tier. */
|
|
73
|
+
setTierLimit(tier, config) {
|
|
74
|
+
this.limits[tier] = config;
|
|
75
|
+
}
|
|
76
|
+
/** Clean up expired window entries. */
|
|
77
|
+
cleanup() {
|
|
78
|
+
const now = Date.now();
|
|
79
|
+
for (const [key, entry] of this.windows) {
|
|
80
|
+
const tier = key.split(':')[1] ?? 'free';
|
|
81
|
+
const config = this.limits[tier] ?? { windowMs: 60_000 };
|
|
82
|
+
if (now - entry.windowStart >= config.windowMs * 2) {
|
|
83
|
+
this.windows.delete(key);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/** Dispose the rate limiter, clearing the cleanup timer and all windows. */
|
|
88
|
+
dispose() {
|
|
89
|
+
if (this.cleanupInterval) {
|
|
90
|
+
clearInterval(this.cleanupInterval);
|
|
91
|
+
this.cleanupInterval = null;
|
|
92
|
+
}
|
|
93
|
+
this.windows.clear();
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=rate-limiter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-limiter.js","sourceRoot":"","sources":["../src/rate-limiter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Launcher Utilities
|
|
3
|
+
*
|
|
4
|
+
* Self-contained logger and exit codes for MCP server launcher scripts.
|
|
5
|
+
* Replaces the @revealui/scripts dependency so the MCP package has no
|
|
6
|
+
* cross-package imports beyond its own declared dependencies.
|
|
7
|
+
*/
|
|
8
|
+
export declare const ExitCode: {
|
|
9
|
+
readonly SUCCESS: 0;
|
|
10
|
+
readonly GENERAL_ERROR: 1;
|
|
11
|
+
readonly CONFIG_ERROR: 2;
|
|
12
|
+
readonly EXECUTION_ERROR: 3;
|
|
13
|
+
};
|
|
14
|
+
export type ExitCode = (typeof ExitCode)[keyof typeof ExitCode];
|
|
15
|
+
interface LauncherLogger {
|
|
16
|
+
info(msg: string): void;
|
|
17
|
+
error(msg: string): void;
|
|
18
|
+
warning(msg: string): void;
|
|
19
|
+
success(msg: string): void;
|
|
20
|
+
header(msg: string): void;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Create a lightweight launcher logger that writes to stderr
|
|
24
|
+
* (so it doesn't interfere with MCP JSON-RPC on stdout).
|
|
25
|
+
*/
|
|
26
|
+
export declare function createLauncherLogger(): LauncherLogger;
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=_launcher-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_launcher-utils.d.ts","sourceRoot":"","sources":["../../src/servers/_launcher-utils.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,eAAO,MAAM,QAAQ;;;;;CAKX,CAAC;AAEX,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,QAAQ,CAAC,CAAC,MAAM,OAAO,QAAQ,CAAC,CAAC;AAMhE,UAAU,cAAc;IACtB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,cAAc,CAuBrD"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Launcher Utilities
|
|
3
|
+
*
|
|
4
|
+
* Self-contained logger and exit codes for MCP server launcher scripts.
|
|
5
|
+
* Replaces the @revealui/scripts dependency so the MCP package has no
|
|
6
|
+
* cross-package imports beyond its own declared dependencies.
|
|
7
|
+
*/
|
|
8
|
+
// =============================================================================
|
|
9
|
+
// Exit Codes
|
|
10
|
+
// =============================================================================
|
|
11
|
+
export const ExitCode = {
|
|
12
|
+
SUCCESS: 0,
|
|
13
|
+
GENERAL_ERROR: 1,
|
|
14
|
+
CONFIG_ERROR: 2,
|
|
15
|
+
EXECUTION_ERROR: 3,
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Create a lightweight launcher logger that writes to stderr
|
|
19
|
+
* (so it doesn't interfere with MCP JSON-RPC on stdout).
|
|
20
|
+
*/
|
|
21
|
+
export function createLauncherLogger() {
|
|
22
|
+
return {
|
|
23
|
+
info(msg) {
|
|
24
|
+
// biome-ignore lint/suspicious/noConsole: MCP launcher logger intentionally writes to stderr
|
|
25
|
+
console.error(`\x1b[36m[mcp]\x1b[0m ${msg}`); // console-allowed
|
|
26
|
+
},
|
|
27
|
+
error(msg) {
|
|
28
|
+
// biome-ignore lint/suspicious/noConsole: MCP launcher logger intentionally writes to stderr
|
|
29
|
+
console.error(`\x1b[31m[mcp] ERROR:\x1b[0m ${msg}`); // console-allowed
|
|
30
|
+
},
|
|
31
|
+
warning(msg) {
|
|
32
|
+
// biome-ignore lint/suspicious/noConsole: MCP launcher logger intentionally writes to stderr
|
|
33
|
+
console.error(`\x1b[33m[mcp] WARN:\x1b[0m ${msg}`); // console-allowed
|
|
34
|
+
},
|
|
35
|
+
success(msg) {
|
|
36
|
+
// biome-ignore lint/suspicious/noConsole: MCP launcher logger intentionally writes to stderr
|
|
37
|
+
console.error(`\x1b[32m[mcp]\x1b[0m ${msg}`); // console-allowed
|
|
38
|
+
},
|
|
39
|
+
header(msg) {
|
|
40
|
+
// biome-ignore lint/suspicious/noConsole: MCP launcher logger intentionally writes to stderr
|
|
41
|
+
console.error(`\n\x1b[1m\x1b[36m${msg}\x1b[0m\n`); // console-allowed
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=_launcher-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_launcher-utils.js","sourceRoot":"","sources":["../../src/servers/_launcher-utils.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,gFAAgF;AAChF,aAAa;AACb,gFAAgF;AAEhF,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,OAAO,EAAE,CAAC;IACV,aAAa,EAAE,CAAC;IAChB,YAAY,EAAE,CAAC;IACf,eAAe,EAAE,CAAC;CACV,CAAC;AAgBX;;;GAGG;AACH,MAAM,UAAU,oBAAoB;IAClC,OAAO;QACL,IAAI,CAAC,GAAW;YACd,6FAA6F;YAC7F,OAAO,CAAC,KAAK,CAAC,wBAAwB,GAAG,EAAE,CAAC,CAAC,CAAC,kBAAkB;QAClE,CAAC;QACD,KAAK,CAAC,GAAW;YACf,6FAA6F;YAC7F,OAAO,CAAC,KAAK,CAAC,+BAA+B,GAAG,EAAE,CAAC,CAAC,CAAC,kBAAkB;QACzE,CAAC;QACD,OAAO,CAAC,GAAW;YACjB,6FAA6F;YAC7F,OAAO,CAAC,KAAK,CAAC,8BAA8B,GAAG,EAAE,CAAC,CAAC,CAAC,kBAAkB;QACxE,CAAC;QACD,OAAO,CAAC,GAAW;YACjB,6FAA6F;YAC7F,OAAO,CAAC,KAAK,CAAC,wBAAwB,GAAG,EAAE,CAAC,CAAC,CAAC,kBAAkB;QAClE,CAAC;QACD,MAAM,CAAC,GAAW;YAChB,6FAA6F;YAC7F,OAAO,CAAC,KAAK,CAAC,oBAAoB,GAAG,WAAW,CAAC,CAAC,CAAC,kBAAkB;QACvE,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -50,21 +50,37 @@ export interface MCPResponse {
|
|
|
50
50
|
idempotencyKey?: string;
|
|
51
51
|
};
|
|
52
52
|
}
|
|
53
|
+
/**
|
|
54
|
+
* Persistent backend for idempotency cache.
|
|
55
|
+
* Implementations handle their own TTL expiration for stored entries.
|
|
56
|
+
*/
|
|
57
|
+
export interface IdempotencyStore {
|
|
58
|
+
get(key: string): Promise<{
|
|
59
|
+
response: MCPResponse;
|
|
60
|
+
expiresAt: number;
|
|
61
|
+
} | null>;
|
|
62
|
+
set(key: string, response: MCPResponse, ttlMs: number): Promise<void>;
|
|
63
|
+
delete(key: string): Promise<void>;
|
|
64
|
+
}
|
|
53
65
|
/**
|
|
54
66
|
* In-memory idempotency cache for preventing duplicate operations.
|
|
55
|
-
* Each adapter instance has its own cache.
|
|
67
|
+
* Each adapter instance has its own cache. Optionally backed by a
|
|
68
|
+
* persistent {@link IdempotencyStore} for cross-process durability.
|
|
56
69
|
*/
|
|
57
70
|
declare class IdempotencyCache {
|
|
58
71
|
private cache;
|
|
72
|
+
private store;
|
|
59
73
|
private cleanupInterval;
|
|
60
74
|
private readonly DEFAULT_TTL;
|
|
61
|
-
constructor();
|
|
75
|
+
constructor(store?: IdempotencyStore);
|
|
62
76
|
/**
|
|
63
|
-
* Get a cached response by idempotency key
|
|
77
|
+
* Get a cached response by idempotency key.
|
|
78
|
+
* Checks memory first, then falls through to the persistent store.
|
|
64
79
|
*/
|
|
65
|
-
get(key: string): MCPResponse | null
|
|
80
|
+
get(key: string): Promise<MCPResponse | null>;
|
|
66
81
|
/**
|
|
67
|
-
* Store a response with idempotency key
|
|
82
|
+
* Store a response with idempotency key.
|
|
83
|
+
* Writes to both memory and the persistent store (if configured).
|
|
68
84
|
*/
|
|
69
85
|
set(key: string, response: MCPResponse, ttl?: number): void;
|
|
70
86
|
/**
|
|
@@ -72,7 +88,7 @@ declare class IdempotencyCache {
|
|
|
72
88
|
*/
|
|
73
89
|
has(key: string): boolean;
|
|
74
90
|
/**
|
|
75
|
-
* Remove expired entries
|
|
91
|
+
* Remove expired entries (memory only — store manages its own TTL)
|
|
76
92
|
*/
|
|
77
93
|
private cleanup;
|
|
78
94
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/servers/adapter.ts"],"names":[],"mappings":";AAEA;;;;;;;;;GASG;AAMH,oBAAY,YAAY;IACtB,gBAAgB,qBAAqB;IACrC,aAAa,kBAAkB;IAC/B,aAAa,kBAAkB;IAC/B,YAAY,iBAAiB;CAC9B;AAED,qBAAa,QAAS,SAAQ,KAAK;IACjC,IAAI,EAAE,YAAY,
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/servers/adapter.ts"],"names":[],"mappings":"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"}
|