Skip to content

Commit 52087a1

Browse files
committed
Update index.ts
1 parent 3450638 commit 52087a1

File tree

1 file changed

+41
-33
lines changed

1 file changed

+41
-33
lines changed

src/index.ts

Lines changed: 41 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,9 @@ function createClient(apiKey?: string): FirecrawlApp {
133133

134134
const ORIGIN = 'mcp-fastmcp';
135135

136+
// Safe mode is enabled by default for cloud service to comply with ChatGPT safety requirements
137+
const SAFE_MODE = process.env.CLOUD_SERVICE === 'true';
138+
136139
function getClient(session?: SessionData): FirecrawlApp {
137140
// For cloud service, API key is required
138141
if (process.env.CLOUD_SERVICE === 'true') {
@@ -156,6 +159,15 @@ function asText(data: unknown): string {
156159

157160
// scrape tool (v2 semantics, minimal args)
158161
// Centralized scrape params (used by scrape, and referenced in search/crawl scrapeOptions)
162+
163+
// Define safe action types
164+
const safeActionTypes = ['wait', 'screenshot', 'scroll', 'scrape'] as const;
165+
const otherActions = ['click', 'write', 'press', 'executeJavascript', 'generatePDF'] as const;
166+
const allActionTypes = [...safeActionTypes, ...otherActions] as const;
167+
168+
// Use appropriate action types based on safe mode
169+
const allowedActionTypes = SAFE_MODE ? safeActionTypes : allActionTypes;
170+
159171
const scrapeParamsSchema = z.object({
160172
url: z.string().url(),
161173
formats: z
@@ -190,30 +202,22 @@ const scrapeParamsSchema = z.object({
190202
includeTags: z.array(z.string()).optional(),
191203
excludeTags: z.array(z.string()).optional(),
192204
waitFor: z.number().optional(),
193-
actions: z
194-
.array(
195-
z.object({
196-
type: z.enum([
197-
'wait',
198-
'click',
199-
'screenshot',
200-
'write',
201-
'press',
202-
'scroll',
203-
'scrape',
204-
'executeJavascript',
205-
'generatePDF',
206-
]),
207-
selector: z.string().optional(),
208-
milliseconds: z.number().optional(),
209-
text: z.string().optional(),
210-
key: z.string().optional(),
211-
direction: z.enum(['up', 'down']).optional(),
212-
script: z.string().optional(),
213-
fullPage: z.boolean().optional(),
214-
})
215-
)
216-
.optional(),
205+
...(SAFE_MODE ? {} : {
206+
actions: z
207+
.array(
208+
z.object({
209+
type: z.enum(allowedActionTypes),
210+
selector: z.string().optional(),
211+
milliseconds: z.number().optional(),
212+
text: z.string().optional(),
213+
key: z.string().optional(),
214+
direction: z.enum(['up', 'down']).optional(),
215+
script: z.string().optional(),
216+
fullPage: z.boolean().optional(),
217+
})
218+
)
219+
.optional(),
220+
}),
217221
mobile: z.boolean().optional(),
218222
skipTlsVerification: z.boolean().optional(),
219223
removeBase64Images: z.boolean().optional(),
@@ -250,6 +254,7 @@ This is the most powerful, fastest and most reliable scraper tool, if available
250254
\`\`\`
251255
**Performance:** Add maxAge parameter for 500% faster scrapes using cached data.
252256
**Returns:** Markdown, HTML, or other formats as specified.
257+
${SAFE_MODE ? '**Safe Mode:** Read-only content extraction. Interactive actions (click, write, executeJavascript) are disabled for security.' : ''}
253258
`,
254259
parameters: scrapeParamsSchema,
255260
execute: async (
@@ -405,6 +410,7 @@ server.addTool({
405410
}
406411
\`\`\`
407412
**Returns:** Operation ID for status checking; use firecrawl_check_crawl_status to check progress.
413+
${SAFE_MODE ? '**Safe Mode:** Read-only crawling. Webhooks and interactive actions are disabled for security.' : ''}
408414
`,
409415
parameters: z.object({
410416
url: z.string(),
@@ -419,15 +425,17 @@ server.addTool({
419425
crawlEntireDomain: z.boolean().optional(),
420426
delay: z.number().optional(),
421427
maxConcurrency: z.number().optional(),
422-
webhook: z
423-
.union([
424-
z.string(),
425-
z.object({
426-
url: z.string(),
427-
headers: z.record(z.string(), z.string()).optional(),
428-
}),
429-
])
430-
.optional(),
428+
...(SAFE_MODE ? {} : {
429+
webhook: z
430+
.union([
431+
z.string(),
432+
z.object({
433+
url: z.string(),
434+
headers: z.record(z.string(), z.string()).optional(),
435+
}),
436+
])
437+
.optional(),
438+
}),
431439
deduplicateSimilarURLs: z.boolean().optional(),
432440
ignoreQueryParameters: z.boolean().optional(),
433441
scrapeOptions: scrapeParamsSchema.omit({ url: true }).partial().optional(),

0 commit comments

Comments
 (0)