Skip to content
Learn Agentic AI
Learn Agentic AI13 min read3 views

MCP Server Discovery and Registry: Finding and Connecting to Available Tools

Learn how MCP clients discover available servers, understand server manifests and tool catalogs, and build a lightweight server registry that lets agents dynamically connect to the right tools.

The Discovery Problem

In a simple setup, an agent connects to a hardcoded list of MCP servers. But as organizations deploy dozens of MCP servers — one for databases, one for Slack, one for file systems, one for monitoring — the question becomes: how does an agent know which servers exist and which tools they offer?

This is the server discovery problem. It parallels service discovery in microservices architectures: you need a registry that catalogs available servers, their capabilities, and their connection details so that agents (or humans configuring agents) can find the right tools without manual configuration.

Static Configuration: The Starting Point

The simplest discovery mechanism is a JSON configuration file that lists available servers. Both Claude Desktop and the OpenAI Agents SDK support this pattern:

flowchart TD
    START["MCP Server Discovery and Registry: Finding and Co…"] --> A
    A["The Discovery Problem"]
    A --> B
    B["Static Configuration: The Starting Point"]
    B --> C
    C["Building a Server Registry"]
    C --> D
    D["Server Manifests"]
    D --> E
    E["Auto-Registration Pattern"]
    E --> F
    F["Agent-Side Dynamic Connection"]
    F --> G
    G["FAQ"]
    G --> DONE["Key Takeaways"]
    style START fill:#4f46e5,stroke:#4338ca,color:#fff
    style DONE fill:#059669,stroke:#047857,color:#fff
# mcp_servers.json — static server configuration
{
    "servers": {
        "database": {
            "transport": "stdio",
            "command": "python",
            "args": ["servers/db_server.py"],
            "description": "Query and manage application databases"
        },
        "filesystem": {
            "transport": "stdio",
            "command": "npx",
            "args": ["-y", "@modelcontextprotocol/server-filesystem", "/data"],
            "description": "Read and write files in the data directory"
        },
        "monitoring": {
            "transport": "http",
            "url": "https://mcp.internal.company.com/monitoring",
            "description": "Access application metrics and alerts"
        }
    }
}

This works for small teams but breaks down as the number of servers grows. Every time someone deploys a new MCP server, every agent configuration file needs to be updated.

Building a Server Registry

A server registry is a centralized catalog that MCP servers register with. Agents query the registry to discover available servers dynamically:

# registry_server.py — a simple MCP server registry
from mcp.server.fastmcp import FastMCP
import json
from datetime import datetime, timedelta

mcp_registry = FastMCP(name="MCPRegistry")

# In-memory registry (use a database in production)
_registry: dict[str, dict] = {}


@mcp_registry.tool()
async def register_server(
    name: str,
    description: str,
    transport: str,
    url: str | None = None,
    command: str | None = None,
    args: list[str] | None = None,
    tags: list[str] | None = None,
) -> str:
    """Register an MCP server in the discovery registry.

    Args:
        name: Unique server name.
        description: What this server does.
        transport: Transport type - 'stdio' or 'http'.
        url: Server URL (required for http transport).
        command: Command to launch (required for stdio transport).
        args: Command arguments (for stdio transport).
        tags: Searchable tags describing server capabilities.
    """
    _registry[name] = {
        "name": name,
        "description": description,
        "transport": transport,
        "url": url,
        "command": command,
        "args": args or [],
        "tags": tags or [],
        "registered_at": datetime.utcnow().isoformat(),
        "last_heartbeat": datetime.utcnow().isoformat(),
    }
    return json.dumps({"registered": name})


@mcp_registry.tool()
async def discover_servers(
    tag: str | None = None,
    transport: str | None = None,
) -> str:
    """Discover available MCP servers, optionally filtered by tag or transport.

    Args:
        tag: Filter servers by this tag.
        transport: Filter by transport type ('stdio' or 'http').
    """
    cutoff = datetime.utcnow() - timedelta(minutes=5)
    results = []

    for server in _registry.values():
        heartbeat = datetime.fromisoformat(server["last_heartbeat"])
        if heartbeat < cutoff:
            continue  # Skip stale servers

        if tag and tag not in server["tags"]:
            continue
        if transport and server["transport"] != transport:
            continue

        results.append(server)

    return json.dumps({
        "count": len(results),
        "servers": results,
    }, indent=2)

Server Manifests

Each MCP server can expose a manifest resource that describes itself in detail. This goes beyond what initialize returns — it includes documentation, examples, and dependency information:

See AI Voice Agents Handle Real Calls

Book a free demo or calculate how much you can save with AI voice automation.

# In your MCP server, expose a manifest resource
@mcp_server.resource("manifest://server/info")
async def get_manifest() -> str:
    """Return the server manifest with capability details."""
    import json
    return json.dumps({
        "name": "DatabaseServer",
        "version": "2.1.0",
        "description": "SQL query and management tools for PostgreSQL",
        "author": "[email protected]",
        "documentation_url": "https://docs.internal/mcp/database",
        "capabilities": {
            "tools": [
                {
                    "name": "query_db",
                    "category": "read",
                    "description": "Execute read-only SQL queries",
                },
                {
                    "name": "insert_record",
                    "category": "write",
                    "description": "Insert records into tables",
                },
            ],
            "resources": ["schema://tables", "metrics://db/stats"],
            "prompts": ["analyze_table", "debug_slow_query"],
        },
        "dependencies": {
            "requires_auth": True,
            "auth_method": "api_key",
            "rate_limit": "100 requests per minute",
        },
    }, indent=2)

Auto-Registration Pattern

Production MCP servers can register themselves with the registry on startup:

import httpx

async def auto_register(registry_url: str, server_info: dict):
    """Register this server with the central MCP registry."""
    async with httpx.AsyncClient() as client:
        response = await client.post(
            f"{registry_url}/mcp",
            json={
                "jsonrpc": "2.0",
                "id": 1,
                "method": "tools/call",
                "params": {
                    "name": "register_server",
                    "arguments": server_info,
                },
            },
        )
        print(f"Registration result: {response.json()}")

Combine auto-registration with periodic heartbeats, and the registry always reflects the current state of available servers. When a server goes down, its heartbeat expires and it disappears from discovery results.

Agent-Side Dynamic Connection

On the agent side, query the registry before building the agent's server list:

from agents import Agent, Runner
from agents.mcp import MCPServerStreamableHTTP

async def build_agent_with_discovery(task_tags: list[str]):
    """Build an agent that connects to servers matching the task."""
    # Query the registry for relevant servers
    registry = MCPServerStreamableHTTP(
        name="Registry",
        params={"url": "http://registry:8000/mcp"},
    )

    async with registry:
        # Use the registry to find servers tagged for our task
        # Then connect the agent to those servers
        pass  # Implementation depends on your agent framework

FAQ

Is there a standard MCP server registry protocol?

As of early 2026, there is no official MCP registry specification. The patterns described here are community-developed approaches. The MCP specification focuses on the client-server protocol, leaving discovery as an implementation concern. Expect a standardized registry protocol to emerge as the ecosystem matures.

How do I handle version conflicts between servers?

Include version information in server manifests and registry entries. When two servers expose tools with the same name, use the server name as a namespace prefix. Your agent configuration should specify which server version to prefer when conflicts arise.

Should agents discover servers at runtime or at configuration time?

For most production deployments, discover at configuration time and cache the server list. Runtime discovery adds latency and introduces a dependency on the registry being available. Reserve runtime discovery for long-running agents that need to adapt to new servers appearing in the ecosystem.


#MCP #ServiceDiscovery #ToolRegistry #AIAgents #AgenticAI #LearnAI #AIEngineering

Share
C

Written by

CallSphere Team

Expert insights on AI voice agents and customer communication automation.

Try CallSphere AI Voice Agents

See how AI voice agents work for your industry. Live demo available -- no signup required.

Related Articles You May Like

Use Cases

Automating Client Document Collection: How AI Agents Chase Missing Tax Documents and Reduce Filing Delays

See how AI agents automate tax document collection — chasing missing W-2s, 1099s, and receipts via calls and texts to eliminate the #1 CPA bottleneck.

Learn Agentic AI

Fine-Tuning LLMs for Agentic Tasks: When and How to Customize Foundation Models

When fine-tuning beats prompting for AI agents: dataset creation from agent traces, SFT and DPO training approaches, evaluation methodology, and cost-benefit analysis for agentic fine-tuning.

Learn Agentic AI

The Rise of Agent-to-Agent Ecosystems: How MCP and A2A Are Creating Agent Marketplaces

How protocols like Anthropic's MCP and Google's A2A enable agents to discover and interact with each other, creating agent marketplaces and service networks in 2026.

Learn Agentic AI

API Design for AI Agent Tool Functions: Best Practices and Anti-Patterns

How to design tool functions that LLMs can use effectively with clear naming, enum parameters, structured responses, informative error messages, and documentation.

Learn Agentic AI

Google Cloud AI Agent Trends Report 2026: Key Findings and Developer Implications

Analysis of Google Cloud's 2026 AI agent trends report covering Gemini-powered agents, Google ADK, Vertex AI agent builder, and enterprise adoption patterns.

Learn Agentic AI

AI Agents for IT Helpdesk: L1 Automation, Ticket Routing, and Knowledge Base Integration

Build IT helpdesk AI agents with multi-agent architecture for triage, device, network, and security issues. RAG-powered knowledge base, automated ticket creation, routing, and escalation.