""" MCP (Model Context Protocol) API endpoints for CQA Test Application """ import json import logging from flask import Blueprint, request, jsonify from lib.jira_client import JiraClient from common.context import api_function logger = logging.getLogger(__name__) # Create Blueprint for MCP routes bp = Blueprint("mcp", __name__, url_prefix="/api/mcp") # Initialize Jira client for MCP tools jira_client = JiraClient() @bp.route("/tools", methods=["GET"]) def list_tools(): """List available MCP tools""" tools = [ { "name": "jira_list_projects", "description": "List all accessible Jira projects", "input_schema": { "type": "object", "properties": {}, "required": [] } }, { "name": "jira_search_issues", "description": "Search Jira issues using JQL query", "input_schema": { "type": "object", "properties": { "jql": { "type": "string", "description": "JQL (Jira Query Language) query string" }, "max_results": { "type": "integer", "description": "Maximum number of results to return (default: 50)", "default": 50 } }, "required": ["jql"] } }, { "name": "jira_get_issue", "description": "Get detailed information about a specific Jira issue", "input_schema": { "type": "object", "properties": { "issue_key": { "type": "string", "description": "Jira issue key (e.g., PROJ-123)" } }, "required": ["issue_key"] } }, { "name": "jira_get_comments", "description": "Get comments for a specific Jira issue", "input_schema": { "type": "object", "properties": { "issue_key": { "type": "string", "description": "Jira issue key (e.g., PROJ-123)" } }, "required": ["issue_key"] } }, { "name": "jira_create_issue", "description": "Create a new Jira issue", "input_schema": { "type": "object", "properties": { "project_key": { "type": "string", "description": "Jira project key" }, "summary": { "type": "string", "description": "Issue summary/title" }, "description": { "type": "string", "description": "Issue description" }, "issue_type": { "type": "string", "description": "Issue type (e.g., Task, Bug, Story)", "default": "Task" }, "priority": { "type": "string", "description": "Issue priority (e.g., High, Medium, Low)", "default": "Medium" } }, "required": ["project_key", "summary", "description"] } }, { "name": "run_command", "description": "Execute a system command", "input_schema": { "type": "object", "properties": { "command": { "type": "string", "description": "Command to execute" } }, "required": ["command"] } }, { "name": "network_test", "description": "Run network performance test using iperf3", "input_schema": { "type": "object", "properties": { "server": { "type": "string", "description": "Target server for iperf test" }, "port": { "type": "integer", "description": "Port number (default: 5201)", "default": 5201 }, "duration": { "type": "integer", "description": "Test duration in seconds (default: 10)", "default": 10 } }, "required": ["server"] } } ] return api_function.make_common_response( request=request, res_msg={"tools": tools, "count": len(tools)} ) @bp.route("/execute", methods=["POST"]) def execute_tool(): """Execute an MCP tool""" try: data = request.get_json() if not data or 'tool_name' not in data: return api_function.make_common_response( request=request, res_msg={"error": "tool_name is required"}, res_code=400 ) tool_name = data['tool_name'] arguments = data.get('arguments', {}) # Execute Jira tools if tool_name == "jira_list_projects": result = jira_client.list_projects() elif tool_name == "jira_search_issues": jql = arguments.get("jql", "") max_results = arguments.get("max_results", 50) result = jira_client.search_issues(jql, max_results) elif tool_name == "jira_get_issue": issue_key = arguments.get("issue_key", "") result = jira_client.get_issue(issue_key) elif tool_name == "jira_get_comments": issue_key = arguments.get("issue_key", "") result = jira_client.get_issue_comments(issue_key) elif tool_name == "jira_create_issue": project_key = arguments.get("project_key", "") summary = arguments.get("summary", "") description = arguments.get("description", "") issue_type = arguments.get("issue_type", "Task") priority = arguments.get("priority", "Medium") result = jira_client.create_issue( project_key, summary, description, issue_type, priority ) # Execute system tools elif tool_name == "run_command": command = arguments.get("command", "") # Use existing run_cmd functionality from flask_restful import reqparse mock_request = type('MockRequest', (), { 'get_json': lambda: {'cmd': command}, 'method': 'POST', 'url': '/mcp/execute', 'headers': request.headers })() result = api_function.run_cmd(reqparse=reqparse, request=mock_request) elif tool_name == "network_test": server = arguments.get("server", "") port = arguments.get("port", 5201) duration = arguments.get("duration", 10) # Use existing iperf functionality from flask_restful import reqparse mock_request = type('MockRequest', (), { 'get_json': lambda: { 'server': server, 'port': port, 'duration': duration }, 'method': 'POST', 'url': '/mcp/execute', 'headers': request.headers })() result = api_function.run_iperf(reqparse=reqparse, request=mock_request) else: result = {"error": f"Unknown tool: {tool_name}"} return api_function.make_common_response( request=request, res_msg={"tool_result": result} ) except Exception as e: logger.error(f"Error executing MCP tool: {e}") return api_function.make_common_response( request=request, res_msg={"error": str(e)}, res_code=500 ) @bp.route("/server/info", methods=["GET"]) def server_info(): """Get MCP server information""" return api_function.make_common_response( request=request, res_msg={ "server_name": "cqa-test-app", "server_version": "1.0.0", "capabilities": { "tools": True, "resources": False, "prompts": False }, "jira_connected": jira_client.is_connected() } )