"""Main FastMCP server for GitLab integration."""
import os
import sys
import logging
from dotenv import load_dotenv
from fastmcp import FastMCP
from .gitlab_client import GitLabClient, GitLabClientError
from .mcp_tools import register_tools
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
def create_server() -> FastMCP:
"""
Create and configure the MCP server.
Returns:
Configured FastMCP instance
Raises:
ValueError: If required environment variables are missing
"""
# Load environment variables from .env file
load_dotenv()
# Get configuration
gitlab_url = os.getenv('GITLAB_URL')
gitlab_token = os.getenv('GITLAB_TOKEN')
debug = os.getenv('DEBUG', 'false').lower() == 'true'
# Validate configuration
if not gitlab_url:
raise ValueError("GITLAB_URL environment variable is not set")
if not gitlab_token:
raise ValueError("GITLAB_TOKEN environment variable is not set")
# Set logging level
if debug:
logging.getLogger().setLevel(logging.DEBUG)
logger.debug("Debug mode enabled")
logger.info(f"Initializing GitLab MCP server for {gitlab_url}")
# Create GitLab client
try:
gitlab_client = GitLabClient(gitlab_url, gitlab_token)
# Test connection
gitlab_client.gl.auth()
logger.info("GitLab authentication successful")
except GitLabClientError as e:
logger.error(f"Failed to initialize GitLab client: {str(e)}")
raise ValueError(f"Failed to connect to GitLab: {str(e)}")
except Exception as e:
logger.error(f"Unexpected error during initialization: {str(e)}")
raise
# Create MCP server
mcp = FastMCP("gitlab-mcp")
# Register tools
register_tools(mcp, gitlab_client)
logger.info("Tools registered successfully")
# Log registered tools for debugging
if debug:
logger.debug("Registered tools:")
logger.debug(" - check_pipeline_status")
logger.debug(" - check_job_status")
logger.debug(" - get_job_log")
else:
# Log to info level if not debug, so users see what tools are available
logger.info("Available GitLab tools:")
logger.info(" - check_pipeline_status: Get pipeline status for current project and branch")
logger.info(" - check_job_status: Check job status with automatic polling")
logger.info(" - get_job_log: Retrieve the whole raw job log")
return mcp
def main():
"""Main entry point for the MCP server."""
try:
mcp = create_server()
logger.info("GitLab MCP server started, listening on stdio")
mcp.run()
except Exception as e:
logger.error(f"Failed to start server: {str(e)}")
sys.exit(1)
if __name__ == "__main__":
main()