> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mcprank.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Agent Tools

> Build AI agents with automatic tool discovery

# Building Agents with Tool Discovery

The MCP Rank SDK makes it easy to build AI agents that automatically discover and use the right tools for any task.

## The Agent Class

The `Agent` class wraps OpenAI or Anthropic clients and handles:

* Searching for relevant MCP servers
* Discovering tools from those servers
* Formatting tools for the model
* Executing tool calls
* Managing the conversation loop

```python theme={null}
from openai import OpenAI
from mcp_rank import Agent

agent = Agent(
    OpenAI(),
    api_key="sk_mcp_rank_...",
    max_tool_calls=10,  # Max iterations
)

response = agent.run("Send an email to the team about the project update")
print(response)
```

## Supported Models

### OpenAI

```python theme={null}
from openai import OpenAI, AsyncOpenAI
from mcp_rank import Agent

# Sync client
agent = Agent(OpenAI(), api_key="sk_mcp_rank_...")
response = agent.run("What's the weather?", model="gpt-4o")

# Async client
async_agent = Agent(AsyncOpenAI(), api_key="sk_mcp_rank_...")
response = await async_agent.run_async("What's the weather?")
```

### Anthropic

```python theme={null}
from anthropic import Anthropic, AsyncAnthropic
from mcp_rank import Agent

agent = Agent(Anthropic(), api_key="sk_mcp_rank_...")
response = agent.run(
    "Summarize my recent emails",
    model="claude-3-5-sonnet-20241022"
)
```

## How Tool Discovery Works

1. **Search**: When you call `agent.run()`, we search for MCP servers matching your query
2. **Discovery**: We connect to the top servers and list their tools
3. **Format**: Tools are formatted for the model (OpenAI function calling or Anthropic tools)
4. **Execute**: When the model calls a tool, we invoke it on the MCP server
5. **Loop**: The conversation continues until the model responds without tool calls

```python theme={null}
# Behind the scenes:
# 1. Search: "send email" -> finds gmail-mcp-server
# 2. Discovery: gmail-mcp-server has send_email, list_emails tools
# 3. Format: Tools converted to OpenAI function calling format
# 4. Execute: Model calls send_email -> we invoke it on the server
# 5. Loop: Model gets result, generates final response
```

## Custom Configuration

```python theme={null}
agent = Agent(
    OpenAI(),
    api_key="sk_mcp_rank_...",
    api_url="https://api.mcprank.com",  # API endpoint
    timeout=30.0,  # Request timeout
    max_tool_calls=10,  # Max tool iterations
)
```

## Error Handling

```python theme={null}
try:
    response = agent.run("Send an email to bob@example.com")
except Exception as e:
    print(f"Agent failed: {e}")
```

Common errors:

* **Tool not found**: No MCP server matched the query
* **Tool execution failed**: The MCP server returned an error
* **Max iterations**: Agent hit `max_tool_calls` limit

## Improving Results

### Be Specific

```python theme={null}
# Good - specific task
response = agent.run("Send an email to bob@example.com with subject 'Meeting' and body 'See you at 3pm'")

# Less good - vague
response = agent.run("Help me with email")
```

### Provide Context

```python theme={null}
response = agent.run(
    "Schedule a meeting with the team for next Tuesday at 2pm to discuss the Q1 roadmap",
    model="gpt-4o"  # Use a capable model for complex tasks
)
```

## Direct Tool Usage

For more control, use the `MCPRankClient` directly:

```python theme={null}
from mcp_rank import MCPRankClient
from mcp_rank.proxy import MCPServerProxy

async with MCPRankClient(api_key="sk_mcp_rank_...") as client:
    # Search for servers
    results = await client.search("email tools")
    
    # Get tools from a specific server
    proxy = MCPServerProxy()
    server = results["servers"][0]
    tools = await proxy.discover_tools(server["remote_url"])
    
    # Invoke a tool directly
    result, latency, error = await proxy.invoke_tool(
        remote_url=server["remote_url"],
        tool_name="send_email",
        arguments={"to": "bob@example.com", "subject": "Hello"}
    )
```
