"""Cloudflare Code Mode MCP Server Integration. Manages the remote Cloudflare MCP server connection via mcp-remote bridge. The server exposes the entire Cloudflare API (2,500+ endpoints) through just two tools: search() and execute(), using ~1,000 tokens total. Architecture: Your bot → npx mcp-remote → https://mcp.cloudflare.com/mcp Auth is via Cloudflare API Token passed as Bearer header. Pattern mirrors obsidian_mcp.py for consistency. """ import os import logging from typing import Any, Dict, List logger = logging.getLogger(__name__) def _load_config() -> Dict[str, Any]: """Load Cloudflare MCP configuration from environment.""" from mcp_servers.cloudflare.config import ( CLOUDFLARE_API_TOKEN, CLOUDFLARE_MCP_URL, CLOUDFLARE_MCP_ENABLED, ) return { "enabled": CLOUDFLARE_MCP_ENABLED, "api_token": CLOUDFLARE_API_TOKEN, "mcp_url": CLOUDFLARE_MCP_URL, } def is_cloudflare_enabled() -> bool: """Check if the Cloudflare MCP integration is enabled and has a token.""" config = _load_config() if not config["enabled"]: return False if not config["api_token"]: logger.warning( "[Cloudflare MCP] Enabled but CLOUDFLARE_API_TOKEN is not set" ) return False return True def get_cloudflare_server_config() -> Dict[str, Any]: """Build the MCP server configuration for Agent SDK registration. Returns the config dict suitable for ClaudeAgentOptions.mcp_servers. Uses npx mcp-remote as a stdio bridge to the remote Cloudflare server. The API token is passed via the --header flag as a Bearer token. """ config = _load_config() return { "command": "npx", "args": [ "mcp-remote", config["mcp_url"], "--header", f"Authorization: Bearer {config['api_token']}", ], "env": { # Pass through any needed env vars for npx/node resolution "PATH": os.environ.get("PATH", ""), "HOME": os.environ.get("HOME", os.environ.get("USERPROFILE", "")), "APPDATA": os.environ.get("APPDATA", ""), }, } # Tools exposed by the Cloudflare Code Mode MCP server. # These are the only two tools — that's the whole point of Code Mode. CLOUDFLARE_TOOLS: List[str] = [ "search", "execute", ]