MCP サービス

このサービスはショップの操作を Model Context Protocol 上のツールとして公開し、エージェントサービスやその他の MCP 互換クライアントがそれらを呼び出せるようにします。 各ツールはフロントエンド API を HTTP 経由で呼び出す薄いラッパーです。

MCP サービスのソースコード

計装ライブラリ

このサービスは opentelemetry-instrument ラッパーを介して起動されません。 Dockerfile はスクリプトを直接実行し、計装はコード内でセットアップされます。

CMD ["python", "run.py"]

run.py では、Traceloop SDK が OpenTelemetry SDK を初期化し、opentelemetry-instrumentation-mcp を含む計装ライブラリのバンドルを有効にします。 その後、HTTPX 計装が明示的に有効化されます。

Traceloop.init(
    app_name=os.getenv("OTEL_SERVICE_NAME", "mcp"),
)

HTTPXClientInstrumentor().instrument()

この組み合わせにより、手動でスパンを作成することなくサービスの両側をカバーします。

  • opentelemetry-instrumentation-mcp — FastMCP サーバーが処理する受信 MCP ツール呼び出しに対するスパン。
  • opentelemetry-instrumentation-httpx — 各ツールがフロントエンド API に対して行う送信 HTTP 呼び出しに対するクライアントスパン。

エージェントとこのサービスは同じ MCP 計装で計装されているため、コンテキストは MCP トランスポートを越えて伝搬し、エージェントが行ったツール呼び出しはこのサービスが実行する処理と同じトレースに表示されます。

トレース

トレースの初期化

Traceloop.init() はバッチスパンプロセッサーと OTLP エクスポーターを備えたトレーサープロバイダーを作成し、グローバルトレーサープロバイダーとして登録します。 そのため、上記の計装ライブラリは単一のエクスポートパイプラインを共有します。

エクスポートエンドポイントは OTEL_EXPORTER_OTLP_ENDPOINT ではなく TRACELOOP_BASE_URL から取得され、Traceloop はそれに /v1/traces を付加します。 Docker Compose では、これは OpenTelemetry Collector の OTLP/HTTP ポートを指します。 app_name 引数は service.name リソース属性になり、追加のリソース属性は OTEL_RESOURCE_ATTRIBUTES から読み取られます。

新しいスパンの作成

このサービスは独自のスパンを作成しません。 ツールは FastMCP サーバーに登録され、ラップされないため、すべてのスパンは計装ライブラリによって生成されます。

self.mcp.tool("add_to_cart")(tools.add_to_cart)

このサービスは OpenTelemetry トレーシング API を直接使用しません。 start_as_current_span を呼び出さず、set_attribute を使用してスパンをエンリッチすることもしません。

メトリクス

メトリクスの初期化

Traceloop.init()TRACELOOP_METRICS_ENABLED=false が設定されていない限り、メトリクスも構成します。 定期エクスポートメトリクスリーダーを備えたメータープロバイダーを作成しグローバルに登録するため、HTTPX 計装ライブラリが出力するメトリクスがエクスポートされます。

カスタムメトリクス

このサービスはカスタムメトリクスを定義していません。 メーターを取得せず、独自の計装も作成しません。

ログ

このサービスは Python 標準ライブラリのロガーのみを設定します。

logging.basicConfig(level=logging.INFO)

Traceloop のログエクスポートはデフォルトで無効であり、このサービスは LoggerProviderLoggingHandler をセットアップしません。 ログレコードは OTLP 経由でエクスポートされるのではなく、stdout に書き込まれコンテナランタイムによって収集されるため、トレースとの相関はありません。 ログカバレッジマトリクスを参照してください。

環境変数の全リストとトラブルシューティング手順については、サービスの README を参照してください。