Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
9 changes: 8 additions & 1 deletion examples/mcp_agent_server/asyncio/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ https://github.com/user-attachments/assets/f651af86-222d-4df0-8241-616414df66e4

- Creating workflows with the `Workflow` base class
- Registering workflows with an `MCPApp`
- Exposing workflows as MCP tools using `create_mcp_server_for_app`
- Exposing workflows as MCP tools using `create_mcp_server_for_app`, optionally using custom FastMCP settings
- Connecting to an MCP server using `gen_client`
- Running workflows remotely and monitoring their status

Expand Down Expand Up @@ -93,11 +93,18 @@ You can also run the server and client separately:

```bash
uv run basic_agent_server.py

# 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

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

## MCP Clients
Expand Down
21 changes: 19 additions & 2 deletions examples/mcp_agent_server/asyncio/basic_agent_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
3. Declarative agent configuration using FastMCPApp decorators
"""

import argparse
import asyncio
import os
import logging
Expand Down Expand Up @@ -169,6 +170,15 @@ async def run(self, input: str) -> WorkflowResult[str]:


async def main():
parser = argparse.ArgumentParser()
parser.add_argument(
"--custom-fastmcp-settings",
action="store_true",
help="Enable custom FastMCP settings for the server",
)
args = parser.parse_args()
use_custom_fastmcp_settings = args.custom_fastmcp_settings

async with app.run() as agent_app:
# Add the current directory to the filesystem server's args if needed
context = agent_app.context
Expand All @@ -182,8 +192,15 @@ async def main():
for workflow_id in agent_app.workflows:
logger.info(f" - {workflow_id}")

# Create the MCP server that exposes both workflows and agent configurations
mcp_server = create_mcp_server_for_app(agent_app)
# Create the MCP server that exposes both workflows and agent configurations,
# optionally using custom FastMCP settings
fast_mcp_settings = (
{"host": "localhost", "port": 8001, "debug": True, "log_level": "DEBUG"}
if use_custom_fastmcp_settings
else None
)
mcp_server = create_mcp_server_for_app(agent_app, fast_mcp_settings)
logger.info(f"MCP Server settings: {mcp_server.settings}")

# Add custom tool to get token usage for a workflow
@mcp_server.tool(
Expand Down
18 changes: 17 additions & 1 deletion examples/mcp_agent_server/asyncio/client.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import argparse
import asyncio
import json
import time
Expand All @@ -11,6 +12,15 @@


async def main():
parser = argparse.ArgumentParser()
parser.add_argument(
"--custom-fastmcp-settings",
action="store_true",
help="Enable custom FastMCP settings for the server",
)
args = parser.parse_args()
use_custom_fastmcp_settings = args.custom_fastmcp_settings

# Create MCPApp to get the server registry
app = MCPApp(name="workflow_mcp_client")
async with app.run() as client_app:
Expand All @@ -21,11 +31,17 @@ async def main():
logger.info("Connecting to workflow server...")

# Override the server configuration to point to our local script
run_server_args = ["run", "basic_agent_server.py"]
if use_custom_fastmcp_settings:
logger.info("Using custom FastMCP settings for the server.")
run_server_args += ["--custom-fastmcp-settings"]
else:
logger.info("Using default FastMCP settings for the server.")
context.server_registry.registry["basic_agent_server"] = MCPServerSettings(
name="basic_agent_server",
description="Local workflow server running the basic agent example",
command="uv",
args=["run", "basic_agent_server.py"],
args=run_server_args,
)

# Connect to the workflow server
Expand Down
6 changes: 5 additions & 1 deletion src/mcp_agent/server/app_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,15 @@ def workflow_registry(self) -> WorkflowRegistry:
return self.context.workflow_registry


def create_mcp_server_for_app(app: MCPApp) -> FastMCP:
def create_mcp_server_for_app(
app: MCPApp, settings: dict[str, Any] | None = None
) -> FastMCP:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should we do this simply as kwargs

Suggested change
def create_mcp_server_for_app(
app: MCPApp, settings: dict[str, Any] | None = None
) -> FastMCP:
def create_mcp_server_for_app(
app: MCPApp, **kwargs: Any
) -> FastMCP:

Copy link
Member Author

Choose a reason for hiding this comment

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

That works, too. Updated

"""
Create an MCP server for a given MCPApp instance.

Args:
app: The MCPApp instance to create a server for
settings: Optional FastMCP Settings dict to configure the server.

Returns:
A configured FastMCP server instance
Expand Down Expand Up @@ -119,6 +122,7 @@ async def app_specific_lifespan(mcp: FastMCP) -> AsyncIterator[ServerContext]:
# or use the MCPApp's description if available.
instructions=f"MCP server exposing {app.name} workflows and agents. Description: {app.description}",
lifespan=app_specific_lifespan,
**settings or {},

This comment was marked as resolved.

)

# region Workflow Tools
Expand Down
Loading