# MCP (Model Context Protocol) Modules This directory contains FastMCP-based implementations for different services. ## Structure ``` products/mcp/ ├── __init__.py # Package initialization and module registry ├── jira.py # Jira integration tools (FastMCP) ├── flava_function.py # Flava Functions integration tools (FastMCP) ├── template.py # Template for creating new FastMCP modules └── README.md # This file ``` ## Current Modules ### Jira (`jira.py`) FastMCP-based Jira issue management and project operations: - `jira_list_projects`: List all accessible Jira projects - `jira_search_issues`: Search issues using JQL queries - `jira_get_issue`: Get detailed issue information - `jira_get_comments`: Retrieve issue comments - `jira_create_issue`: Create new issues ### Flava Functions (`flava_function.py`) FastMCP-based Flava Functions API integration for FaaS operations: - `flava_get_functions`: Get list of functions from Flava API - `flava_get_function_details`: Get detailed information for a specific function **Authentication Methods:** 1. **Basic Authentication**: For development and testing (default) - Uses basic headers without authentication tokens 2. **Athenz Authentication**: For production environments (using enhanced `lib/athenz_client.py`) - Requires `FUNC_ACCOUNT_NAME` environment variable - Automatically generates `PROVIDER_DOMAIN` from Flava environment variables - Handles token refresh and certificate-based authentication - Falls back to basic authentication if configuration is incomplete ## Adding New FastMCP Modules 1. **Copy the template**: Start with `template.py` as your base 2. **Rename and customize**: Replace `template` with your service name 3. **Create FastMCP instance**: Initialize your service's FastMCP server 4. **Define tools**: Use `@your_mcp.tool` decorator to register tools 5. **Update package**: Add imports to `__init__.py` ### Example: Adding GitHub module ```python # products/mcp/github.py import logging from fastmcp import FastMCP from github_client import GitHubClient logger = logging.getLogger(__name__) github_client = GitHubClient() # Create FastMCP instance github_mcp = FastMCP("CQA GitHub MCP Server") @github_mcp.tool def github_list_repos(): """List user repositories""" logger.info("Listing GitHub repositories") return github_client.list_repos() def get_github_mcp_server(): """Get the configured GitHub MCP server instance""" return github_mcp ``` ## Benefits of FastMCP - **Simplicity**: No manual JSON-RPC handling required - **Auto-discovery**: Tools are automatically registered and exposed - **Type safety**: Function signatures become MCP tool schemas - **Less boilerplate**: Minimal code compared to manual implementation ## Running the MCP Server The MCP server now uses FastMCP's mount functionality to combine multiple service modules into a single server. ### Standalone ```bash python mcp_server.py ``` ### Tool Naming Convention With the mount approach, tools are prefixed with their service namespace: - **Jira tools**: `jira_jira_list_projects`, `jira_jira_search_issues`, etc. - **Flava Functions tools**: `flava_flava_get_functions`, `flava_flava_get_function_details` ### Docker ```bash docker build -f Dockerfile.mcp -t cqa-mcp-server . docker run -p 8001:8001 cqa-mcp-server ``` ## API Endpoints FastMCP automatically provides: - `POST /mcp`: MCP JSON-RPC protocol endpoint - Standard MCP methods: `initialize`, `tools/list`, `tools/call` ## Environment Variables ### Server Configuration - `MCP_PORT`: Server port (default: 8001) - `MCP_HOST`: Server host (default: 0.0.0.0) ### Jira Configuration (Required) - `JIRA_URL`: Jira server URL (e.g., https://your-domain.atlassian.net) - `JIRA_PERSONAL_TOKEN`: Jira personal access token ### Flava Functions Configuration (Required) - `FLAVA_FUNCTION_BASE_URL`: Flava API base URL (e.g., https://api.flava.example.com) ### Flava Environment Configuration (Auto-generates PROVIDER_DOMAIN) - `FLAVA_PRODUCT`: Product type (e.g., "faas", "paas") (default: "faas") - `FLAVA_ENVIRONMENT`: Environment (e.g., "stage", "prod") (default: "stage") - `FLAVA_PROJECT`: Project name (default: "flava-qa") - **Auto-generated PROVIDER_DOMAIN**: `flava-{FLAVA_PRODUCT}.{FLAVA_ENVIRONMENT}.{FLAVA_PROJECT}` - Example: `flava-faas.stage.flava-qa` ### Athenz Authentication Configuration - Uses fixed certificate paths: `/var/run/athenz/service.key.pem` and `/var/run/athenz/service.cert.pem` - Automatically attempts Athenz authentication when certificates are available - Falls back to basic authentication if certificate files are not found or initialization fails - **Proxy Configuration**: `ATHENZ_USE_PROXY=false` (default) for cloud environments, `true` for corporate networks ### Setting up Environment Variables 1. **Copy the example file**: ```bash cp .env.example .env ``` 2. **Edit .env file**: ```bash # Jira Configuration JIRA_URL=https://your-domain.atlassian.net JIRA_PERSONAL_TOKEN=your_personal_access_token_here # Flava Functions Configuration FLAVA_FUNCTION_BASE_URL=https://api.flava.example.com # Flava Environment Configuration (auto-generates PROVIDER_DOMAIN) FLAVA_PRODUCT=faas FLAVA_ENVIRONMENT=stage FLAVA_PROJECT=flava-qa # This will generate PROVIDER_DOMAIN: flava-faas.stage.flava-qa # Athenz Authentication (optional, for production) FUNC_ACCOUNT_NAME=your-account-name # MCP Server Configuration (optional) MCP_PORT=8001 MCP_HOST=0.0.0.0 ``` 3. **Docker usage**: ```bash # Using environment file docker run --env-file .env -p 8001:8001 cqa-mcp-server # Using environment variables directly docker run -e JIRA_URL=https://your-domain.atlassian.net \ -e JIRA_PERSONAL_TOKEN=your_token \ -p 8001:8001 cqa-mcp-server ``` ### Jira Personal Access Token Setup 1. Go to Jira Settings → Personal Access Tokens 2. Create a new token with appropriate permissions 3. Copy the token and add it to your .env file ⚠️ **Important**: Without proper Jira configuration, the MCP tools will not function. ## Code Comparison ### Before (Manual JSON-RPC): ```python def handle_mcp_request(data): # 100+ lines of JSON-RPC handling code if method == "tools/list": # Manual schema generation elif method == "tools/call": # Manual tool execution ``` ### After (FastMCP): ```python from fastmcp import FastMCP mcp = FastMCP("Service Name") @mcp.tool def my_tool(param: str): """Tool description""" return result ``` FastMCP가 훨씬 간결하고 유지보수하기 쉽습니다!