1111import asyncio
1212import json
1313import logging
14- import os
1514import sys
1615from typing import Any , TypedDict
1716
1817import anthropic
1918from anthropic .types import Message , TextBlock
2019from dotenv import load_dotenv
21-
2220from mcp .client .session_group import ClientSessionGroup , StdioServerParameters
2321from mcp .types import TextContent
2422
@@ -29,7 +27,6 @@ class ToolDict(TypedDict, total=False):
2927 name : str
3028 description : str
3129
32-
3330# Load environment variables from .env file
3431load_dotenv ()
3532
@@ -59,7 +56,9 @@ def format(self, record: logging.LogRecord) -> str:
5956
6057# Configure detailed logging
6158handler = logging .StreamHandler (sys .stdout )
62- handler .setFormatter (ColoredFormatter ("%(asctime)s - %(name)s - %(levelname)s - %(message)s" ))
59+ handler .setFormatter (
60+ ColoredFormatter ("%(asctime)s - %(name)s - %(levelname)s - %(message)s" )
61+ )
6362
6463logging .basicConfig (
6564 level = logging .INFO ,
@@ -263,11 +262,10 @@ async def initialize(self):
263262
264263 # Connect to the discovery server via stdio
265264 logger .info ("\n [AGENT] Connecting to MCP server..." )
266- discovery_dir = os .path .dirname (os .path .abspath (__file__ ))
267265 server_params = StdioServerParameters (
268266 command = "uv" ,
269267 args = ["run" , "progressive_discovery_server.py" ],
270- cwd = discovery_dir ,
268+ cwd = "examples/discovery" ,
271269 )
272270
273271 try :
@@ -387,7 +385,9 @@ async def _refresh_prompts(self):
387385 except Exception as e :
388386 logger .debug ("[DISCOVERY] Could not refresh prompts: %s" , e )
389387
390- async def _fetch_and_use_prompt (self , prompt_name : str , arguments : dict [str , str ] | None = None ) -> str :
388+ async def _fetch_and_use_prompt (
389+ self , prompt_name : str , arguments : dict [str , str ] | None = None
390+ ) -> str :
391391 """Fetch a prompt from the server and return its content."""
392392 if not self .mcp_client :
393393 return ""
@@ -449,7 +449,7 @@ async def _fetch_resource_info(self, resource_name: str) -> dict[str, str] | Non
449449 resources = self .mcp_client .resources
450450 if resource_name in resources :
451451 resource = resources [resource_name ] # type: ignore
452- logger .info ("[DISCOVERY] Found resource: %s" , resource_name )
452+ logger .info ("[DISCOVERY] 📦 Found resource: %s" , resource_name )
453453 return {
454454 "name" : resource .name , # type: ignore
455455 "description" : resource .description , # type: ignore
@@ -531,7 +531,7 @@ async def _process_tool_call(self, tool_name: str, tool_input: dict[str, Any]) -
531531 raise RuntimeError ("MCP client not initialized" )
532532
533533 logger .info (
534- "\033 [95m \ n [AGENT] Calling tool: %s with args: %s\033 [0m " ,
534+ "\n [AGENT] Calling tool: %s with args: %s" ,
535535 tool_name ,
536536 json .dumps (tool_input ),
537537 )
@@ -639,7 +639,9 @@ async def chat(self, user_message: str) -> str:
639639 # Try to read the resource content
640640 content = await self ._read_resource (uri )
641641 if content :
642- resource_contents .append (f"[RESOURCE: { resource_info ['name' ]} ]\n { content } " )
642+ resource_contents .append (
643+ f"[RESOURCE: { resource_info ['name' ]} ]\n { content } "
644+ )
643645 else :
644646 resource_contents .append (
645647 f"[RESOURCE: { resource_info ['name' ]} ]\n { resource_info ['description' ]} \n URI: { uri } "
@@ -651,7 +653,10 @@ async def chat(self, user_message: str) -> str:
651653 )
652654
653655 if resource_contents :
654- resource_context = "[AVAILABLE RESOURCES]\n \n " + "\n \n " .join (resource_contents )
656+ resource_context = (
657+ "[AVAILABLE RESOURCES]\n \n "
658+ + "\n \n " .join (resource_contents )
659+ )
655660 messages .append (
656661 {
657662 "role" : "user" ,
@@ -680,7 +685,8 @@ async def chat(self, user_message: str) -> str:
680685 self .context_tracker .add_message (response )
681686
682687 logger .info ( # type: ignore
683- "[AGENT] Claude response - stop_reason: %s | Tokens: input=%d, output=%d, total=%d" ,
688+ "[AGENT] Claude response - stop_reason: %s | "
689+ "Tokens: input=%d, output=%d, total=%d" ,
684690 response .stop_reason , # type: ignore
685691 response .usage .input_tokens , # type: ignore
686692 response .usage .output_tokens , # type: ignore
@@ -754,7 +760,9 @@ async def chat(self, user_message: str) -> str:
754760 # Try to read the resource content
755761 content = await self ._read_resource (uri )
756762 if content :
757- loaded_resources .append (f"[RESOURCE: { resource_info ['name' ]} ]\n { content } " )
763+ loaded_resources .append (
764+ f"[RESOURCE: { resource_info ['name' ]} ]\n { content } "
765+ )
758766 else :
759767 loaded_resources .append (
760768 f"[RESOURCE: { resource_info ['name' ]} ]\n { resource_info ['description' ]} \n URI: { uri } "
@@ -767,16 +775,17 @@ async def chat(self, user_message: str) -> str:
767775
768776 if loaded_resources :
769777 # Inject all resources with their content
770- resource_context = "[AVAILABLE RESOURCES]\n \n " + "\n \n " .join (loaded_resources )
778+ resource_context = (
779+ "[AVAILABLE RESOURCES]\n \n "
780+ + "\n \n " .join (loaded_resources )
781+ )
771782 messages .append (
772783 {
773784 "role" : "user" ,
774785 "content" : resource_context ,
775786 }
776787 )
777- logger .info (
778- "[DISCOVERY] ✓ Injected %d resources into conversation" , len (loaded_resources )
779- )
788+ logger .info ("[DISCOVERY] ✓ Injected %d resources into conversation" , len (loaded_resources ))
780789
781790 # Collect tool result
782791 tool_results .append ( # type: ignore
@@ -806,7 +815,9 @@ async def chat(self, user_message: str) -> str:
806815
807816 async def run_test_scenarios (self ):
808817 """Run test scenario demonstrating prompt usage and tool group traversal."""
809- test_question = "whats the weather like right now in my location, after you figured that out, what is 25 * 5"
818+ test_question = (
819+ "whats the weather like right now in my location"
820+ )
810821
811822 try :
812823 logger .info ("\n " + "=" * 80 )
0 commit comments