Add otel-enable flag for mcp (#583)
This commit is contained in:
parent
413ff2b915
commit
710cd2b48a
3 changed files with 46 additions and 5 deletions
|
|
@ -227,6 +227,9 @@ def mcp(
|
|||
False, "--reload", help="Enable auto-reload on code changes (HTTP mode only)"
|
||||
),
|
||||
debug: bool = typer.Option(False, "--debug", help="Enable debug mode with verbose logging"),
|
||||
otel_enable: bool = typer.Option(
|
||||
False, "--otel-enable", help="Send logs to OpenTelemetry", show_default=True
|
||||
),
|
||||
env_file: Optional[str] = typer.Option(None, "--env-file", help="Path to environment file"),
|
||||
name: Optional[str] = typer.Option(None, "--name", help="Server name"),
|
||||
version: Optional[str] = typer.Option(None, "--version", help="Server version"),
|
||||
|
|
@ -250,7 +253,10 @@ def mcp(
|
|||
# Add optional arguments
|
||||
cmd.extend(["--host", host])
|
||||
cmd.extend(["--port", str(port)])
|
||||
cmd.append("--debug")
|
||||
if debug:
|
||||
cmd.append("--debug")
|
||||
if otel_enable:
|
||||
cmd.append("--otel-enable")
|
||||
if tool_package:
|
||||
cmd.extend(["--tool-package", tool_package])
|
||||
if discover_installed:
|
||||
|
|
|
|||
|
|
@ -264,6 +264,11 @@ Auto-discovery looks for Python files with @tool decorated functions in:
|
|||
action="store_true",
|
||||
help="Enable debug mode with verbose logging",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--otel-enable",
|
||||
action="store_true",
|
||||
help="Send logs to OpenTelemetry",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--env-file",
|
||||
help="Path to environment file",
|
||||
|
|
@ -336,6 +341,7 @@ Auto-discovery looks for Python files with @tool decorated functions in:
|
|||
port=args.port,
|
||||
reload=args.reload,
|
||||
debug=args.debug,
|
||||
otel_enable=args.otel_enable,
|
||||
tool_package=args.tool_package,
|
||||
discover_installed=args.discover_installed,
|
||||
show_packages=args.show_packages,
|
||||
|
|
|
|||
|
|
@ -5,12 +5,15 @@ Creates a FastAPI application that exposes both Arcade Worker endpoints and
|
|||
MCP Server endpoints over HTTP/SSE. MCP is always enabled in this integrated mode.
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
from collections.abc import AsyncGenerator, AsyncIterator
|
||||
from contextlib import asynccontextmanager
|
||||
from typing import Any
|
||||
|
||||
import uvicorn
|
||||
from arcade_core.catalog import ToolCatalog
|
||||
from arcade_serve.fastapi.telemetry import OTELHandler
|
||||
from arcade_serve.fastapi.worker import FastAPIWorker
|
||||
from fastapi import FastAPI
|
||||
from loguru import logger
|
||||
|
|
@ -74,6 +77,7 @@ def create_arcade_mcp(
|
|||
catalog: ToolCatalog,
|
||||
mcp_settings: MCPSettings | None = None,
|
||||
debug: bool = False,
|
||||
otel_enable: bool = False,
|
||||
**kwargs: Any,
|
||||
) -> FastAPI:
|
||||
"""
|
||||
|
|
@ -87,12 +91,28 @@ def create_arcade_mcp(
|
|||
if secret is None:
|
||||
secret = "dev" # noqa: S105
|
||||
|
||||
otel_handler = OTELHandler(
|
||||
enable=otel_enable,
|
||||
log_level=logging.DEBUG if debug else logging.INFO,
|
||||
)
|
||||
|
||||
@asynccontextmanager
|
||||
async def lifespan(app: FastAPI) -> AsyncIterator[None]:
|
||||
async with create_lifespan(catalog, mcp_settings, **kwargs) as components:
|
||||
app.state.mcp_server = components["mcp_server"]
|
||||
app.state.session_manager = components["session_manager"]
|
||||
yield
|
||||
try:
|
||||
logger.debug(f"Server lifespan startup. OTEL enabled: {otel_enable}")
|
||||
async with create_lifespan(catalog, mcp_settings, **kwargs) as components:
|
||||
app.state.mcp_server = components["mcp_server"]
|
||||
app.state.session_manager = components["session_manager"]
|
||||
yield
|
||||
except (asyncio.CancelledError, KeyboardInterrupt):
|
||||
logger.debug("Server lifespan cancelled.")
|
||||
raise
|
||||
finally:
|
||||
logger.debug(f"Server lifespan shutdown. OTEL enabled: {otel_enable}")
|
||||
if otel_enable and otel_handler:
|
||||
otel_handler.shutdown()
|
||||
await logger.complete()
|
||||
logger.debug("Server lifespan shutdown complete.")
|
||||
|
||||
app = FastAPI(
|
||||
title=(mcp_settings.server.title or mcp_settings.server.name),
|
||||
|
|
@ -103,12 +123,14 @@ def create_arcade_mcp(
|
|||
lifespan=lifespan,
|
||||
**kwargs,
|
||||
)
|
||||
otel_handler.instrument_app(app)
|
||||
|
||||
# Worker endpoints
|
||||
worker = FastAPIWorker(
|
||||
app=app,
|
||||
secret=secret,
|
||||
disable_auth=mcp_settings.arcade.auth_disabled,
|
||||
otel_meter=otel_handler.get_meter(),
|
||||
)
|
||||
worker.catalog = catalog
|
||||
|
||||
|
|
@ -191,6 +213,7 @@ def create_arcade_mcp_factory() -> FastAPI:
|
|||
|
||||
# Read configuration from env vars that were set before running the server
|
||||
debug = os.environ.get("ARCADE_MCP_DEBUG", "false").lower() == "true"
|
||||
otel_enable = os.environ.get("ARCADE_MCP_OTEL_ENABLE", "false").lower() == "true"
|
||||
tool_package = os.environ.get("ARCADE_MCP_TOOL_PACKAGE")
|
||||
discover_installed = os.environ.get("ARCADE_MCP_DISCOVER_INSTALLED", "false").lower() == "true"
|
||||
show_packages = os.environ.get("ARCADE_MCP_SHOW_PACKAGES", "false").lower() == "true"
|
||||
|
|
@ -216,6 +239,8 @@ def create_arcade_mcp_factory() -> FastAPI:
|
|||
raise RuntimeError("No tools found")
|
||||
|
||||
logger.info(f"Total tools loaded: {total_tools}")
|
||||
if otel_enable:
|
||||
logger.info("OpenTelemetry is enabled")
|
||||
|
||||
# Build kwargs for server creation
|
||||
kwargs = {}
|
||||
|
|
@ -228,6 +253,7 @@ def create_arcade_mcp_factory() -> FastAPI:
|
|||
catalog=catalog,
|
||||
mcp_settings=None,
|
||||
debug=debug,
|
||||
otel_enable=otel_enable,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
|
|
@ -238,6 +264,7 @@ def run_arcade_mcp(
|
|||
port: int = 7777,
|
||||
reload: bool = False,
|
||||
debug: bool = False,
|
||||
otel_enable: bool = False,
|
||||
tool_package: str | None = None,
|
||||
discover_installed: bool = False,
|
||||
show_packages: bool = False,
|
||||
|
|
@ -253,6 +280,7 @@ def run_arcade_mcp(
|
|||
if reload:
|
||||
# Set env vars for the app factory to read later
|
||||
os.environ["ARCADE_MCP_DEBUG"] = str(debug)
|
||||
os.environ["ARCADE_MCP_OTEL_ENABLE"] = str(otel_enable)
|
||||
if tool_package:
|
||||
os.environ["ARCADE_MCP_TOOL_PACKAGE"] = tool_package
|
||||
os.environ["ARCADE_MCP_DISCOVER_INSTALLED"] = str(discover_installed)
|
||||
|
|
@ -278,6 +306,7 @@ def run_arcade_mcp(
|
|||
app = create_arcade_mcp(
|
||||
catalog=catalog,
|
||||
debug=debug,
|
||||
otel_enable=otel_enable,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue