https://github.com/promptmesh/easymcp
A high performance MCP client sdk for python
https://github.com/promptmesh/easymcp
ai client mcp mcp-client modelcontextprotocol python
Last synced: 3 days ago
JSON representation
A high performance MCP client sdk for python
- Host: GitHub
- URL: https://github.com/promptmesh/easymcp
- Owner: promptmesh
- License: mit
- Created: 2025-03-12T11:12:31.000Z (about 2 months ago)
- Default Branch: master
- Last Pushed: 2025-04-08T23:59:48.000Z (29 days ago)
- Last Synced: 2025-05-04T23:40:29.285Z (3 days ago)
- Topics: ai, client, mcp, mcp-client, modelcontextprotocol, python
- Language: Python
- Homepage: https://easymcp.promptmesh.io/
- Size: 888 KB
- Stars: 15
- Watchers: 2
- Forks: 1
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
- awesome-mcp-devtools - easymcp - A high level asyncio native client SDK with native support for namespaced servers and caching. (SDKs / Python)
- awesome-mcp-devtools - easymcp - A high level asyncio native client SDK with native support for namespaced servers and caching. (SDKs / Python)
README
# EasyMCP
EasyMCP is a complete rewrite of the model context protocol (MCP) in Python.
## Installation
```bash
uv add easymcp
```## Usage
The high level API exposes a ClientManager class that can be used to manage multiple MCP servers.
```python
import asyncio
from easymcp.client.ClientManager import ClientManager
from easymcp.client.transports.stdio import StdioServerParametersmgr = ClientManager()
searxng = StdioServerParameters(
command="uvx",
args=["mcp-searxng"],
)timeserver = StdioServerParameters(
command="uvx",
args=["mcp-timeserver"],
)servers = {
"searxng": searxng,
"timeserver": timeserver,
}async def main():
# initialize the client manager
await mgr.init(servers=servers)# list servers
print(mgr.list_servers())# remove a server
await mgr.remove_server("searxng")# add a server
await mgr.add_server("searxng", searxng)# list tools - these are namespaced by server name automatically
# {server name}.{tool name}
print(await mgr.list_tools())# call tool
print(await mgr.call_tool("timeserver.get-current-time", {}))# list resources - these are namespaced by server name automatically
# mcp-{server name}+{resource uri}
print(await mgr.list_resources())# read resource
print(await mgr.read_resource("mcp-timeserver+datetime://Africa/Algiers/now"))await asyncio.Future()
asyncio.run(main())
```## Core Features
- list tools/resources/prompts caching out of the box
- automatic cache invalidation on tool/resource/prompt change notifications
- out of the box support for parallel requests to servers
- full lifecycle management of servers
- dynamic server addition/removal
- namespaced tools/resources/prompts
- lightweight asyncio native implementation## Why namespace tools?
Namespaced tools remove need to perform a lookup to find the correct tool. This means:
- faster tool calls
- tool calls can be routed across many MCP hosts at scale
- mcp servers do not need globally unique tool names## Why namespace resources?
Resources are namespaced in a way that makes it easy to make a resource URI to a specific server. You can:
- check if a URL needs to be resolved via mcp by checking if it starts with `mcp`
- check what server to resolve the URI with
- ingest resources into a search system like elastic search without having to store metadata about the server
- completely eliminate the need to map URIs to servers via a database or lookup table## Comparison of classes to other MCP libraries
| **easyMCP** | **modelcontextprotocol/python-sdk** | |
| -------------- | ----------------------------------- | ---------------------------- |
| ClientManager | | manages multiple MCP servers |
| ClientSession | ClientSession | manages a single MCP server |
| StdioTransport | stdio_client | raw subprocess transport |## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.