Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 20 additions & 5 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from typing import Annotated

from fastmcp import FastMCP
from mcp.types import TextContent
from mcp_ui_server.core import UIResource
from pydantic import Field
from starlette.requests import Request
Expand All @@ -14,7 +15,6 @@
from config import get_config
from middleware import BearerAuthMiddleware, RequestLoggingMiddleware
from search import google_search, google_search_raw, extract_page_content, SerperClient, create_search_results_ui
from mcp_ui_server import create_ui_resource

# Load configuration
config = get_config()
Expand Down Expand Up @@ -49,7 +49,7 @@ async def lifespan(app):
mcp = FastMCP(
name="mcp-search",
version="0.1.0",
instructions="MCP Search Server providing search tools.",
instructions="MCP Search Server providing search tools with UI.",
# Performance and behavior settings
on_duplicate_tools=config.ON_DUPLICATE_TOOLS,
on_duplicate_resources=config.ON_DUPLICATE_RESOURCES,
Expand Down Expand Up @@ -135,8 +135,8 @@ async def search_web_ui_tool(
location: Annotated[str | None, Field(description="Geographic location for results (e.g., 'Prague, Czech Republic', 'New York, United States')")] = None,
time_period: Annotated[str | None, Field(description="Time filter: 'qdr:h' (past hour), 'qdr:d' (past day), 'qdr:w' (past week), 'qdr:m' (past month), 'qdr:y' (past year)")] = None,
page: Annotated[int | None, Field(description="Page number for pagination (starts at 1)", ge=1)] = 1,
) -> list[UIResource]:
"""Search the web using Google and return results with visual UI."""
) -> list[UIResource | TextContent]:
"""Search the web using Google and return results with visual UI and text content."""
# Get raw search results
data = await google_search_raw(
query=query,
Expand All @@ -152,7 +152,22 @@ async def search_web_ui_tool(
# Create UI resource using helper from search package
ui_resource = create_search_results_ui(query, results)

return [ui_resource]
# Format text content for client awareness
text_lines = [f"Search results for: {query}\n"]
for i, item in enumerate(results, 1):
title = item.get("title", "No title")
link = item.get("link", "")
snippet = item.get("snippet", "")
text_lines.append(f"{i}. {title}\n URL: {link}\n {snippet}\n")
Comment on lines +156 to +161
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The text formatting has redundant newlines that create excessive spacing. Each element in text_lines already contains trailing newlines (e.g., "Search results for: {query}\n" and "{i}. {title}\n URL: {link}\n {snippet}\n"), and then line 165 joins them with additional newlines using "\n".join(text_lines). This results in double-spacing between elements. Consider either removing the trailing newlines from each line or using "".join() instead of "\n".join() to avoid the redundant spacing.

Copilot uses AI. Check for mistakes.

text_content = TextContent(
type="text",
text="\n".join(text_lines)
)
Comment on lines +155 to +166
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When results is empty, the text content will only show "Search results for: {query}" without any indication that no results were found. The UI component handles empty results by displaying a message ("Žádné výsledky" meaning "No results" in Czech - see search/ui.py:44-56), but the text content doesn't provide equivalent feedback. Consider adding a check for empty results and providing a clear message in the text content, such as "No results found."

Copilot uses AI. Check for mistakes.

# Return both UI resource and text content
# The UI will be displayed visually, and the text makes the client aware of results
return [ui_resource, text_content]


# ============================================================================
Expand Down
Loading