init commit, added server and client
This commit is contained in:
39
mcpServer/.dockerignore
Normal file
39
mcpServer/.dockerignore
Normal file
@@ -0,0 +1,39 @@
|
||||
# Python
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
*.so
|
||||
.Python
|
||||
*.egg-info/
|
||||
dist/
|
||||
build/
|
||||
wheels/
|
||||
|
||||
# Virtual environments
|
||||
venv/
|
||||
.venv/
|
||||
env/
|
||||
ENV/
|
||||
|
||||
# Git
|
||||
.git/
|
||||
.gitignore
|
||||
|
||||
# IDE
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Docker
|
||||
Dockerfile
|
||||
.dockerignore
|
||||
docker-compose.yml
|
||||
|
||||
# Documentation
|
||||
README.md
|
||||
27
mcpServer/Dockerfile
Normal file
27
mcpServer/Dockerfile
Normal file
@@ -0,0 +1,27 @@
|
||||
# Use Python 3.12 slim image
|
||||
FROM python:3.12-slim
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
|
||||
# Set environment variables
|
||||
ENV PYTHONUNBUFFERED=1 \
|
||||
PYTHONDONTWRITEBYTECODE=1 \
|
||||
FASTMCP_HOST=0.0.0.0 \
|
||||
FASTMCP_PORT=8000
|
||||
|
||||
# Copy requirements first for better caching
|
||||
COPY requirements.txt .
|
||||
|
||||
# Install dependencies
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# Copy application code
|
||||
COPY modules/ ./modules/
|
||||
COPY main.py .
|
||||
|
||||
# Expose port 8000 for the MCP server
|
||||
EXPOSE 8000
|
||||
|
||||
# Run the MCP server
|
||||
CMD ["python", "main.py"]
|
||||
11
mcpServer/docker-compose.yml
Normal file
11
mcpServer/docker-compose.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
services:
|
||||
mcp-server:
|
||||
build: .
|
||||
container_name: cariddi-mcp-server
|
||||
ports:
|
||||
- "8000:8000"
|
||||
environment:
|
||||
- PYTHONUNBUFFERED=1
|
||||
- FASTMCP_HOST=0.0.0.0
|
||||
- FASTMCP_PORT=8000
|
||||
restart: unless-stopped
|
||||
41
mcpServer/main.py
Normal file
41
mcpServer/main.py
Normal file
@@ -0,0 +1,41 @@
|
||||
import os
|
||||
from mcp.server.fastmcp import FastMCP
|
||||
from modules.filesystem import internal_listFiles, internal_readFile, internal_writeFile, internal_executeCommand, internal_writePythonFile
|
||||
|
||||
mcpServer = FastMCP(
|
||||
"Cariddi",
|
||||
host=os.getenv("FASTMCP_HOST", os.getenv("MCP_HOST", "0.0.0.0")),
|
||||
port=int(os.getenv("FASTMCP_PORT", os.getenv("MCP_PORT", "8000"))),
|
||||
)
|
||||
|
||||
@mcpServer.tool()
|
||||
def listFiles(path: str) -> list[str]:
|
||||
"""List all files in the given path"""
|
||||
return internal_listFiles(path)
|
||||
|
||||
@mcpServer.tool()
|
||||
def readFile(path: str) -> str:
|
||||
"""Read the contents of a file"""
|
||||
return internal_readFile(path)
|
||||
|
||||
@mcpServer.tool()
|
||||
def writeFile(path: str, content: str) -> bool:
|
||||
"""Write the contents of a file"""
|
||||
return internal_writeFile(path, content)
|
||||
|
||||
@mcpServer.tool()
|
||||
def executeCommand(command: str) -> dict:
|
||||
"""Execute a command"""
|
||||
return internal_executeCommand(command)
|
||||
|
||||
@mcpServer.tool()
|
||||
def writePythonFile(path: str, content: str) -> str:
|
||||
"""Write a Python file handling streaming and escape characters correctly."""
|
||||
return internal_writePythonFile(path, content)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
mcpServer.run(transport="streamable-http")
|
||||
except KeyboardInterrupt:
|
||||
print("Server stopped by user")
|
||||
7
mcpServer/mcp.json
Normal file
7
mcpServer/mcp.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"mcpServers": {
|
||||
"cariddi": {
|
||||
"url": "http://localhost:8000/mcp"
|
||||
}
|
||||
}
|
||||
}
|
||||
61
mcpServer/modules/filesystem.py
Normal file
61
mcpServer/modules/filesystem.py
Normal file
@@ -0,0 +1,61 @@
|
||||
import os
|
||||
from typing import List
|
||||
import subprocess
|
||||
def internal_listFiles(path: str) -> List[str]:
|
||||
"""List all files in the given path"""
|
||||
if os.path.exists(path) and os.path.isdir(path):
|
||||
result = os.listdir(path)
|
||||
return result
|
||||
print(f"Path does not exist or is not a directory: {path}")
|
||||
return []
|
||||
|
||||
def internal_readFile(path: str) -> str:
|
||||
"""Read the contents of a file"""
|
||||
if os.path.exists(path) and os.path.isfile(path):
|
||||
try:
|
||||
with open(path, "r", encoding="utf-8") as f:
|
||||
content = f.read()
|
||||
return content
|
||||
except Exception as e:
|
||||
error_msg = f"Error reading file: {str(e)}"
|
||||
return error_msg
|
||||
return ""
|
||||
|
||||
def internal_writeFile(path: str, content: str) -> bool:
|
||||
"""Write the contents of a file"""
|
||||
try:
|
||||
with open(path, "w", encoding="utf-8") as f:
|
||||
f.write(content)
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"Error writing file: {str(e)}")
|
||||
return False
|
||||
|
||||
def internal_executeCommand(command: str) -> str:
|
||||
"""Execute a command"""
|
||||
try:
|
||||
result = subprocess.run(command, shell=True, capture_output=True, text=True)
|
||||
output = {
|
||||
"stderr": result.stderr,
|
||||
"stdout": result.stdout,
|
||||
"returncode": result.returncode
|
||||
}
|
||||
return output
|
||||
except Exception as e:
|
||||
print(f"Error executing command: {str(e)}")
|
||||
return ""
|
||||
|
||||
def internal_writePythonFile(path: str, content: str) -> str:
|
||||
"""Write a Python file handling streaming and escape characters correctly."""
|
||||
content = content.encode('utf-8').decode('unicode_escape') if '\\n' in content else content
|
||||
if "```python" in content:
|
||||
content = content.split("```python")[1].split("```")[0].strip()
|
||||
elif "```" in content:
|
||||
content = content.split("```")[1].split("```")[0].strip()
|
||||
|
||||
try:
|
||||
with open(path, "w", encoding="utf-8") as f:
|
||||
f.write(content)
|
||||
return f"File saved correctly in {path}"
|
||||
except Exception as e:
|
||||
return f"Error: {str(e)}"
|
||||
1
mcpServer/requirements.txt
Normal file
1
mcpServer/requirements.txt
Normal file
@@ -0,0 +1 @@
|
||||
mcp[cli]>=1.25.0
|
||||
Reference in New Issue
Block a user