@@ -133,6 +133,9 @@ function createClient(apiKey?: string): FirecrawlApp {
133133
134134const 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+
136139function 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+
159171const 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