https://github.com/dynstat/agents-mcp-clients
A working example of your own agents from the scratch and using it with the mcp servers from scratch
https://github.com/dynstat/agents-mcp-clients
agents mcp mcp-client mcp-server
Last synced: about 2 months ago
JSON representation
A working example of your own agents from the scratch and using it with the mcp servers from scratch
- Host: GitHub
- URL: https://github.com/dynstat/agents-mcp-clients
- Owner: dynstat
- Created: 2025-04-26T20:09:04.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2025-05-04T17:22:49.000Z (about 1 year ago)
- Last Synced: 2026-04-26T01:32:07.161Z (about 2 months ago)
- Topics: agents, mcp, mcp-client, mcp-server
- Language: Python
- Homepage:
- Size: 56.6 KB
- Stars: 0
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
- awesome-mcp-servers - **agents-mcp-clients** - A working example of your own agents from the scratch and using it with the mcp servers from scratch `file` `http` `git` `github` `python` `pip install git+https://github.com/dynstat/agents-mcp-clients` (🔧 Utilities)
README
# MCP File Operations Agent
A simple Model Context Protocol (MCP) implementation providing file system operations through a server-client architecture.
## Components
- **file_agent_server.py**: MCP server exposing file system operations as tools
- **file_agent_client.py**: Client implementation using Google's Gemini API
## Features
- Read file contents
- Write content to files
- List directory contents
## Requirements
- Python ≥3.12
- `mcp[cli]>=1.6.0`
- `google-genai>=1.12.1`
- `python-dotenv`
## Setup
1. Install dependencies: `pip install -e .`
2. Create a `.env` file with your API keys (see `.env-sample`)
3. Run server: `python file_agent_server.py`
4. Run client: `python file_agent_client.py`
5. For SSE example: `python sse_echo.py`
## Implementing MCP Agents
Here's how to set up MCP servers and clients using different transport layers:
### Stdio Transport (Standard Input/Output)
Stdio transport is useful for local inter-process communication, often used when a client application spawns a server process.
**Server (`file_agent_server.py` example):**
```python
# file_agent_server.py
from mcp.server.fastmcp import FastMCP
import os # Example tool dependencies
# 1. Create a FastMCP server instance
file_agent = FastMCP("File Operations Agent")
# 2. Define tools using the @file_agent.tool() decorator
@file_agent.tool()
def read_file(file_path: str) -> str:
"""Read the contents of a file."""
try:
with open(file_path, 'r', encoding='utf-8') as f:
return f.read()
except Exception as e:
return f"Error reading file: {str(e)}"
# Add other tools (write_file, list_directory) similarly...
# 3. Run the server (automatically uses Stdio)
if __name__ == "__main__":
file_agent.run()
```
**Client (`file_agent_client.py` example):**
```python
# file_agent_client.py
import asyncio
from mcp import ClientSession, StdioServerParameters, types as mcp_types
from mcp.client.stdio import stdio_client
# 1. Define server parameters (how to start the server process)
server_params = StdioServerParameters(
command="python", # Command to execute
args=["file_agent_server.py"], # Arguments for the command
)
async def run_client():
try:
# 2. Use stdio_client to start the server process and get read/write streams
async with stdio_client(server_params) as (read, write):
print("stdio_client connected.")
# 3. Create a ClientSession with the streams
# Optionally pass a sampling_callback for agent logic
async with ClientSession(read, write) as session:
print("ClientSession created.")
# 4. Initialize the connection
await session.initialize()
print("Session initialized.")
# 5. List available tools
list_tools_result = await session.list_tools()
print("Available tools:", list_tools_result.tools)
# 6. Call a tool
call_result = await session.call_tool("read_file", {"file_path": "README.md"})
if call_result.content and isinstance(call_result.content[0], mcp_types.TextContent):
print("Read file result:", call_result.content[0].text[:100] + "...")
else:
print("Error or unexpected result:", call_result)
except Exception as e:
print(f"Client error: {e}")
if __name__ == "__main__":
asyncio.run(run_client())
```
### SSE Transport (Server-Sent Events)
SSE transport uses HTTP for communication, suitable for web-based or network-based interactions.
**Server (`sse_echo.py` example):**
```python
# sse_server_example.py (based on sse_echo.py)
import asyncio
from mcp import FastMCP
from mcp.types import TextContent # Example type import
# Define connection details
HOST = "127.0.0.1"
PORT = 8765
SSE_PATH = "/sse" # The HTTP path for the SSE endpoint
# 1. Instantiate FastMCP with SSE configuration
app = FastMCP(name="SSE Echo Server", host=HOST, port=PORT, sse_path=SSE_PATH)
# 2. Define tools as usual
@app.tool()
async def echo(text: str) -> list[TextContent]:
"""Echoes the input text back."""
print(f"Server received: {text}")
return [TextContent(type="text", text=f"Echo: {text}")]
# 3. Run the server asynchronously using run_sse_async
async def run_server():
print(f"Starting SSE server on http://{HOST}:{PORT}{SSE_PATH}")
await app.run_sse_async()
if __name__ == "__main__":
asyncio.run(run_server())
```
**Client (`sse_echo.py` example):**
```python
# sse_client_example.py (based on sse_echo.py)
import asyncio
from mcp import ClientSession
from mcp.client.sse import sse_client # SSE specific client helper
from mcp.types import TextContent, CallToolResult # Example type imports
# Server connection details (must match the server)
HOST = "127.0.0.1"
PORT = 8765
SSE_PATH = "/sse"
async def run_client():
server_url = f"http://{HOST}:{PORT}{SSE_PATH}"
print(f"Client connecting to {server_url}")
try:
# Allow server time to start (in combined demo scripts)
await asyncio.sleep(1)
# 1. Use sse_client helper to connect to the server URL
async with sse_client(url=server_url) as (read, write):
print("sse_client connected.")
# 2. Create ClientSession with the read/write streams
async with ClientSession(read, write) as session:
print("ClientSession created.")
# 3. Initialize the session
await session.initialize()
print("Session initialized.")
# 4. Call a tool
message = "Hello via SSE!"
response: CallToolResult = await session.call_tool("echo", {"text": message})
# Process response
if response.content and isinstance(response.content[0], TextContent):
print(f"Client received: {response.content[0].text}")
else:
print(f"Client received unexpected response: {response}")
except Exception as e:
print(f"Client error: {e}")
if __name__ == "__main__":
asyncio.run(run_client())
```
## Cursor IDE Integration (sample example)
Configure in `.cursor/mcp.json`:
```json
{
"mcpServers": {
"File Operations Agent": {
"command": "python",
"args": ["path/to/file_agent_server.py"],
"env": {}
}
}
}
```