99- smartcrawler_fetch_results: Retrieve results from asynchronous crawling operations
1010"""
1111
12- import os
1312import json
1413from typing import Any , Dict , Optional , List , Union
1514
1615import httpx
17- import uvicorn
18- from fastmcp import FastMCP
16+ from fastmcp import Context , FastMCP
1917from smithery .decorators import smithery
2018from pydantic import BaseModel , Field
21- from starlette .middleware .cors import CORSMiddleware
2219
2320
2421class ScapeGraphClient :
@@ -35,7 +32,7 @@ def __init__(self, api_key: str):
3532 """
3633 self .api_key = api_key
3734 self .headers = {
38- "SGAI_API_KEY " : api_key ,
35+ "SGAI-APIKEY " : api_key ,
3936 "Content-Type" : "application/json"
4037 }
4138 self .client = httpx .Client (timeout = httpx .Timeout (120.0 ))
@@ -307,48 +304,16 @@ def close(self) -> None:
307304
308305# Pydantic configuration schema for Smithery
309306class ConfigSchema (BaseModel ):
310- api_key : str = Field (description = "Your Scrapegraph API key" )
307+ scrapegraph_api_key : str = Field (..., description = "Your Scrapegraph API key" )
311308
312309
313- # Create MCP server
310+ # Create MCP server instance
314311mcp = FastMCP ("ScapeGraph API MCP Server" )
315312
316- # Default API key (will be overridden in main or by direct assignment)
317- default_api_key = os .environ .get ("SGAI_API_KEY" )
318- scrapegraph_client = ScapeGraphClient (default_api_key ) if default_api_key else None
319-
320-
321- # Smithery server function with config schema
322- @smithery .server (config_schema = ConfigSchema )
323- def create_server (config : Optional [ConfigSchema ] = None ) -> FastMCP :
324- """
325- Create and return the FastMCP server instance for Smithery deployment.
326-
327- Args:
328- config: Configuration object with api_key
329-
330- Returns:
331- Configured FastMCP server instance
332- """
333- global scrapegraph_client
334-
335- # Get API key from config or environment
336- api_key = None
337- if config and hasattr (config , 'api_key' ):
338- api_key = config .api_key
339- else :
340- api_key = os .environ .get ("SGAI_API_KEY" )
341-
342- # Initialize client if API key is available
343- if api_key :
344- scrapegraph_client = ScapeGraphClient (api_key )
345-
346- return mcp
347-
348313
349314# Add tool for markdownify
350315@mcp .tool ()
351- def markdownify (website_url : str ) -> Dict [str , Any ]:
316+ def markdownify (website_url : str , ctx : Context ) -> Dict [str , Any ]:
352317 """
353318 Convert a webpage into clean, formatted markdown.
354319
@@ -358,11 +323,9 @@ def markdownify(website_url: str) -> Dict[str, Any]:
358323 Returns:
359324 Dictionary containing the markdown result
360325 """
361- if scrapegraph_client is None :
362- return {"error" : "ScapeGraph client not initialized. Please provide an API key." }
363-
364326 try :
365- return scrapegraph_client .markdownify (website_url )
327+ client = ScapeGraphClient (ctx .session_config .scrapegraph_api_key )
328+ return client .markdownify (website_url )
366329 except Exception as e :
367330 return {"error" : str (e )}
368331
@@ -372,6 +335,7 @@ def markdownify(website_url: str) -> Dict[str, Any]:
372335def smartscraper (
373336 user_prompt : str ,
374337 website_url : str ,
338+ ctx : Context ,
375339 number_of_scrolls : int = None ,
376340 markdown_only : bool = None
377341) -> Dict [str , Any ]:
@@ -387,11 +351,9 @@ def smartscraper(
387351 Returns:
388352 Dictionary containing the extracted data or markdown content
389353 """
390- if scrapegraph_client is None :
391- return {"error" : "ScapeGraph client not initialized. Please provide an API key." }
392-
393354 try :
394- return scrapegraph_client .smartscraper (user_prompt , website_url , number_of_scrolls , markdown_only )
355+ client = ScapeGraphClient (ctx .session_config .scrapegraph_api_key )
356+ return client .smartscraper (user_prompt , website_url , number_of_scrolls , markdown_only )
395357 except Exception as e :
396358 return {"error" : str (e )}
397359
@@ -400,6 +362,7 @@ def smartscraper(
400362@mcp .tool ()
401363def searchscraper (
402364 user_prompt : str ,
365+ ctx : Context ,
403366 num_results : int = None ,
404367 number_of_scrolls : int = None
405368) -> Dict [str , Any ]:
@@ -414,11 +377,9 @@ def searchscraper(
414377 Returns:
415378 Dictionary containing search results and reference URLs
416379 """
417- if scrapegraph_client is None :
418- return {"error" : "ScapeGraph client not initialized. Please provide an API key." }
419-
420380 try :
421- return scrapegraph_client .searchscraper (user_prompt , num_results , number_of_scrolls )
381+ client = ScapeGraphClient (ctx .session_config .scrapegraph_api_key )
382+ return client .searchscraper (user_prompt , num_results , number_of_scrolls )
422383 except Exception as e :
423384 return {"error" : str (e )}
424385
@@ -427,6 +388,7 @@ def searchscraper(
427388@mcp .tool ()
428389def smartcrawler_initiate (
429390 url : str ,
391+ ctx : Context ,
430392 prompt : str = None ,
431393 extraction_mode : str = "ai" ,
432394 depth : int = None ,
@@ -451,11 +413,9 @@ def smartcrawler_initiate(
451413 Returns:
452414 Dictionary containing the request ID for async processing
453415 """
454- if scrapegraph_client is None :
455- return {"error" : "ScapeGraph client not initialized. Please provide an API key." }
456-
457416 try :
458- return scrapegraph_client .smartcrawler_initiate (
417+ client = ScapeGraphClient (ctx .session_config .scrapegraph_api_key )
418+ return client .smartcrawler_initiate (
459419 url = url ,
460420 prompt = prompt ,
461421 extraction_mode = extraction_mode ,
@@ -469,7 +429,7 @@ def smartcrawler_initiate(
469429
470430# Add tool for fetching SmartCrawler results
471431@mcp .tool ()
472- def smartcrawler_fetch_results (request_id : str ) -> Dict [str , Any ]:
432+ def smartcrawler_fetch_results (request_id : str , ctx : Context ) -> Dict [str , Any ]:
473433 """
474434 Fetch the results of a SmartCrawler operation.
475435
@@ -480,30 +440,26 @@ def smartcrawler_fetch_results(request_id: str) -> Dict[str, Any]:
480440 Dictionary containing the crawled data (structured extraction or markdown)
481441 and metadata about processed pages
482442 """
483- if scrapegraph_client is None :
484- return {"error" : "ScapeGraph client not initialized. Please provide an API key." }
485-
486443 try :
487- return scrapegraph_client .smartcrawler_fetch_results (request_id )
444+ client = ScapeGraphClient (ctx .session_config .scrapegraph_api_key )
445+ return client .smartcrawler_fetch_results (request_id )
488446 except Exception as e :
489447 return {"error" : str (e )}
490448
491449
492450# Add tool for basic scrape
493451@mcp .tool ()
494- def scrape (website_url : str , render_heavy_js : Optional [bool ] = None ) -> Dict [str , Any ]:
452+ def scrape (website_url : str , ctx : Context , render_heavy_js : Optional [bool ] = None ) -> Dict [str , Any ]:
495453 """
496454 Fetch page content for a URL.
497455
498456 Args:
499457 website_url: URL to scrape
500458 render_heavy_js: Whether to render heavy JS (optional)
501459 """
502- if scrapegraph_client is None :
503- return {"error" : "ScapeGraph client not initialized. Please provide an API key." }
504-
505460 try :
506- return scrapegraph_client .scrape (website_url = website_url , render_heavy_js = render_heavy_js )
461+ client = ScapeGraphClient (ctx .session_config .scrapegraph_api_key )
462+ return client .scrape (website_url = website_url , render_heavy_js = render_heavy_js )
507463 except httpx .HTTPError as http_err :
508464 return {"error" : str (http_err )}
509465 except ValueError as val_err :
@@ -512,18 +468,16 @@ def scrape(website_url: str, render_heavy_js: Optional[bool] = None) -> Dict[str
512468
513469# Add tool for sitemap extraction
514470@mcp .tool ()
515- def sitemap (website_url : str ) -> Dict [str , Any ]:
471+ def sitemap (website_url : str , ctx : Context ) -> Dict [str , Any ]:
516472 """
517473 Extract sitemap for a website.
518474
519475 Args:
520476 website_url: Base website URL
521477 """
522- if scrapegraph_client is None :
523- return {"error" : "ScapeGraph client not initialized. Please provide an API key." }
524-
525478 try :
526- return scrapegraph_client .sitemap (website_url = website_url )
479+ client = ScapeGraphClient (ctx .session_config .scrapegraph_api_key )
480+ return client .sitemap (website_url = website_url )
527481 except httpx .HTTPError as http_err :
528482 return {"error" : str (http_err )}
529483 except ValueError as val_err :
@@ -534,6 +488,7 @@ def sitemap(website_url: str) -> Dict[str, Any]:
534488@mcp .tool ()
535489def agentic_scrapper (
536490 url : str ,
491+ ctx : Context ,
537492 user_prompt : Optional [str ] = None ,
538493 output_schema : Optional [Union [str , Dict [str , Any ]]] = None ,
539494 steps : Optional [Union [str , List [str ]]] = None ,
@@ -544,9 +499,6 @@ def agentic_scrapper(
544499 """
545500 Run the Agentic Scraper workflow. Accepts flexible input forms for steps and schema.
546501 """
547- if scrapegraph_client is None :
548- return {"error" : "ScapeGraph client not initialized. Please provide an API key." }
549-
550502 # Normalize inputs
551503 normalized_steps : Optional [List [str ]] = None
552504 if isinstance (steps , list ):
@@ -576,7 +528,8 @@ def agentic_scrapper(
576528 return {"error" : f"Invalid JSON for output_schema: { str (e )} " }
577529
578530 try :
579- return scrapegraph_client .agentic_scrapper (
531+ client = ScapeGraphClient (ctx .session_config .scrapegraph_api_key )
532+ return client .agentic_scrapper (
580533 url = url ,
581534 user_prompt = user_prompt ,
582535 output_schema = normalized_schema ,
@@ -593,51 +546,21 @@ def agentic_scrapper(
593546 return {"error" : str (val_err )}
594547
595548
596- # Config schema for Smithery
597- CONFIG_SCHEMA = {
598- "type" : "object" ,
599- "required" : ["scrapegraphApiKey" ],
600- "properties" : {
601- "scrapegraphApiKey" : {
602- "type" : "string" ,
603- "description" : "Your Scrapegraph API key"
604- }
605- }
606- }
607-
608-
609- @smithery .server (config_schema = CONFIG_SCHEMA )
610- def create_server (config : Optional [Dict [str , Any ]] = None ) -> FastMCP :
549+ # Smithery server creation function
550+ @smithery .server (config_schema = ConfigSchema )
551+ def create_server () -> FastMCP :
611552 """
612553 Create and return the FastMCP server instance for Smithery deployment.
613-
614- Args:
615- config: Configuration dictionary with optional keys:
616- - scrapegraphApiKey: API key for ScapeGraph API
617-
554+
618555 Returns:
619556 Configured FastMCP server instance
620557 """
621- global scrapegraph_client
622-
623- # Get API key from config or environment
624- api_key = None
625- if config and "scrapegraphApiKey" in config :
626- api_key = config ["scrapegraphApiKey" ]
627- else :
628- api_key = os .environ .get ("SGAI_API_KEY" )
629-
630- # Initialize client if API key is available
631- if api_key :
632- scrapegraph_client = ScapeGraphClient (api_key )
633-
634558 return mcp
635559
636560
637561def main () -> None :
638562 """Run the ScapeGraph MCP server."""
639563 print ("Starting ScapeGraph MCP server!" )
640- # Run the server
641564 mcp .run (transport = "stdio" )
642565
643566
0 commit comments