firecrawl-mcp 3.29.1 → 3.30.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 +9 -48
- package/dist/index.js +57 -227
- package/dist/server.d.ts +28 -6
- package/dist/server.js +50 -223
- package/package.json +1 -1
- package/dist/agent-hints.js +0 -46
package/dist/server.js
CHANGED
|
@@ -80,7 +80,7 @@ var alexandriaSessionFeedbackSchema = z.strictObject({
|
|
|
80
80
|
// src/server.ts
|
|
81
81
|
import FirecrawlApp from "firecrawl";
|
|
82
82
|
|
|
83
|
-
// node_modules/.pnpm/fastmcp@4.3.2_patch_hash=
|
|
83
|
+
// node_modules/.pnpm/fastmcp@4.3.2_patch_hash=37f9a424ae5b0b6202b2b16109a1ea88b69cdcda5407f13eda6654a56489ad70/node_modules/fastmcp/dist/chunk-LWU5CQGW.js
|
|
84
84
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
85
85
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
86
86
|
import {
|
|
@@ -884,6 +884,7 @@ ${error2 instanceof Error ? error2.stack : JSON.stringify(error2)}`
|
|
|
884
884
|
// Top-level Tool.title (MCP 2025-06-18). Clients such as Codex index this
|
|
885
885
|
// for tool search and do not read annotations.title.
|
|
886
886
|
...tool.annotations?.title && { title: tool.annotations.title },
|
|
887
|
+
...tool.icons && { icons: tool.icons },
|
|
887
888
|
description: tool.description,
|
|
888
889
|
inputSchema: tool.parameters ? strictJsonSchema(await toJsonSchema(tool.parameters)) : {
|
|
889
890
|
additionalProperties: false,
|
|
@@ -2059,7 +2060,7 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
2059
2060
|
}
|
|
2060
2061
|
};
|
|
2061
2062
|
|
|
2062
|
-
// node_modules/.pnpm/fastmcp@4.3.2_patch_hash=
|
|
2063
|
+
// node_modules/.pnpm/fastmcp@4.3.2_patch_hash=37f9a424ae5b0b6202b2b16109a1ea88b69cdcda5407f13eda6654a56489ad70/node_modules/fastmcp/dist/chunk-OJG4XYXA.js
|
|
2063
2064
|
import { z as z3 } from "zod";
|
|
2064
2065
|
import { createHmac as createHmac2, pbkdf2, randomBytes } from "crypto";
|
|
2065
2066
|
import { promisify } from "util";
|
|
@@ -2072,45 +2073,6 @@ import { randomUUID as randomUUID2 } from "crypto";
|
|
|
2072
2073
|
import path from "path";
|
|
2073
2074
|
import { z as z12 } from "zod";
|
|
2074
2075
|
|
|
2075
|
-
// src/agent-hints.ts
|
|
2076
|
-
var AGENT_HINTS_HEADERS = { "X-Firecrawl-Agent-Hints": "true" };
|
|
2077
|
-
function readAgentHints(value) {
|
|
2078
|
-
if (!value || typeof value !== "object") return void 0;
|
|
2079
|
-
const hints = value.agent_hints;
|
|
2080
|
-
return Array.isArray(hints) && hints.every((hint) => typeof hint === "string") ? hints : void 0;
|
|
2081
|
-
}
|
|
2082
|
-
function preserveAgentHints(data, envelope) {
|
|
2083
|
-
const hints = readAgentHints(envelope);
|
|
2084
|
-
if (!hints) return data;
|
|
2085
|
-
return data && typeof data === "object" && !Array.isArray(data) ? { ...data, agent_hints: hints } : { data, agent_hints: hints };
|
|
2086
|
-
}
|
|
2087
|
-
function agentHintsText(hints) {
|
|
2088
|
-
return `Firecrawl API agent_hints (response guidance, separate from page content):
|
|
2089
|
-
${JSON.stringify(hints, null, 2)}`;
|
|
2090
|
-
}
|
|
2091
|
-
function withAgentHints(result, response, separateText = false) {
|
|
2092
|
-
const hints = readAgentHints(response);
|
|
2093
|
-
if (!hints) return result;
|
|
2094
|
-
return {
|
|
2095
|
-
...result,
|
|
2096
|
-
content: separateText && hints.length ? [...result.content, { type: "text", text: agentHintsText(hints) }] : result.content,
|
|
2097
|
-
structuredContent: { ...result.structuredContent, agent_hints: hints }
|
|
2098
|
-
};
|
|
2099
|
-
}
|
|
2100
|
-
function readErrorAgentHints(error2) {
|
|
2101
|
-
const hints = readAgentHints(error2);
|
|
2102
|
-
if (hints) return hints;
|
|
2103
|
-
if (!error2 || typeof error2 !== "object") return void 0;
|
|
2104
|
-
const extras = error2.extras;
|
|
2105
|
-
const extrasHints = readAgentHints(extras);
|
|
2106
|
-
if (extrasHints) return extrasHints;
|
|
2107
|
-
const details = error2.details;
|
|
2108
|
-
const detailsHints = readAgentHints(details);
|
|
2109
|
-
if (detailsHints) return detailsHints;
|
|
2110
|
-
const response = error2.response;
|
|
2111
|
-
return readAgentHints(response?.data);
|
|
2112
|
-
}
|
|
2113
|
-
|
|
2114
2076
|
// src/tool-output.ts
|
|
2115
2077
|
import { z as z4 } from "zod";
|
|
2116
2078
|
function isRecord(value) {
|
|
@@ -2139,9 +2101,6 @@ var unknown = (description) => z4.unknown().optional().describe(description);
|
|
|
2139
2101
|
var success = bool("Whether the API call succeeded.");
|
|
2140
2102
|
var error = unknown("Error message or error object when the call did not succeed.");
|
|
2141
2103
|
var warning = str("Non-fatal warning about the result.");
|
|
2142
|
-
var agentHints = {
|
|
2143
|
-
agent_hints: z4.array(z4.string()).optional().describe("Optional response guidance from the Firecrawl API.")
|
|
2144
|
-
};
|
|
2145
2104
|
var alexandriaEnvelope = {
|
|
2146
2105
|
requestId: str("Identifier of this Alexandria execution."),
|
|
2147
2106
|
scrape_id: str("Identifier of the underlying scrape."),
|
|
@@ -2159,7 +2118,6 @@ var alexandriaEnvelope = {
|
|
|
2159
2118
|
feedbackTool: unknown("Pointer to the feedback tool for reporting how this result served the task.")
|
|
2160
2119
|
};
|
|
2161
2120
|
var scrapeOutputSchema = z4.object({
|
|
2162
|
-
...agentHints,
|
|
2163
2121
|
// URL mode: the scraped document, with the formats that were requested.
|
|
2164
2122
|
markdown: str("Page content as markdown."),
|
|
2165
2123
|
html: str("Processed HTML of the page."),
|
|
@@ -2191,7 +2149,6 @@ var scrapeOutputSchema = z4.object({
|
|
|
2191
2149
|
...alexandriaEnvelope
|
|
2192
2150
|
}).describe("A scraped document, or the Alexandria execution envelope when `alexandria` was passed.");
|
|
2193
2151
|
var mapOutputSchema = z4.object({
|
|
2194
|
-
...agentHints,
|
|
2195
2152
|
links: unknown("URLs discovered under the website."),
|
|
2196
2153
|
success,
|
|
2197
2154
|
error,
|
|
@@ -2199,7 +2156,6 @@ var mapOutputSchema = z4.object({
|
|
|
2199
2156
|
id: str("Identifier of the map run, for optional map feedback.")
|
|
2200
2157
|
}).describe("URLs indexed under the requested website.");
|
|
2201
2158
|
var searchOutputSchema = z4.object({
|
|
2202
|
-
...agentHints,
|
|
2203
2159
|
success,
|
|
2204
2160
|
data: unknown("Ranked results grouped by source, such as `web`, `news`, `images`, and `alexandria`."),
|
|
2205
2161
|
error,
|
|
@@ -2211,14 +2167,12 @@ var searchOutputSchema = z4.object({
|
|
|
2211
2167
|
feedbackTool: unknown("Pointer to the feedback tool for this search.")
|
|
2212
2168
|
}).describe("Ranked search results grouped by source.");
|
|
2213
2169
|
var findToolsOutputSchema = z4.object({
|
|
2214
|
-
...agentHints,
|
|
2215
2170
|
success,
|
|
2216
2171
|
data: unknown("Discovery page in `data.alexandria[0].data`, with `level`, `items`, `total`, and an optional `nextTool`."),
|
|
2217
2172
|
error,
|
|
2218
2173
|
...alexandriaEnvelope
|
|
2219
2174
|
}).describe("One page of the Alexandria catalogue: categories, providers, tools, or one contract.");
|
|
2220
2175
|
var feedbackOutputSchema = z4.object({
|
|
2221
|
-
...agentHints,
|
|
2222
2176
|
success,
|
|
2223
2177
|
error,
|
|
2224
2178
|
status: num("HTTP status when the submission was rejected."),
|
|
@@ -2237,7 +2191,6 @@ var feedbackOutputSchema = z4.object({
|
|
|
2237
2191
|
raw: str("Response body when it was not JSON.")
|
|
2238
2192
|
}).describe("Result of submitting feedback.");
|
|
2239
2193
|
var crawlOutputSchema = z4.object({
|
|
2240
|
-
...agentHints,
|
|
2241
2194
|
success,
|
|
2242
2195
|
error,
|
|
2243
2196
|
warning,
|
|
@@ -2252,7 +2205,6 @@ var crawlOutputSchema = z4.object({
|
|
|
2252
2205
|
data: unknown("Scraped documents collected by the crawl.")
|
|
2253
2206
|
}).describe("Crawl job state and the documents collected so far.");
|
|
2254
2207
|
var agentOutputSchema = z4.object({
|
|
2255
|
-
...agentHints,
|
|
2256
2208
|
success,
|
|
2257
2209
|
error,
|
|
2258
2210
|
id: str("Agent job identifier, for `firecrawl_agent_status`."),
|
|
@@ -2261,7 +2213,6 @@ var agentOutputSchema = z4.object({
|
|
|
2261
2213
|
threadTurn: num("Turn number of this job within its thread.")
|
|
2262
2214
|
}).describe("The queued research job. The result is read with `firecrawl_agent_status`.");
|
|
2263
2215
|
var agentStatusOutputSchema = z4.object({
|
|
2264
|
-
...agentHints,
|
|
2265
2216
|
success,
|
|
2266
2217
|
error,
|
|
2267
2218
|
id: str("Agent job identifier."),
|
|
@@ -2289,7 +2240,6 @@ var agentStatusOutputSchema = z4.object({
|
|
|
2289
2240
|
)
|
|
2290
2241
|
}).describe("Progress or final result of a research agent job.");
|
|
2291
2242
|
var interactOutputSchema = z4.object({
|
|
2292
|
-
...agentHints,
|
|
2293
2243
|
success,
|
|
2294
2244
|
error: unknown("Why the interaction or the session could not run."),
|
|
2295
2245
|
url: str("The URL the session was opened from, when opening failed."),
|
|
@@ -2304,14 +2254,12 @@ var interactOutputSchema = z4.object({
|
|
|
2304
2254
|
liveUrl: str("URL for viewing the live session.")
|
|
2305
2255
|
}).describe("Result of a browser interaction, with the session identifier to continue or stop it.");
|
|
2306
2256
|
var interactStopOutputSchema = z4.object({
|
|
2307
|
-
...agentHints,
|
|
2308
2257
|
success,
|
|
2309
2258
|
error,
|
|
2310
2259
|
message: str("Confirmation that the session was stopped."),
|
|
2311
2260
|
scrapeId: str("Session that was stopped.")
|
|
2312
2261
|
}).describe("Confirmation that the interact session was stopped.");
|
|
2313
2262
|
var parseOutputSchema = z4.object({
|
|
2314
|
-
...agentHints,
|
|
2315
2263
|
success,
|
|
2316
2264
|
error,
|
|
2317
2265
|
warning,
|
|
@@ -2339,39 +2287,33 @@ var deprecatedToolOutputSchema = z4.object({
|
|
|
2339
2287
|
docs_url: str("Documentation for the replacement.")
|
|
2340
2288
|
}).describe("A pointer to the replacement tool. This entry point is deprecated and always errors.");
|
|
2341
2289
|
var monitorOutputSchema = z4.object({
|
|
2342
|
-
...agentHints,
|
|
2343
2290
|
success,
|
|
2344
2291
|
error,
|
|
2345
2292
|
data: unknown("The monitor record: configuration, schedule, targets, and current state.")
|
|
2346
2293
|
}).describe("One monitor record.");
|
|
2347
2294
|
var monitorListOutputSchema = z4.object({
|
|
2348
|
-
...agentHints,
|
|
2349
2295
|
success,
|
|
2350
2296
|
error,
|
|
2351
2297
|
data: unknown("One page of monitor records."),
|
|
2352
2298
|
pagination: unknown("Pagination metadata for the listing.")
|
|
2353
2299
|
}).describe("One page of monitors for the authenticated account.");
|
|
2354
2300
|
var monitorDeleteOutputSchema = z4.object({
|
|
2355
|
-
...agentHints,
|
|
2356
2301
|
success,
|
|
2357
2302
|
error,
|
|
2358
2303
|
data: unknown("Deletion details, when the API returns any.")
|
|
2359
2304
|
}).describe("Deletion status for the monitor.");
|
|
2360
2305
|
var monitorRunOutputSchema = z4.object({
|
|
2361
|
-
...agentHints,
|
|
2362
2306
|
success,
|
|
2363
2307
|
error,
|
|
2364
2308
|
data: unknown("The queued check.")
|
|
2365
2309
|
}).describe("The check queued outside the monitor schedule.");
|
|
2366
2310
|
var monitorChecksOutputSchema = z4.object({
|
|
2367
|
-
...agentHints,
|
|
2368
2311
|
success,
|
|
2369
2312
|
error,
|
|
2370
2313
|
data: unknown("One page of check summaries."),
|
|
2371
2314
|
pagination: unknown("Pagination metadata for the listing.")
|
|
2372
2315
|
}).describe("One page of historical checks for the monitor.");
|
|
2373
2316
|
var monitorCheckOutputSchema = z4.object({
|
|
2374
|
-
...agentHints,
|
|
2375
2317
|
success,
|
|
2376
2318
|
error,
|
|
2377
2319
|
data: unknown("The check and its page-level results: each page reports `same`, `new`, `changed`, `removed`, or `error`, with diffs and any goal judgment."),
|
|
@@ -2390,25 +2332,20 @@ var paperSchema = z4.looseObject({
|
|
|
2390
2332
|
updateDate: str("Date the paper was last updated.")
|
|
2391
2333
|
});
|
|
2392
2334
|
var researchSearchOutputSchema = z4.object({
|
|
2393
|
-
...agentHints,
|
|
2394
2335
|
results: z4.array(paperSchema).describe("Ranked papers, in the order the text block lists them.")
|
|
2395
2336
|
}).describe("Ranked papers with canonical IDs, titles, authors, and abstracts.");
|
|
2396
2337
|
var researchPaperOutputSchema = z4.object({
|
|
2397
|
-
...agentHints,
|
|
2398
2338
|
paper: paperSchema.optional().describe("Canonical metadata for the requested paper, absent when it was not found.")
|
|
2399
2339
|
}).describe("Canonical metadata for one paper.");
|
|
2400
2340
|
var researchRelatedOutputSchema = z4.object({
|
|
2401
|
-
...agentHints,
|
|
2402
2341
|
results: z4.array(paperSchema).describe("Ranked citation-graph candidates."),
|
|
2403
2342
|
poolSize: z4.number().describe("Number of candidates evaluated before ranking."),
|
|
2404
2343
|
note: str("Note about how the candidates were produced.")
|
|
2405
2344
|
}).describe("Ranked citation-graph candidates and the size of the evaluated pool.");
|
|
2406
2345
|
var researchReadOutputSchema = z4.object({
|
|
2407
|
-
...agentHints,
|
|
2408
2346
|
passages: z4.array(z4.looseObject({ text: str("Passage text.") })).describe("In-body passages relevant to the question; empty when no full text is indexed.")
|
|
2409
2347
|
}).describe("Full-text passages from one paper.");
|
|
2410
2348
|
var developerSearchOutputSchema = z4.object({
|
|
2411
|
-
...agentHints,
|
|
2412
2349
|
results: z4.array(
|
|
2413
2350
|
z4.looseObject({
|
|
2414
2351
|
id: str("Stable result id, such as `issue:owner/repo#123` or `doc:<hash>`; its prefix gives the source type."),
|
|
@@ -2419,7 +2356,6 @@ var developerSearchOutputSchema = z4.object({
|
|
|
2419
2356
|
).describe("Ranked results, in the order the text block lists them.")
|
|
2420
2357
|
}).describe("Ranked developer-index results with their matched passages.");
|
|
2421
2358
|
var govSearchOutputSchema = z4.object({
|
|
2422
|
-
...agentHints,
|
|
2423
2359
|
results: z4.array(
|
|
2424
2360
|
z4.looseObject({
|
|
2425
2361
|
url: str("Source URL."),
|
|
@@ -2668,7 +2604,7 @@ Returns ranked results with an ID, source type, URL, title, and the matched pass
|
|
|
2668
2604
|
const client = getClient(session);
|
|
2669
2605
|
const res = await client.http.get(`${BASE}?${params.toString()}`, originHeaders(requestOrigin(mcpClient, session)));
|
|
2670
2606
|
const results = res.data?.results ?? [];
|
|
2671
|
-
return
|
|
2607
|
+
return withStructured(fmtDeveloper(results), { results });
|
|
2672
2608
|
}
|
|
2673
2609
|
});
|
|
2674
2610
|
}
|
|
@@ -2717,11 +2653,7 @@ Returns ranked results with a position, title, URL, and matched snippet. Results
|
|
|
2717
2653
|
originHeaders(requestOrigin(mcpClient, session))
|
|
2718
2654
|
);
|
|
2719
2655
|
const results = res.data?.data?.web ?? [];
|
|
2720
|
-
return
|
|
2721
|
-
withStructured(fmtGov(results), { results }),
|
|
2722
|
-
res.data,
|
|
2723
|
-
true
|
|
2724
|
-
);
|
|
2656
|
+
return withStructured(fmtGov(results), { results });
|
|
2725
2657
|
}
|
|
2726
2658
|
});
|
|
2727
2659
|
}
|
|
@@ -2732,12 +2664,10 @@ import { z as z8 } from "zod";
|
|
|
2732
2664
|
// src/core-http-error.ts
|
|
2733
2665
|
var CoreHttpError = class extends Error {
|
|
2734
2666
|
status;
|
|
2735
|
-
|
|
2736
|
-
constructor(message, status, agentHints2) {
|
|
2667
|
+
constructor(message, status) {
|
|
2737
2668
|
super(message);
|
|
2738
2669
|
this.name = "CoreHttpError";
|
|
2739
2670
|
this.status = status;
|
|
2740
|
-
if (agentHints2 !== void 0) this.agent_hints = agentHints2;
|
|
2741
2671
|
}
|
|
2742
2672
|
};
|
|
2743
2673
|
|
|
@@ -2760,7 +2690,6 @@ async function monitorRequest(api, session, origin, path2, init = {}) {
|
|
|
2760
2690
|
}
|
|
2761
2691
|
const headers = {
|
|
2762
2692
|
...originHeaders(origin),
|
|
2763
|
-
...AGENT_HINTS_HEADERS,
|
|
2764
2693
|
...extraHeaders
|
|
2765
2694
|
};
|
|
2766
2695
|
if (apiKey) headers.Authorization = `Bearer ${apiKey}`;
|
|
@@ -2773,13 +2702,10 @@ async function monitorRequest(api, session, origin, path2, init = {}) {
|
|
|
2773
2702
|
const payload = await response.json().catch(() => ({}));
|
|
2774
2703
|
if (!response.ok || payload?.success === false) {
|
|
2775
2704
|
const message = payload?.error || `HTTP ${response.status}: ${response.statusText || "Request failed"}`;
|
|
2776
|
-
throw new CoreHttpError(message, response.status
|
|
2705
|
+
throw new CoreHttpError(message, response.status);
|
|
2777
2706
|
}
|
|
2778
2707
|
return payload;
|
|
2779
2708
|
}
|
|
2780
|
-
function monitorResult(data) {
|
|
2781
|
-
return withAgentHints(structuredText(data), data);
|
|
2782
|
-
}
|
|
2783
2709
|
var pageStatusSchema = z8.enum(["same", "new", "changed", "removed", "error"]);
|
|
2784
2710
|
var checkStatusSchema = z8.enum([
|
|
2785
2711
|
"queued",
|
|
@@ -2905,7 +2831,7 @@ In the simple form, a \`goal\` is required. If \`queries\` contains one or more
|
|
|
2905
2831
|
body
|
|
2906
2832
|
}
|
|
2907
2833
|
);
|
|
2908
|
-
return
|
|
2834
|
+
return structuredText(res);
|
|
2909
2835
|
}
|
|
2910
2836
|
});
|
|
2911
2837
|
server.addTool({
|
|
@@ -2938,7 +2864,7 @@ List monitors for the authenticated account with optional pagination controls. R
|
|
|
2938
2864
|
query: { limit, offset }
|
|
2939
2865
|
}
|
|
2940
2866
|
);
|
|
2941
|
-
return
|
|
2867
|
+
return structuredText(res);
|
|
2942
2868
|
}
|
|
2943
2869
|
});
|
|
2944
2870
|
server.addTool({
|
|
@@ -2965,7 +2891,7 @@ Retrieve one monitor by ID, including its configuration and current state. This
|
|
|
2965
2891
|
requestOrigin(mcpClient, session),
|
|
2966
2892
|
`/monitor/${encodeURIComponent(id)}`
|
|
2967
2893
|
);
|
|
2968
|
-
return
|
|
2894
|
+
return structuredText(res);
|
|
2969
2895
|
}
|
|
2970
2896
|
});
|
|
2971
2897
|
server.addTool({
|
|
@@ -2998,7 +2924,7 @@ Returns the updated monitor.
|
|
|
2998
2924
|
`/monitor/${encodeURIComponent(id)}`,
|
|
2999
2925
|
{ method: "PATCH", body }
|
|
3000
2926
|
);
|
|
3001
|
-
return
|
|
2927
|
+
return structuredText(res);
|
|
3002
2928
|
}
|
|
3003
2929
|
});
|
|
3004
2930
|
server.addTool({
|
|
@@ -3027,7 +2953,7 @@ Permanently delete a monitor by ID and stop its future schedule. This operation
|
|
|
3027
2953
|
`/monitor/${encodeURIComponent(id)}`,
|
|
3028
2954
|
{ method: "DELETE" }
|
|
3029
2955
|
);
|
|
3030
|
-
return
|
|
2956
|
+
return structuredText(res);
|
|
3031
2957
|
}
|
|
3032
2958
|
});
|
|
3033
2959
|
server.addTool({
|
|
@@ -3055,7 +2981,7 @@ Queue an immediate check for a monitor outside its normal schedule. This starts
|
|
|
3055
2981
|
`/monitor/${encodeURIComponent(id)}/run`,
|
|
3056
2982
|
{ method: "POST" }
|
|
3057
2983
|
);
|
|
3058
|
-
return
|
|
2984
|
+
return structuredText(res);
|
|
3059
2985
|
}
|
|
3060
2986
|
});
|
|
3061
2987
|
server.addTool({
|
|
@@ -3088,7 +3014,7 @@ List historical checks for a monitor, optionally filtered by status and bounded
|
|
|
3088
3014
|
`/monitor/${encodeURIComponent(id)}/checks`,
|
|
3089
3015
|
{ query: { limit, offset, status } }
|
|
3090
3016
|
);
|
|
3091
|
-
return
|
|
3017
|
+
return structuredText(res);
|
|
3092
3018
|
}
|
|
3093
3019
|
});
|
|
3094
3020
|
server.addTool({
|
|
@@ -3124,7 +3050,7 @@ Markdown tracking returns a unified text diff, JSON tracking returns field paths
|
|
|
3124
3050
|
`/monitor/${encodeURIComponent(id)}/checks/${encodeURIComponent(checkId)}`,
|
|
3125
3051
|
{ query: { limit, skip, status: pageStatus } }
|
|
3126
3052
|
);
|
|
3127
|
-
return
|
|
3053
|
+
return structuredText(res);
|
|
3128
3054
|
}
|
|
3129
3055
|
});
|
|
3130
3056
|
}
|
|
@@ -3132,9 +3058,6 @@ Markdown tracking returns a unified text diff, JSON tracking returns field paths
|
|
|
3132
3058
|
// src/research.ts
|
|
3133
3059
|
import { z as z9 } from "zod";
|
|
3134
3060
|
var BASE3 = "/v2/search/research";
|
|
3135
|
-
function researchHeaders(origin) {
|
|
3136
|
-
return { ...originHeaders(origin), ...AGENT_HINTS_HEADERS };
|
|
3137
|
-
}
|
|
3138
3061
|
function appendParam(params, key, value) {
|
|
3139
3062
|
if (value == null) return;
|
|
3140
3063
|
if (Array.isArray(value)) {
|
|
@@ -3279,10 +3202,10 @@ Returns ranked papers with canonical IDs, titles, authors, and abstracts.
|
|
|
3279
3202
|
const client = getClient(session);
|
|
3280
3203
|
const res = await client.http.get(
|
|
3281
3204
|
withQuery(`${BASE3}/papers`, params),
|
|
3282
|
-
|
|
3205
|
+
originHeaders(requestOrigin(mcpClient, session))
|
|
3283
3206
|
);
|
|
3284
3207
|
const results = res.data?.results ?? [];
|
|
3285
|
-
return
|
|
3208
|
+
return withStructured(fmtHits(results), { results });
|
|
3286
3209
|
}
|
|
3287
3210
|
});
|
|
3288
3211
|
server.addTool({
|
|
@@ -3310,13 +3233,13 @@ Retrieve canonical metadata for one paper ID, such as an arXiv, PMC, PMID, or DO
|
|
|
3310
3233
|
const client = getClient(session);
|
|
3311
3234
|
const res = await client.http.get(
|
|
3312
3235
|
`${BASE3}/papers/${encodeURIComponent(paperId)}`,
|
|
3313
|
-
|
|
3236
|
+
originHeaders(requestOrigin(mcpClient, session))
|
|
3314
3237
|
);
|
|
3315
3238
|
const paper = res.data?.paper;
|
|
3316
|
-
return
|
|
3239
|
+
return withStructured(
|
|
3317
3240
|
fmtPaperMetadata(paper),
|
|
3318
3241
|
paper ? { paper } : {}
|
|
3319
|
-
)
|
|
3242
|
+
);
|
|
3320
3243
|
}
|
|
3321
3244
|
});
|
|
3322
3245
|
server.addTool({
|
|
@@ -3358,17 +3281,17 @@ Returns ranked candidates and the evaluated pool size.
|
|
|
3358
3281
|
`${BASE3}/papers/${encodeURIComponent(primary)}/similar`,
|
|
3359
3282
|
params
|
|
3360
3283
|
),
|
|
3361
|
-
|
|
3284
|
+
originHeaders(requestOrigin(mcpClient, session))
|
|
3362
3285
|
);
|
|
3363
3286
|
const results = res.data?.results ?? [];
|
|
3364
3287
|
const poolSize = res.data?.poolSize ?? 0;
|
|
3365
3288
|
const note = res.data?.note ? `
|
|
3366
3289
|
note: ${res.data.note}` : "";
|
|
3367
|
-
return
|
|
3290
|
+
return withStructured(
|
|
3368
3291
|
`${fmtHits(results)}
|
|
3369
3292
|
(poolSize=${poolSize})${note}`,
|
|
3370
3293
|
{ results, poolSize, ...res.data?.note ? { note: res.data.note } : {} }
|
|
3371
|
-
)
|
|
3294
|
+
);
|
|
3372
3295
|
}
|
|
3373
3296
|
});
|
|
3374
3297
|
server.addTool({
|
|
@@ -3403,13 +3326,13 @@ Returns matching passages or a notice when full text is unavailable.
|
|
|
3403
3326
|
const client = getClient(session);
|
|
3404
3327
|
const res = await client.http.get(
|
|
3405
3328
|
withQuery(`${BASE3}/papers/${encodeURIComponent(paperId)}`, params),
|
|
3406
|
-
|
|
3329
|
+
originHeaders(requestOrigin(mcpClient, session))
|
|
3407
3330
|
);
|
|
3408
3331
|
const passages = res.data?.passages ?? [];
|
|
3409
|
-
return
|
|
3332
|
+
return withStructured(
|
|
3410
3333
|
passages.length ? passages.map((p) => p.text).join("\n---\n") : "(no full-text passages available for this paper)",
|
|
3411
3334
|
{ passages }
|
|
3412
|
-
)
|
|
3335
|
+
);
|
|
3413
3336
|
}
|
|
3414
3337
|
});
|
|
3415
3338
|
server.addTool({
|
|
@@ -3635,20 +3558,6 @@ async function runWithCredentialRecovery(run, requestId, session) {
|
|
|
3635
3558
|
return await run();
|
|
3636
3559
|
} catch (error2) {
|
|
3637
3560
|
if (session?.authType !== "api-key" || !isCoreCredentialRejection(error2, session)) {
|
|
3638
|
-
const hints = readErrorAgentHints(error2);
|
|
3639
|
-
if (hints) {
|
|
3640
|
-
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
3641
|
-
throw new UserError(
|
|
3642
|
-
hints.length ? `${message}
|
|
3643
|
-
|
|
3644
|
-
${agentHintsText(hints)}` : message,
|
|
3645
|
-
{
|
|
3646
|
-
...error2 instanceof UserError ? error2.extras : {},
|
|
3647
|
-
error: message,
|
|
3648
|
-
agent_hints: hints
|
|
3649
|
-
}
|
|
3650
|
-
);
|
|
3651
|
-
}
|
|
3652
3561
|
throw error2;
|
|
3653
3562
|
}
|
|
3654
3563
|
const payload = recoveryPayload("CREDENTIAL_INVALID", requestId);
|
|
@@ -3707,8 +3616,6 @@ var searchDomainSchema = z11.string().trim().toLowerCase().min(1).max(253).regex
|
|
|
3707
3616
|
var searchToolBaseFields = {
|
|
3708
3617
|
toolDetail: z11.enum(["compact", "summary", "full"]).optional().describe("Compact by default. Compact returns only provider, capability and description; full includes contracts. Inspect selected compact tools with firecrawl_find_tools providers and capabilities."),
|
|
3709
3618
|
query: z11.string().min(1).describe("Query for web and semantic tool discovery. Operators include quoted phrases, `-term`, `site:host`, `inurl:term`, `intitle:term`, and `related:host`; the set is non-exhaustive. Catalogue browsing is available through firecrawl_find_tools."),
|
|
3710
|
-
objective: z11.string().trim().min(1).max(5e3).optional().describe("Optional broader goal for this search, if known. Avoid sensitive information."),
|
|
3711
|
-
clientModel: z11.string().trim().min(1).max(128).optional().describe("Optional model identifier, if known."),
|
|
3712
3619
|
domainTools: z11.boolean().optional().describe(
|
|
3713
3620
|
"Include domain-matched tools for result URLs. Defaults to true when Alexandria is combined with web, news or images; semantic-only search leaves domain matching off."
|
|
3714
3621
|
),
|
|
@@ -3774,7 +3681,7 @@ function termsRequiredAction(body) {
|
|
|
3774
3681
|
url: action.url
|
|
3775
3682
|
};
|
|
3776
3683
|
}
|
|
3777
|
-
function termsRequiredError(action, context
|
|
3684
|
+
function termsRequiredError(action, context) {
|
|
3778
3685
|
const requestId = context.requestId;
|
|
3779
3686
|
const retryIdentity = requestId ? ` and requestId ${requestId}` : "";
|
|
3780
3687
|
const message = `Alexandria provider terms required. An organization admin must accept the ${action.terms} provider's terms (version ${action.version}) before this request can run.`;
|
|
@@ -3789,7 +3696,6 @@ Do not retry until acceptance is confirmed.`,
|
|
|
3789
3696
|
code: TERMS_REQUIRED_CODE,
|
|
3790
3697
|
status: 403,
|
|
3791
3698
|
message,
|
|
3792
|
-
...hints ? { agent_hints: hints } : {},
|
|
3793
3699
|
...requestId ? { requestId } : {},
|
|
3794
3700
|
requiresAction: action,
|
|
3795
3701
|
nextTool: {
|
|
@@ -3820,8 +3726,7 @@ Do not retry until acceptance is confirmed.`,
|
|
|
3820
3726
|
function throwIfTermsRequired(error2, context) {
|
|
3821
3727
|
const source = error2;
|
|
3822
3728
|
const action = termsRequiredAction(source?.response?.data ?? source?.details);
|
|
3823
|
-
if (action)
|
|
3824
|
-
throw termsRequiredError(action, context, readErrorAgentHints(error2));
|
|
3729
|
+
if (action) throw termsRequiredError(action, context);
|
|
3825
3730
|
}
|
|
3826
3731
|
async function relayTermsRequired(run, context) {
|
|
3827
3732
|
try {
|
|
@@ -3839,7 +3744,6 @@ async function relayExchangeError(run, context) {
|
|
|
3839
3744
|
const response = error2?.response;
|
|
3840
3745
|
if (!response || response.status === 401) throw error2;
|
|
3841
3746
|
const data = response.data;
|
|
3842
|
-
const hints = readErrorAgentHints(error2);
|
|
3843
3747
|
const message = typeof data?.error === "string" ? data.error : `Alexandria request failed (HTTP ${response.status})`;
|
|
3844
3748
|
const disabledProvider = response.status === 403 ? context.providers?.find((provider) => message === `Access to ${provider} is disabled for this organization.`) : void 0;
|
|
3845
3749
|
if (disabledProvider) {
|
|
@@ -3849,7 +3753,6 @@ async function relayExchangeError(run, context) {
|
|
|
3849
3753
|
code: typeof data?.code === "string" ? data.code : "exchange_error",
|
|
3850
3754
|
status: 403,
|
|
3851
3755
|
message,
|
|
3852
|
-
...hints ? { agent_hints: hints } : {},
|
|
3853
3756
|
nextTool: {
|
|
3854
3757
|
name: "firecrawl_scrape",
|
|
3855
3758
|
arguments: {
|
|
@@ -3863,7 +3766,6 @@ async function relayExchangeError(run, context) {
|
|
|
3863
3766
|
code: typeof data?.code === "string" ? data.code : "exchange_error",
|
|
3864
3767
|
status: response.status,
|
|
3865
3768
|
message,
|
|
3866
|
-
...hints ? { agent_hints: hints } : {},
|
|
3867
3769
|
...typeof data?.chargeId === "string" ? { chargeId: data.chargeId } : {}
|
|
3868
3770
|
});
|
|
3869
3771
|
}
|
|
@@ -3910,10 +3812,6 @@ function copySession(session) {
|
|
|
3910
3812
|
Object.getOwnPropertyDescriptors(session ?? {})
|
|
3911
3813
|
);
|
|
3912
3814
|
}
|
|
3913
|
-
function resultAgentHints(result) {
|
|
3914
|
-
return result && typeof result === "object" ? readAgentHints(result.structuredContent) : void 0;
|
|
3915
|
-
}
|
|
3916
|
-
var warnedMissingAgentHintsInterceptor = false;
|
|
3917
3815
|
var ConsoleLogger = class {
|
|
3918
3816
|
constructor(shouldLog) {
|
|
3919
3817
|
this.shouldLog = shouldLog;
|
|
@@ -4065,20 +3963,10 @@ function createFirecrawlMcpServer(options = {}) {
|
|
|
4065
3963
|
requestId,
|
|
4066
3964
|
session
|
|
4067
3965
|
);
|
|
4068
|
-
hooks.onToolResult?.({
|
|
4069
|
-
...call,
|
|
4070
|
-
status: "success",
|
|
4071
|
-
result,
|
|
4072
|
-
agentHints: resultAgentHints(result)
|
|
4073
|
-
});
|
|
3966
|
+
hooks.onToolResult?.({ ...call, status: "success", result });
|
|
4074
3967
|
return result;
|
|
4075
3968
|
} catch (error2) {
|
|
4076
|
-
hooks.onToolResult?.({
|
|
4077
|
-
...call,
|
|
4078
|
-
status: "error",
|
|
4079
|
-
error: error2,
|
|
4080
|
-
agentHints: readErrorAgentHints(error2)
|
|
4081
|
-
});
|
|
3969
|
+
hooks.onToolResult?.({ ...call, status: "error", error: error2 });
|
|
4082
3970
|
throw error2;
|
|
4083
3971
|
}
|
|
4084
3972
|
}
|
|
@@ -4109,44 +3997,7 @@ function createFirecrawlMcpServer(options = {}) {
|
|
|
4109
3997
|
if (apiKey) {
|
|
4110
3998
|
clientConfig.apiKey = apiKey;
|
|
4111
3999
|
}
|
|
4112
|
-
|
|
4113
|
-
const axiosInstance = client.http?.instance;
|
|
4114
|
-
if (axiosInstance?.interceptors?.request?.use) {
|
|
4115
|
-
axiosInstance.interceptors.request.use((request) => {
|
|
4116
|
-
if (typeof request.headers?.set === "function") {
|
|
4117
|
-
request.headers.set("X-Firecrawl-Agent-Hints", "true");
|
|
4118
|
-
} else {
|
|
4119
|
-
request.headers = { ...request.headers ?? {}, ...AGENT_HINTS_HEADERS };
|
|
4120
|
-
}
|
|
4121
|
-
return request;
|
|
4122
|
-
});
|
|
4123
|
-
} else if (!warnedMissingAgentHintsInterceptor) {
|
|
4124
|
-
warnedMissingAgentHintsInterceptor = true;
|
|
4125
|
-
console.warn(
|
|
4126
|
-
"[firecrawl-mcp] SDK request interceptor unavailable; API agent hints may be absent."
|
|
4127
|
-
);
|
|
4128
|
-
}
|
|
4129
|
-
return client;
|
|
4130
|
-
}
|
|
4131
|
-
async function sdkResultWithAgentHints(client, execute) {
|
|
4132
|
-
const responseInterceptors = client.http?.instance?.interceptors?.response;
|
|
4133
|
-
if (!responseInterceptors?.use) return execute();
|
|
4134
|
-
let hints;
|
|
4135
|
-
const interceptor = responseInterceptors.use((response) => {
|
|
4136
|
-
hints = readAgentHints(response?.data) ?? hints;
|
|
4137
|
-
return response;
|
|
4138
|
-
});
|
|
4139
|
-
try {
|
|
4140
|
-
const result = await execute();
|
|
4141
|
-
return preserveAgentHints(result, { agent_hints: hints });
|
|
4142
|
-
} catch (error2) {
|
|
4143
|
-
if (hints && error2 && typeof error2 === "object" && !readErrorAgentHints(error2)) {
|
|
4144
|
-
error2.agent_hints = hints;
|
|
4145
|
-
}
|
|
4146
|
-
throw error2;
|
|
4147
|
-
} finally {
|
|
4148
|
-
responseInterceptors.eject?.(interceptor);
|
|
4149
|
-
}
|
|
4000
|
+
return new FirecrawlApp(clientConfig);
|
|
4150
4001
|
}
|
|
4151
4002
|
const SAFE_MODE = config.safeMode;
|
|
4152
4003
|
function getClient(session) {
|
|
@@ -4499,7 +4350,6 @@ function createFirecrawlMcpServer(options = {}) {
|
|
|
4499
4350
|
const response = await fetch(`${resolveApiBaseUrl()}${pathName}`, {
|
|
4500
4351
|
method: "POST",
|
|
4501
4352
|
headers: {
|
|
4502
|
-
...AGENT_HINTS_HEADERS,
|
|
4503
4353
|
"Content-Type": "application/json",
|
|
4504
4354
|
...extraHeaders,
|
|
4505
4355
|
Authorization: `Bearer ${apiKey}`,
|
|
@@ -4517,8 +4367,7 @@ function createFirecrawlMcpServer(options = {}) {
|
|
|
4517
4367
|
if (!response.ok) {
|
|
4518
4368
|
throw new CoreHttpError(
|
|
4519
4369
|
parsed?.error || parsed?.message || `Firecrawl request failed (HTTP ${response.status})`,
|
|
4520
|
-
response.status
|
|
4521
|
-
readAgentHints(parsed)
|
|
4370
|
+
response.status
|
|
4522
4371
|
);
|
|
4523
4372
|
}
|
|
4524
4373
|
return parsed;
|
|
@@ -4600,7 +4449,6 @@ function createFirecrawlMcpServer(options = {}) {
|
|
|
4600
4449
|
session,
|
|
4601
4450
|
origin
|
|
4602
4451
|
);
|
|
4603
|
-
const uploadHints = readAgentHints(uploadJson);
|
|
4604
4452
|
const upload = parseApiData(uploadJson);
|
|
4605
4453
|
if (!upload?.uploadUrl || !upload?.uploadRef) {
|
|
4606
4454
|
throw new Error(
|
|
@@ -4611,7 +4459,6 @@ function createFirecrawlMcpServer(options = {}) {
|
|
|
4611
4459
|
const uploadForCommand = { ...upload, headers: uploadHeaders };
|
|
4612
4460
|
return asText({
|
|
4613
4461
|
success: true,
|
|
4614
|
-
...uploadHints ? { agent_hints: uploadHints } : {},
|
|
4615
4462
|
mode: "hosted-upload-ref-awaiting-upload",
|
|
4616
4463
|
message: "Hosted MCP cannot read local files. Run the local upload command, then call firecrawl_parse again with uploadRef. No Firecrawl API key is included in this command.",
|
|
4617
4464
|
upload: {
|
|
@@ -4710,17 +4557,14 @@ Alexandria mode, on an authenticated session with Alexandria access: \`alexandri
|
|
|
4710
4557
|
},
|
|
4711
4558
|
session
|
|
4712
4559
|
);
|
|
4713
|
-
return structuredText(
|
|
4560
|
+
return structuredText(json?.data ?? json);
|
|
4714
4561
|
}
|
|
4715
4562
|
const client = getClient(session);
|
|
4716
4563
|
const res = await relayTermsRequired(
|
|
4717
|
-
() =>
|
|
4718
|
-
|
|
4719
|
-
|
|
4720
|
-
|
|
4721
|
-
origin
|
|
4722
|
-
})
|
|
4723
|
-
),
|
|
4564
|
+
() => client.scrape(String(url), {
|
|
4565
|
+
...cleaned,
|
|
4566
|
+
origin
|
|
4567
|
+
}),
|
|
4724
4568
|
{ tool: "firecrawl_scrape" }
|
|
4725
4569
|
);
|
|
4726
4570
|
return structuredText(res);
|
|
@@ -4760,13 +4604,10 @@ Returns matching URLs rather than page bodies. Retrieve one page with \`firecraw
|
|
|
4760
4604
|
const client = getClient(session);
|
|
4761
4605
|
const cleaned = removeEmptyTopLevel(options2);
|
|
4762
4606
|
log.info("Mapping URL", { url: String(url) });
|
|
4763
|
-
const res = await
|
|
4764
|
-
|
|
4765
|
-
|
|
4766
|
-
|
|
4767
|
-
origin: requestOrigin(mcpClient, session)
|
|
4768
|
-
})
|
|
4769
|
-
);
|
|
4607
|
+
const res = await client.map(String(url), {
|
|
4608
|
+
...cleaned,
|
|
4609
|
+
origin: requestOrigin(mcpClient, session)
|
|
4610
|
+
});
|
|
4770
4611
|
return structuredText(res);
|
|
4771
4612
|
}
|
|
4772
4613
|
});
|
|
@@ -4946,7 +4787,6 @@ For a programming question, add \`categories: ["developer"]\`; its hits return i
|
|
|
4946
4787
|
const origin = originOverride ?? (typeof body.origin === "string" && body.origin.length > 0 ? body.origin : requestOrigin(void 0, session));
|
|
4947
4788
|
await hooks.beforeKeylessRequest?.(session, origin);
|
|
4948
4789
|
const headers = {
|
|
4949
|
-
...AGENT_HINTS_HEADERS,
|
|
4950
4790
|
...originHeaders(origin),
|
|
4951
4791
|
"Content-Type": "application/json",
|
|
4952
4792
|
...resolveOutbound(session).headers
|
|
@@ -4964,14 +4804,11 @@ For a programming question, add \`categories: ["developer"]\`; its hits return i
|
|
|
4964
4804
|
retryAfterSeconds: Number.isFinite(json?.retry_after_seconds) && json.retry_after_seconds > 0 ? json.retry_after_seconds : void 0,
|
|
4965
4805
|
signupUrl: keylessSignupUrlFrom(json?.signup_url)
|
|
4966
4806
|
});
|
|
4967
|
-
const hints = readAgentHints(json);
|
|
4968
|
-
if (hints) payload.agent_hints = hints;
|
|
4969
4807
|
throw new UserError2(String(payload.message), payload);
|
|
4970
4808
|
}
|
|
4971
4809
|
throw new CoreHttpError(
|
|
4972
4810
|
json?.error || `Firecrawl request failed (HTTP ${response.status})`,
|
|
4973
|
-
response.status
|
|
4974
|
-
readAgentHints(json)
|
|
4811
|
+
response.status
|
|
4975
4812
|
);
|
|
4976
4813
|
}
|
|
4977
4814
|
return json;
|
|
@@ -4992,8 +4829,7 @@ For a programming question, add \`categories: ["developer"]\`; its hits return i
|
|
|
4992
4829
|
creditsUsed: body.creditsUsed,
|
|
4993
4830
|
expiresAt: body.expiresAt,
|
|
4994
4831
|
next: body.next ?? null,
|
|
4995
|
-
data: initialDocs
|
|
4996
|
-
...readAgentHints(body) ? { agent_hints: readAgentHints(body) } : {}
|
|
4832
|
+
data: initialDocs
|
|
4997
4833
|
};
|
|
4998
4834
|
}
|
|
4999
4835
|
const docs = initialDocs.slice();
|
|
@@ -5017,8 +4853,7 @@ For a programming question, add \`categories: ["developer"]\`; its hits return i
|
|
|
5017
4853
|
creditsUsed: body.creditsUsed,
|
|
5018
4854
|
expiresAt: body.expiresAt,
|
|
5019
4855
|
next: null,
|
|
5020
|
-
data: docs
|
|
5021
|
-
...readAgentHints(body) ? { agent_hints: readAgentHints(body) } : {}
|
|
4856
|
+
data: docs
|
|
5022
4857
|
};
|
|
5023
4858
|
}
|
|
5024
4859
|
async function waitForCrawlCompletionWithOrigin(client, jobId, origin, pollInterval = 2, timeout) {
|
|
@@ -5114,7 +4949,6 @@ Eligibility is limited to successful searches within the feedback age window. Th
|
|
|
5114
4949
|
}
|
|
5115
4950
|
if (querySuggestions) body.querySuggestions = querySuggestions;
|
|
5116
4951
|
const headers = {
|
|
5117
|
-
...AGENT_HINTS_HEADERS,
|
|
5118
4952
|
...originHeaders(origin),
|
|
5119
4953
|
"Content-Type": "application/json"
|
|
5120
4954
|
};
|
|
@@ -5155,8 +4989,7 @@ Eligibility is limited to successful searches within the feedback age window. Th
|
|
|
5155
4989
|
status: response.status,
|
|
5156
4990
|
feedbackErrorCode: parsed?.feedbackErrorCode,
|
|
5157
4991
|
error: parsed?.error ?? `HTTP ${response.status}`,
|
|
5158
|
-
retryable: response.status >= 500
|
|
5159
|
-
...readAgentHints(parsed) ? { agent_hints: readAgentHints(parsed) } : {}
|
|
4992
|
+
retryable: response.status >= 500
|
|
5160
4993
|
});
|
|
5161
4994
|
}
|
|
5162
4995
|
return structuredText(parsed);
|
|
@@ -5240,7 +5073,6 @@ Returns submission status, feedback ID, and accounting fields.
|
|
|
5240
5073
|
} = args;
|
|
5241
5074
|
const apiBase = resolveApiBaseUrl();
|
|
5242
5075
|
const headers = {
|
|
5243
|
-
...AGENT_HINTS_HEADERS,
|
|
5244
5076
|
...originHeaders(origin),
|
|
5245
5077
|
"Content-Type": "application/json"
|
|
5246
5078
|
};
|
|
@@ -5296,8 +5128,7 @@ Returns submission status, feedback ID, and accounting fields.
|
|
|
5296
5128
|
status: response.status,
|
|
5297
5129
|
feedbackErrorCode: parsed?.feedbackErrorCode,
|
|
5298
5130
|
error: parsed?.error ?? `HTTP ${response.status}`,
|
|
5299
|
-
retryable: response.status >= 500
|
|
5300
|
-
...readAgentHints(parsed) ? { agent_hints: readAgentHints(parsed) } : {}
|
|
5131
|
+
retryable: response.status >= 500
|
|
5301
5132
|
});
|
|
5302
5133
|
}
|
|
5303
5134
|
return structuredText(parsed);
|
|
@@ -5785,7 +5616,6 @@ Set \`redactPII\` to request redaction of personally identifiable information in
|
|
|
5785
5616
|
form.append("file", blob, filename);
|
|
5786
5617
|
form.append("options", JSON.stringify(optionsPayload));
|
|
5787
5618
|
const headers = {
|
|
5788
|
-
...AGENT_HINTS_HEADERS,
|
|
5789
5619
|
...originHeaders(origin)
|
|
5790
5620
|
};
|
|
5791
5621
|
const outbound = resolveOutbound(session);
|
|
@@ -5807,15 +5637,9 @@ Set \`redactPII\` to request redaction of personally identifiable information in
|
|
|
5807
5637
|
});
|
|
5808
5638
|
const responseText = await response.text();
|
|
5809
5639
|
if (!response.ok) {
|
|
5810
|
-
let parsed;
|
|
5811
|
-
try {
|
|
5812
|
-
parsed = JSON.parse(responseText);
|
|
5813
|
-
} catch {
|
|
5814
|
-
}
|
|
5815
5640
|
throw new CoreHttpError(
|
|
5816
5641
|
`Parse request failed with status ${response.status}: ${responseText}`,
|
|
5817
|
-
response.status
|
|
5818
|
-
readAgentHints(parsed)
|
|
5642
|
+
response.status
|
|
5819
5643
|
);
|
|
5820
5644
|
}
|
|
5821
5645
|
try {
|
|
@@ -5843,6 +5667,9 @@ Set \`redactPII\` to request redaction of personally identifiable information in
|
|
|
5843
5667
|
builtInTool: (name2) => builtInTools.get(name2)
|
|
5844
5668
|
}
|
|
5845
5669
|
);
|
|
5670
|
+
hooks.registerResources?.({
|
|
5671
|
+
addResource: (resource) => server.addResource(resource)
|
|
5672
|
+
});
|
|
5846
5673
|
return {
|
|
5847
5674
|
start: (args) => server.start(args),
|
|
5848
5675
|
stop: () => server.stop()
|