#!/usr/bin/env python3 """Lightweight stdio Model Context Protocol (MCP) server for project inspection. Zero-dependency standard library implementation compliant with MCP JSON-RPC specifications. """ import json import os import subprocess import sys def read_message(): line = sys.stdin.readline() if not line: return None return json.loads(line) def write_message(obj): sys.stdout.write(json.dumps(obj) + "\n") sys.stdout.flush() def tool_inspect_health(args): service = args.get("service") try: cmd = ["docker", "compose", "ps", "--format", "json"] proc = subprocess.run(cmd, capture_output=True, text=True, check=False) if proc.returncode == 0: output = proc.stdout.strip() return { "status": "success", "containers": output or "No active containers", } return { "status": "unknown", "message": "Docker Compose not running or available", } except Exception as e: return {"status": "error", "error": str(e)} def tool_inspect_contract(args): contract_path = os.path.join(os.getcwd(), "contracts", "openapi.yaml") if not os.path.exists(contract_path): return { "status": "missing", "message": "No contracts/openapi.yaml found in project root", } try: with open(contract_path, "r", encoding="utf-8") as f: content = f.read(2048) # Sample first 2KB return { "status": "found", "path": "contracts/openapi.yaml", "preview": content, } except Exception as e: return {"status": "error", "error": str(e)} def main(): while True: try: msg = read_message() if msg is None: break req_id = msg.get("id") method = msg.get("method") params = msg.get("params", {}) if method == "initialize": write_message({ "jsonrpc": "2.0", "id": req_id, "result": { "protocolVersion": "2024-11-05", "capabilities": {"tools": {}}, "serverInfo": {"name": "project-mcp-server", "version": "1.0.0"}, }, }) elif method == "tools/list": write_message({ "jsonrpc": "2.0", "id": req_id, "result": { "tools": [ { "name": "inspect_project_health", "description": ( "Checks the status of project containers and API" " endpoints" ), "inputSchema": { "type": "object", "properties": { "service": { "type": "string", "description": ( "Optional specific service to check" ), } }, }, }, { "name": "inspect_openapi_contract", "description": ( "Reads and summarizes endpoints from" " contracts/openapi.yaml" ), "inputSchema": {"type": "object", "properties": {}}, }, ] }, }) elif method == "tools/call": tool_name = params.get("name") arguments = params.get("arguments", {}) if tool_name == "inspect_project_health": res = tool_inspect_health(arguments) elif tool_name == "inspect_openapi_contract": res = tool_inspect_contract(arguments) else: res = {"error": f"Unknown tool: {tool_name}"} write_message({ "jsonrpc": "2.0", "id": req_id, "result": { "content": [{"type": "text", "text": json.dumps(res, indent=2)}] }, }) elif method == "ping": write_message({"jsonrpc": "2.0", "id": req_id, "result": {}}) else: write_message({ "jsonrpc": "2.0", "id": req_id, "error": {"code": -32601, "message": f"Method {method} not found"}, }) except Exception as ex: write_message({ "jsonrpc": "2.0", "id": None, "error": {"code": -32603, "message": str(ex)}, }) if __name__ == "__main__": main()