Skip to content

feat(mcp): add a feature to start MCP server from config file #623

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

JackYPCOnline
Copy link
Contributor

@JackYPCOnline JackYPCOnline commented Aug 6, 2025

Description

add a feature to start MCP server from config file

Anthropic MCP Server Config Examples
MCP TransportType Source Code

For STDIO, configuration file should like, only name, command is required:

{
  "mcpServers": {
    "weather": {
      "command": "uv",
      "args": [
        "--directory",
        "/ABSOLUTE/PATH/TO/PARENT/FOLDER/weather",
        "run",
        "weather.py"
      ],
     "env":{},
     "cwd": "/home/xyz/mcp-servers/abc"
    }
  }
}

For Streamable-http, only name, url is required:

  • Http:
 {
  "mcpServers": {
    "local-agent": {
      "transport": "streamable-http",
      "url": "http://localhost:8000/mcp",
      "timeout": 300
    }
  }
}
  • SSE:
 {
  "mcpServers": {
    "local-agent": {
      "transport": "sse",
      "url": "http://localhost:8000/sse",
      "timeout": 300
    }
  }
}

Example:

MCP Server:
from mcp.server import FastMCP

# Create an MCP server
mcp = FastMCP("Calculator Server")

# Define a tool
@mcp.tool(description="Calculator tool which performs calculations")
def calculator(x: int, y: int) -> int:
    return x + y

# Run the server with SSE transport
mcp.run(transport="sse") # or  relpace with streamable-http
#Config file
{
  "mcpServers": {
    "local-agent": {
      "transport": "sse",  # streamable-http
      "url": "http://127.0.0.1:8000/sse", # for streamable-http use mcp
      "timeout": 30000
    }
  }
}

#Use Config
from strands import Agent
from strands.tools.mcp.mcp_from_config import MCPServerConfig

# Load MCP server configurations from config file
configs = MCPServerConfig.from_config("mcp_config.json")
print(f"Loaded {len(configs)} server configs")

# Connect to the first server (local-agent)
server_config = configs[0]
print(f"Connecting to server: {server_config.name}")
mcp_client = server_config.create_client()

# Test connection and list tools
with mcp_client:
    print("Connected successfully!")
    tools = mcp_client.list_tools_sync()
    print(f"Available tools: {[tool.tool_name for tool in tools]}")
    
    # Create agent and test calculator tool
    agent = Agent(tools=tools)
    result = agent("add 5 and 3")
    print(f"Agent result: {result}")

Output:
Loaded 1 server configs
Connecting to server: local-agent
Connected successfully!
Available tools: ['calculator']
I'll add 5 and 3 for you using the calculator.
Tool #1: calculator
The result of adding 5 and 3 is 8.Agent result: The result of adding 5 and 3 is 8.

Related Issues

Documentation PR

Type of Change

Bug fix
New feature
Breaking change
Documentation update
Other (please describe):

Testing

How have you tested the change? Verify that the changes do not break functionality or introduce warnings in consuming repositories: agents-docs, agents-tools, agents-cli
I ran unit tests and also ran an example from Anthropic

  • [ x] I ran hatch run prepare

Checklist

  • [ x] I have read the CONTRIBUTING document
  • [ x] I have added any necessary tests that prove my fix is effective or my feature works
  • [ x] I have updated the documentation accordingly
  • [ x] I have added an appropriate example to the documentation to outline the feature, or no new docs are needed
  • [ x] My changes generate no new warnings
  • [x ] Any dependent changes have been merged and published

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@mkmeral
Copy link
Contributor

mkmeral commented Aug 7, 2025

Can we also add this to agent-builder? :)

@JackYPCOnline
Copy link
Contributor Author

Agent-builder is specific for building an agent? This feature is to start a MCP ?

server_params = StdioServerParameters(command=self.command, args=self.args, env=self.env)
return stdio_client(server_params)

return MCPClient(transport_callable)
Copy link
Member

Choose a reason for hiding this comment

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

Is this something that should live in the SDK - e.g. should Strands consumers be able to load MCP client from file? @dbschmigelski is this on your roadmap?

return str(config_path)


class TestMCPTransportType:
Copy link
Member

Choose a reason for hiding this comment

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

Switch to top-level methods for tests; AFAIK that's the standard throughout the SDK



class MCPServerConfig:
"""Configuration for an MCP server following MCP standards."""
Copy link
Member

Choose a reason for hiding this comment

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

Is this truly a standard or a De facto standard? If the former, then let's link to the standard, if the latter let's document what the format is (both in code and in our docs) to make it obvious to readers/customers

or server_config.get("transportType")
or server_config.get("transport_type")
)
if raw_transport is None and "url" in server_config:
Copy link
Member

Choose a reason for hiding this comment

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

Are there any other config formats that support streamable http or sse? If so, do they use the same logic for deciding on the format? If not, let's make it a hard requirement that you specify the transport type for non stdio formats. I'd rather be safe than sorry.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is prettey standard and firm. url end with SSE is SSE, end with MCP is Http.
eg: https://mcp.intercom.com/mcp | https://mcp.linear.app/sse
Stdio won't have url but must have command

Copy link
Member

Choose a reason for hiding this comment

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

We should have an e2e integ test for this as well.

And we should have a docs PR that shows how this is to be used? The example of how it will be used should also be in the PR description for easy review

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, sir. I will update PR accordingly.
Doc example in separate PR.

return []

@classmethod
def _parse_mcp_servers_format(cls, mcp_servers: Dict[str, Dict]) -> List["MCPServerConfig"]:
Copy link
Member

Choose a reason for hiding this comment

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

Are we reading and validating json here? If so, would it make sense to model this using something like pydantic, and then use pydantic to validate the shape?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's a good idea but I think the only MUST is command for STDIO and url for Streamable-HTTP(sse/http), so we could keep it simple here.

@JackYPCOnline
Copy link
Contributor Author

JackYPCOnline commented Aug 14, 2025

Team deceided that we will have new MCP interface in next couple weeks. Will follow up this PR after release.
Notes: configuration pattern should follow Q CLI

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants