From 82e0253a6290a7ce0a798305b8432efe92494f2e Mon Sep 17 00:00:00 2001 From: vipyne Date: Thu, 4 Dec 2025 12:56:24 -0600 Subject: [PATCH] add mcp filter example and changelog --- changelog/3187.added.md | 1 + examples/foundational/39-mcp-stdio.py | 35 +++++++++++++++++++---- examples/foundational/39c-multiple-mcp.py | 15 +++++----- 3 files changed, 38 insertions(+), 13 deletions(-) create mode 100644 changelog/3187.added.md diff --git a/changelog/3187.added.md b/changelog/3187.added.md new file mode 100644 index 000000000..967655a3c --- /dev/null +++ b/changelog/3187.added.md @@ -0,0 +1 @@ +- Added optional tool and tool output filters for MCP services. \ No newline at end of file diff --git a/examples/foundational/39-mcp-stdio.py b/examples/foundational/39-mcp-stdio.py index 7127d831f..8fe64f73b 100644 --- a/examples/foundational/39-mcp-stdio.py +++ b/examples/foundational/39-mcp-stdio.py @@ -64,11 +64,14 @@ class UrlToImageProcessor(FrameProcessor): await self.push_frame(frame, direction) def extract_url(self, text: str): - data = json.loads(text) - if "artObject" in data: - return data["artObject"]["webImage"]["url"] - if "artworks" in data and len(data["artworks"]): - return data["artworks"][0]["webImage"]["url"] + try: + data = json.loads(text) + if "artObject" in data: + return data["artObject"]["webImage"]["url"] + if "artworks" in data and len(data["artworks"]): + return data["artworks"][0]["webImage"]["url"] + except: + pass return None @@ -88,6 +91,23 @@ class UrlToImageProcessor(FrameProcessor): logger.error(error_msg) +# full list of tools available from rijksmuseum MCP: +# - get_artwork_details +# - get_artwork_image +# - get_user_sets +# - get_user_set_details +# - open_image_in_browser +# - get_artist_timeline + +mcp_tools_filter = ["get_artwork_details", "get_artwork_image", "open_image_in_browser"] + + +def open_image_output_filter(output: str): + pattern = r"Successfully opened image in browser: " + text_to_print = re.sub(pattern, "", output) + print(f"🖼️ link to high resolution artwork: {text_to_print}") + + # We store functions so objects (e.g. SileroVADAnalyzer) don't get # instantiated. The function will be called when the desired transport gets # selected. @@ -136,7 +156,10 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): # https://github.com/r-huijts/rijksmuseum-mcp args=["-y", "mcp-server-rijksmuseum"], env={"RIJKSMUSEUM_API_KEY": os.getenv("RIJKSMUSEUM_API_KEY")}, - ) + ), + # Optional + tools_filter=mcp_tools_filter, # Optional + tools_output_filters={"open_image_in_browser": open_image_output_filter}, ) except Exception as e: logger.error(f"error setting up mcp") diff --git a/examples/foundational/39c-multiple-mcp.py b/examples/foundational/39c-multiple-mcp.py index 88fdc3610..e69f79f13 100644 --- a/examples/foundational/39c-multiple-mcp.py +++ b/examples/foundational/39c-multiple-mcp.py @@ -67,13 +67,14 @@ class UrlToImageProcessor(FrameProcessor): await self.push_frame(frame, direction) def extract_url(self, text: str): - data = json.loads(text) - if "artObject" in data: - return data["artObject"]["webImage"]["url"] - if "artworks" in data and len(data["artworks"]): - return data["artworks"][0]["webImage"]["url"] - - return None + try: + data = json.loads(text) + if "artObject" in data: + return data["artObject"]["webImage"]["url"] + if "artworks" in data and len(data["artworks"]): + return data["artworks"][0]["webImage"]["url"] + except: + pass async def run_image_process(self, image_url: str): try: