Skip to content
Merged
134 changes: 83 additions & 51 deletions examples/mcp_agent_server/asyncio/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,25 +55,26 @@ Before running the example, you'll need to configure the necessary paths and API

1. Copy the example secrets file:

```bash
cp mcp_agent.secrets.yaml.example mcp_agent.secrets.yaml
```
```
cp mcp_agent.secrets.yaml.example mcp_agent.secrets.yaml
```

2. Edit `mcp_agent.secrets.yaml` to add your API keys:
```yaml
anthropic:
api_key: "your-anthropic-api-key"
openai:
api_key: "your-openai-api-key"
```

```
anthropic:
api_key: "your-anthropic-api-key"
openai:
api_key: "your-openai-api-key"
```

## How to Run

### Using the Client Script

The simplest way to run the example is using the provided client script:

```bash
```
# Make sure you're in the mcp_agent_server/asyncio directory
uv run client.py
```
Expand All @@ -91,21 +92,52 @@ You can also run the server and client separately:

1. In one terminal, start the server:

```bash
uv run basic_agent_server.py
```
uv run basic_agent_server.py

# Optionally, run with the example custom FastMCP settings
uv run basic_agent_server.py --custom-fastmcp-settings
```
# Optionally, run with the example custom FastMCP settings
uv run basic_agent_server.py --custom-fastmcp-settings
```

2. In another terminal, run the client:

```bash
uv run client.py
```
uv run client.py

# Optionally, run with the example custom FastMCP settings
uv run client.py --custom-fastmcp-settings
```

## Receiving Server Logs in the Client

# Optionally, run with the example custom FastMCP settings
uv run client.py --custom-fastmcp-settings
```
The server advertises the `logging` capability (via `logging/setLevel`) and forwards its structured logs upstream using `notifications/message`. To receive these logs in a client session, pass a `logging_callback` when constructing the client session and set the desired level:

```python
from datetime import timedelta
from anyio.streams.memory import MemoryObjectReceiveStream, MemoryObjectSendStream
from mcp import ClientSession
from mcp.types import LoggingMessageNotificationParams
from mcp_agent.mcp.mcp_agent_client_session import MCPAgentClientSession

async def on_server_log(params: LoggingMessageNotificationParams) -> None:
print(f"[SERVER LOG] [{params.level.upper()}] [{params.logger}] {params.data}")

def make_session(read_stream: MemoryObjectReceiveStream,
write_stream: MemoryObjectSendStream,
read_timeout_seconds: timedelta | None) -> ClientSession:
return MCPAgentClientSession(
read_stream=read_stream,
write_stream=write_stream,
read_timeout_seconds=read_timeout_seconds,
logging_callback=on_server_log,
)

# Later, when connecting via gen_client(..., client_session_factory=make_session)
# you can request the minimum server log level:
# await server.set_logging_level("info")
```

The example client (`client.py`) demonstrates this end-to-end: it registers a logging callback and calls `set_logging_level("info")` so logs from the server appear in the client's console.

## MCP Clients

Expand All @@ -116,7 +148,7 @@ like any other MCP server.

You can inspect and test the server using [MCP Inspector](https://github.com/modelcontextprotocol/inspector):

```bash
```
npx @modelcontextprotocol/inspector \
uv \
--directory /path/to/mcp-agent/examples/mcp_agent_server/asyncio \
Expand All @@ -138,41 +170,41 @@ To use this server with Claude Desktop:

2. Add a new server configuration:

```json
"basic-agent-server": {
"command": "/path/to/uv",
"args": [
"--directory",
"/path/to/mcp-agent/examples/mcp_agent_server/asyncio",
"run",
"basic_agent_server.py"
]
}
```
```json
"basic-agent-server": {
"command": "/path/to/uv",
"args": [
"--directory",
"/path/to/mcp-agent/examples/mcp_agent_server/asyncio",
"run",
"basic_agent_server.py"
]
}
```

3. Restart Claude Desktop, and you'll see the server available in the tool drawer

4. (**claude desktop workaround**) Update `mcp_agent.config.yaml` file with the full paths to npx/uvx on your system:

Find the full paths to `uvx` and `npx` on your system:

```bash
which uvx
which npx
```

Update the `mcp_agent.config.yaml` file with these paths:

```yaml
mcp:
servers:
fetch:
command: "/full/path/to/uvx" # Replace with your path
args: ["mcp-server-fetch"]
filesystem:
command: "/full/path/to/npx" # Replace with your path
args: ["-y", "@modelcontextprotocol/server-filesystem"]
```
Find the full paths to `uvx` and `npx` on your system:

```
which uvx
which npx
```

Update the `mcp_agent.config.yaml` file with these paths:

```yaml
mcp:
servers:
fetch:
command: "/full/path/to/uvx" # Replace with your path
args: ["mcp-server-fetch"]
filesystem:
command: "/full/path/to/npx" # Replace with your path
args: ["-y", "@modelcontextprotocol/server-filesystem"]
```

## Code Structure

Expand Down
Loading
Loading