Opportunistically Discover and Utilize Remote MCP Servers in Your Agents
Simply run:
docker compose upThis spins up 3 containers: Client, Website, and MCP Server -- each with its own startup command.
This document describes the complete event flow of a dynamic Model Context Protocol (MCP) agent that discovers and integrates new tools at runtime by detecting MCP servers through HTTP headers.
The system consists of three components:
- Client Agent - A LangChain-based agent that can dynamically discover and integrate MCP servers
- MCP Server - Provides job search and application tools via the MCP protocol
- Web Server - Serves job listing pages with MCP discovery headers
The user initiates a job search:
User Query: "i want to get a job at TechCorp. Please look for jobs online.
I am a software engineer, open to anything. What jobs can I apply for?"
The agent starts with two base tools:
bing-search-tool- Mock web search functionalityweb-crawler-tool- Extracts content and HTTP headers from URLs
Step 1: Web Search
The agent calls bing-search-tool with the query:
{'query': 'TechCorp jobs TechCorp careers "TechCorp" software engineer jobs...'}This returns two results:
http://website:8000/first-page- Software Engineer job postinghttp://website:8000/second-page- Job market article
Step 2: Web Crawling & MCP Discovery
The agent calls web-crawler-tool on the first URL:
{'url': 'http://website:8000/first-page'}The crawler extracts:
- Page content (job requirements, benefits, etc.)
- HTTP headers, including the critical
mcp_urlheader
Found MCP URL in headers: http://mcp:8000/mcp
Discovered new MCP server: http://mcp:8000/mcp
The web server's /first-page endpoint includes this custom header:
response.headers["mcp_url"] = "http://mcp:8000/mcp"Once the MCP server is discovered, the system:
- Registers the MCP server in the client's server configuration
- Recreates the agent with expanded toolset
- Loads MCP tools from the newly discovered server
New MCP Tools Discovered! Recreating Agent
Loaded 2 tools from 1 MCP server(s)
- search_jobs: Search for jobs at a company.
- apply_to_job: Apply to a job posting.
The agent is re-invoked with the same query plus a note about new tools:
User Query (augmented): "i want to get a job at TechCorp. Please look for jobs online.
I am a software engineer, open to anything. What jobs can I apply for?
(Note: New tools are now available, use them if helpful)"
Step 3: Search with Base Tools
The agent re-executes the web search and crawler (discovering the same MCP URL, which is now skipped since it's already registered).
Step 4: Company-Specific Job Search
The agent now calls the newly available search_jobs MCP tool:
{'company': 'TechCorp'}Returns:
[
{"id": "job_001", "title": "Software Engineer", "company": "TechCorp"},
{"id": "job_002", "title": "Machine Learning Engineer", "company": "TechCorp"}
]Step 5: Additional Content Gathering
The agent also crawls the second page to gather market context.
The agent synthesizes all information and provides:
- Search Results Summary - Raw search hits from the mock search tool
- Crawled Page Content - Detailed job requirements from the first page
- Jobs from MCP Tool - Structured job data (job_001, job_002)
- Recommendations - Direct match analysis for the Software Engineer role
- Next Steps - Options to apply, search more broadly, tailor resume, or prepare for interviews
The client's web-crawler-tool inspects HTTP response headers:
mcp_url = headers.get("mcp_url")
if mcp_url:
print(f"Found MCP URL in headers: {mcp_url}")
await self.add_mcp_server(mcp_url)The MCP server exposes tools via FastMCP:
@server.tool()
def search_jobs(company: str) -> list:
"""Search for jobs at a company."""
return [...]
@server.tool()
def apply_to_job(job_id: str, name: str) -> dict:
"""Apply to a job posting."""
return {...}The agent is configured to autonomously use tools:
"You are an autonomous assistant with access to search and crawling tools.
When a user asks to find, search, or look up something online,
immediately call the `bing-search-tool` with their query. Do not ask for confirmation.
If a URL is provided or found in the search results,
you must call the `web-crawler-tool` to extract its content,
when the article is actually relevant to the query.
After crawling, if new tools become available, use them if they help answer the user's query."
The dynamic MCP discovery pattern enables the agent to:
- Start with general-purpose web tools
- Discover domain-specific tools at runtime through HTTP headers
- Automatically expand its capabilities without manual reconfiguration
- Provide more comprehensive and specialized responses using the newly discovered tools