diff --git a/agentops/instrumentation/__init__.py b/agentops/instrumentation/__init__.py index e47b6e7fb..5fc2c82eb 100644 --- a/agentops/instrumentation/__init__.py +++ b/agentops/instrumentation/__init__.py @@ -118,6 +118,12 @@ class InstrumentorConfig(TypedDict): "min_version": "1.0.0", "package_name": "xpander-sdk", }, + "mcp_agent": { + "module_name": "agentops.instrumentation.agentic.mcp_agent", + "class_name": "McpAgentInstrumentor", + "min_version": "0.1.0", + "package_name": "mcp-agent", + }, } # Combine all target packages for monitoring diff --git a/agentops/instrumentation/agentic/mcp_agent/__init__.py b/agentops/instrumentation/agentic/mcp_agent/__init__.py new file mode 100644 index 000000000..b7ec73bec --- /dev/null +++ b/agentops/instrumentation/agentic/mcp_agent/__init__.py @@ -0,0 +1,3 @@ +from .instrumentor import McpAgentInstrumentor + +__all__ = ["McpAgentInstrumentor"] \ No newline at end of file diff --git a/agentops/instrumentation/agentic/mcp_agent/instrumentor.py b/agentops/instrumentation/agentic/mcp_agent/instrumentor.py new file mode 100644 index 000000000..c6387db7c --- /dev/null +++ b/agentops/instrumentation/agentic/mcp_agent/instrumentor.py @@ -0,0 +1,52 @@ +from typing import Collection + +from opentelemetry import trace +from opentelemetry.instrumentation.instrumentor import BaseInstrumentor # type: ignore + +from agentops.logging import logger + + +class McpAgentInstrumentor(BaseInstrumentor): + """Instrumentor for lastmile-ai mcp-agent. + + This instrumentor doesn't need to monkey-patch the library because mcp-agent + already emits OpenTelemetry spans via its telemetry module. Our goal is to + ensure a single agentic library is marked active so provider-level + instrumentations are not double-counted, and to initialize a tracer namespace. + """ + + _is_instrumented_instance_flag: bool = False + + def __init__(self) -> None: + super().__init__() + self._tracer = None + + def instrumentation_dependencies(self) -> Collection[str]: + """Return required package for activation. + + The pip package name is mcp-agent; the module is mcp_agent. + """ + return ["mcp-agent >= 0.1.0"] + + def _instrument(self, **kwargs): + if self._is_instrumented_instance_flag: + logger.debug("mcp-agent already instrumented. Skipping.") + return + + tracer_provider = kwargs.get("tracer_provider") + # Create a named tracer for clarity in backends + self._tracer = trace.get_tracer("agentops.instrumentation.mcp_agent") + + # Optionally, we could hook mcp_agent telemetry here if needed in the future. + # For now, we rely on global OTEL configuration so mcp_agent spans export via AgentOps exporter. + self._is_instrumented_instance_flag = True + logger.info("Successfully activated mcp-agent integration for AgentOps") + + def _uninstrument(self, **kwargs): + if not self._is_instrumented_instance_flag: + logger.debug("mcp-agent not currently instrumented. Skipping uninstrument.") + return + # No patches applied, so nothing to undo besides flipping the flag + self._is_instrumented_instance_flag = False + self._tracer = None + logger.info("Successfully removed mcp-agent integration for AgentOps") \ No newline at end of file diff --git a/docs/mint.json b/docs/mint.json index 3af5008ae..c065ff541 100644 --- a/docs/mint.json +++ b/docs/mint.json @@ -157,7 +157,8 @@ "v2/integrations/smolagents", "v2/integrations/ibm_watsonx_ai", "v2/integrations/xai", - "v2/integrations/xpander" + "v2/integrations/xpander", + "v2/integrations/mcp_agent" ], "version": "v2" }, diff --git a/docs/v2/integrations/mcp_agent.mdx b/docs/v2/integrations/mcp_agent.mdx new file mode 100644 index 000000000..5375e81ed --- /dev/null +++ b/docs/v2/integrations/mcp_agent.mdx @@ -0,0 +1,32 @@ +--- +title: MCP Agent +--- + +MCP Agent (lastmile-ai/mcp-agent) is now auto-instrumented by AgentOps. + +- No code changes needed. Ensure AgentOps is initialized in your app so OpenTelemetry spans export to AgentOps. +- When `mcp-agent` is installed and imported as `mcp_agent`, AgentOps will activate the `McpAgentInstrumentor` and suppress duplicate provider instrumentation. + +Quick start: + +```python +import agentops + +agentops.init("") + +# Import and use mcp_agent normally +from mcp_agent.app import MCPApp + +# ... your app code ... + +agentops.end_session("Success") +``` + +Requirements: + +- `mcp-agent >= 0.1.0` +- AgentOps Python SDK installed (`pip install agentops`) + +Notes: + +- MCP Agent already emits OpenTelemetry spans via its telemetry manager; AgentOps will route them to your project with proper resource attributes and JWT-auth OTLP exporter. \ No newline at end of file diff --git a/external/mcp-agent b/external/mcp-agent new file mode 160000 index 000000000..64b93d25e --- /dev/null +++ b/external/mcp-agent @@ -0,0 +1 @@ +Subproject commit 64b93d25e05873b20a78d22cedbd1ef4fdfcf93d