main.py•2.38 kB
import asyncio
import os
from pathlib import Path
from mcp.server.fastmcp import FastMCP
from mcp.types import TextContent
mcp = FastMCP("shellserver")
async def _run_command(command: str) -> TextContent:
trimmed_command = command.strip()
if not trimmed_command:
return TextContent(type="text", text="Error: provide a non-empty command.")
process = await asyncio.create_subprocess_shell(
trimmed_command,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
)
stdout_data, stderr_data = await process.communicate()
if process.returncode != 0:
error_output = stderr_data.decode("utf-8", errors="ignore").strip()
message = error_output or f"Command exited with {process.returncode}."
return TextContent(type="text", text=f"Error: {message}")
stdout_text = stdout_data.decode("utf-8", errors="ignore").strip()
return TextContent(type="text", text=stdout_text or "Command completed with no output.")
@mcp.tool("terminal")
async def terminal_tool(command: str) -> list[TextContent]:
result = await _run_command(command)
return [result]
def _resolve_desktop_mcpreadme() -> Path:
one_drive = os.environ.get("OneDrive")
if one_drive:
candidate = Path(one_drive) / "Desktop" / "mcpreadme.md"
if candidate.exists():
return candidate
home = Path.home()
# Fallbacks commonly seen on Windows + OneDrive setups
candidates = [
home / "OneDrive" / "Desktop" / "mcpreadme.md",
home / "Desktop" / "mcpreadme.md",
]
for path in candidates:
if path.exists():
return path
# Default to OneDrive Desktop path even if missing, error will be shown on read
return (Path(one_drive) / "Desktop" / "mcpreadme.md") if one_drive else (home / "OneDrive" / "Desktop" / "mcpreadme.md")
@mcp.resource("mcpreadme://desktop")
def mcpreadme_desktop() -> str:
path = _resolve_desktop_mcpreadme()
try:
return path.read_text(encoding="utf-8", errors="ignore")
except FileNotFoundError:
return f"Error: file not found at {path}"
except PermissionError:
return f"Error: permission denied reading {path}"
except OSError as exc:
return f"Error: failed reading {path}: {exc}"
def main() -> None:
mcp.run()
if __name__ == "__main__":
main()