跳到正文
DEV Community· Anand Kannan·· 3 小時前AI 評分49

MCP 與 Code Mode:SRE 如何由個別工具呼叫進行智能事故調查

MCP vs Code Mode for SREs: From Individual Tool Calls to Intelligent Incident Investigation

AI 導讀

MCP 為大語言模型提供標準方式,以發現和呼叫工具;Code Mode 則讓模型編寫及執行程式碼,協調多項工具進行事故調查。兩者用途不同,並非互相競爭的協定,Code Mode 可以使用 MCP 工具。程式碼可在執行環境內處理及整合中間結果,減少傳回模型上下文的原始資料。

正文

Imagine you're on call. Your application suddenly starts returning HTTP
500 errors.

You have Prometheus for metrics, Loki for logs, Kubernetes for workload
information, and GitHub for deployments.

You ask an LLM:

Why did our application start returning 5xx errors around 10:30 AM?

The LLM needs to investigate several things:

  • Query Prometheus to identify when the error rate increased.
  • Check whether request volume or latency changed.
  • Search Loki for corresponding application errors.
  • Inspect Kubernetes pods and recent restarts.
  • Correlate the findings and identify a possible cause.

This is where two concepts become interesting: Model Context Protocol
(MCP)
and Code Mode.

They are often discussed together, but they solve different problems.

  • MCP gives an LLM a standard way to discover and invoke tools.
  • Code Mode allows an LLM to write and execute code to orchestrate those tools.

They are not competing protocols. Code Mode can use MCP tools
underneath.

Let's explore the difference through an SRE incident investigation,
using Python examples.

1. Understanding MCP

The Model Context Protocol (MCP) is an open standard that allows LLM
applications to connect to external tools and data sources through a
consistent interface.

Without MCP, every integration may require a custom implementation.
Prometheus, Loki, Kubernetes, and GitHub could each expose different
APIs and authentication mechanisms.

MCP provides a common way to expose these capabilities to an LLM.

For example, an SRE monitoring MCP server could expose tools such as:

query_prometheus
query_loki
get_pod_status
get_recent_deployments

The LLM can discover these tools, understand their descriptions and
input parameters, and invoke them when needed.

How MCP works

A simplified flow:

                User
                 |
                 v
             LLM Client
                 |
                 v
            MCP Client
                 |
                 v
          MCP Server
           /   |   \
          /    |    \
         v     v     v
    Prometheus Loki Kubernetes

The MCP server handles the integration with the underlying systems. The
LLM does not need to know every API endpoint or authentication detail.

For an SRE team, this means monitoring and operational capabilities can
be exposed in a consistent way.

A simple Python MCP server

The following example uses the Python MCP SDK to expose a Prometheus
query tool.

Install the SDK and HTTP client:

pip install "mcp[cli]" httpx

Example:

import os
import httpx

from mcp.server.fastmcp import FastMCP

mcp = FastMCP("sre-monitoring")

PROMETHEUS_URL = os.environ["PROMETHEUS_URL"]
PROMETHEUS_TOKEN = os.environ["PROMETHEUS_TOKEN"]


@mcp.tool()
async def query_prometheus(query: str) -> dict:
    """Execute an instant Prometheus query."""

    headers = {
        "Authorization": f"Bearer {PROMETHEUS_TOKEN}"
    }

    async with httpx.AsyncClient(timeout=15) as client:
        response = await client.get(
            f"{PROMETHEUS_URL}/api/v1/query",
            params={"query": query},
            headers=headers,
        )

        response.raise_for_status()
        payload = response.json()

    return payload["data"]


if __name__ == "__main__":
    mcp.run(transport="streamable-http")

This exposes Prometheus querying as an MCP tool.

You could implement similar tools for Loki, Kubernetes, and other
operational systems.

For production, add authentication, authorization, query restrictions,
timeouts, rate limits, and response-size limits. Avoid exposing
unrestricted access to monitoring or infrastructure APIs.

The important point is that MCP provides the tool interface. It does not
automatically decide how to investigate an incident or correlate
information across tools.

That is where Code Mode becomes interesting.

2. What is Code Mode?

With a conventional tool-calling approach, the LLM generally invokes
tools individually.

For example:

  1. Call Prometheus.
  2. Read the result.
  3. Decide to call Loki.
  4. Read the logs.
  5. Decide to inspect Kubernetes.
  6. Read the pod status.
  7. Correlate everything and produce an answer.

This works, but the LLM may need to make several tool calls and process
a lot of intermediate data.

Code Mode takes a different approach.

Instead of asking the LLM to orchestrate every individual tool call
itself, it allows the LLM to write a small program that performs the
orchestration.

For example, the LLM could generate Python code that:

  • Queries Prometheus for the error rate.
  • Identifies the time window when the error rate increased.
  • Searches Loki only for that time window.
  • Groups matching errors by type.
  • Retrieves relevant Kubernetes information.
  • Returns a compact summary.

The intermediate processing happens in an execution environment rather
than requiring every raw result to be sent back into the LLM's context.

How Code Mode works

                  User
                   |
                   v
                  LLM
                   |
                   v
          Generates Python code
                   |
                   v
          Isolated execution runtime
                   |
           -------------------
           |        |        |
           v        v        v
       Prometheus  Loki  Kubernetes
           |        |        |
           -------------------
                   |
                   v
          Process and correlate
                   |
                   v
          Compact result to LLM
                   |
                   v
             Final answer

The LLM still makes decisions, but code handles much of the repetitive
orchestration and data processing.

Important distinction: Code Mode is an architectural pattern, not a
separate protocol that replaces MCP. The execution runtime is an
additional component. The Python example below illustrates a custom
sandbox architecture; it is not an official Python implementation of
Cloudflare's Code Mode SDK.

3. MCP vs Code Mode: What is the actual difference?


Area Traditional MCP tool Code Mode
calling


Main purpose Expose tools to an LLM Orchestrate tools using
code

Execution Individual tool calls Generated code executes
multiple operations

Data processing Often handled by the Can happen inside the
LLM runtime

Intermediate results May enter LLM context Can remain inside the
runtime

Tool orchestration LLM coordinates calls Generated code
coordinates calls

Context usage Can grow with tool Can reduce context
responses usage through
aggregation

Flexibility Depends on available Can combine tools and
tools perform custom
processing


A useful way to remember it:

MCP provides the capabilities. Code Mode provides a way to compose
those capabilities programmatically.

4. Real-world SRE example: Investigating a 5xx incident

Let's take a practical scenario.

At 10:30 AM, an application starts returning HTTP 500 errors.

The on-call engineer asks:

Investigate why the 5xx error rate increased around 10:30 AM. Check
Prometheus, Loki, and Kubernetes. Identify the most likely cause.

Assume the monitoring environment provides the following MCP tools:

query_prometheus(query, start, end)
query_loki(query, start, end)
get_pod_status(namespace, deployment)

Approach A: Individual MCP tool calls

The LLM might execute the investigation in several steps.

Step 1: Check the error rate in Prometheus

sum(rate(http_requests_total{
  status=~"5.."
}[5m]))
/
sum(rate(http_requests_total[5m]))

The result indicates that the 5xx error rate increased from 0.5% to 18%
around 10:30 AM.

Step 2: Investigate application logs in Loki

{namespace="production", app="checkout"}
|= "ERROR"

The LLM receives matching logs and identifies repeated database
connection timeout errors.

Step 3: Check Kubernetes

The LLM invokes the pod-status tool and finds that several checkout pods
are restarting.

Step 4: Correlate the results

The LLM now has to reason across the metrics, logs, and Kubernetes
responses.

A possible conclusion:

The 5xx error rate increased around 10:30 AM. Loki shows repeated
database connection timeouts, while Kubernetes reports pod restarts.
The evidence suggests that database connectivity may be contributing
to the application failures.

This approach works.

However, each tool invocation can return a substantial amount of data.
The LLM must repeatedly process intermediate results and decide what to
investigate next.

Approach B: Code Mode with Python

Now imagine the LLM can generate Python code and execute it in an
isolated runtime.

Instead of making every decision through separate conversational tool
calls, it can generate a program that coordinates the investigation.

Conceptually:

async def investigate_5xx_incident(start, end):

    # 1. Query the error rate
    metrics = await tools.query_prometheus(
        query="""
        sum(rate(http_requests_total{
            status=~"5.."
        }[5m]))
        /
        sum(rate(http_requests_total[5m]))
        """,
        start=start,
        end=end,
    )

    # 2. Identify the first abnormal point
    first_bad_point = find_threshold_crossing(
        metrics,
        threshold=0.05,
    )

    if not first_bad_point:
        return {
            "status": "No significant increase detected"
        }

    # 3. Search logs around the abnormal time
    logs = await tools.query_loki(
        query='{namespace="production", app="checkout"} |= "ERROR"',
        start=first_bad_point["timestamp"] - 300,
        end=end,
    )

    # 4. Group and summarize errors
    error_summary = summarize_errors(logs)

    # 5. Check Kubernetes
    pods = await tools.get_pod_status(
        namespace="production",
        deployment="checkout",
    )

    # 6. Return only relevant findings
    return {
        "error_rate": first_bad_point,
        "log_summary": error_summary,
        "pod_status": summarize_pods(pods),
    }

Here, tools represents a controlled bridge to available MCP
capabilities inside the custom execution runtime. It is illustrative
pseudocode, not an API provided directly by the MCP Python SDK.

The helper functions would need to be implemented, tested, and given
appropriate input and output contracts.

The key idea is that the runtime can process large responses, correlate
information, and return only the relevant findings to the LLM.

Example investigation output

The LLM could receive a compact result like this:

{
  "incident": "checkout-5xx-increase",
  "time": "10:30 AM",
  "error_rate": {
    "before": "0.5%",
    "after": "18%"
  },
  "top_log_error": "Database connection timeout",
  "affected_pods": 4,
  "restarts_detected": true,
  "likely_cause": "Database connectivity issue",
  "confidence": "Medium"
}

The LLM can then explain the findings, distinguish observed facts from
hypotheses, and recommend the next investigation steps.

Notice that the runtime does not need to send every metric sample, every
log line, and every pod detail back to the LLM.

That is the practical advantage.

5. Why context windows matter

This is one of the most important reasons to consider Code Mode for
operational workflows.

Every LLM has a context window.

A context window is the amount of information the model can consider
during a request or conversation. It is measured in tokens, not simply
words or characters.

The context window may contain:

  • System instructions.
  • User prompts.
  • Conversation history.
  • MCP tool definitions and descriptions.
  • Tool arguments.
  • Tool responses.
  • Retrieved documentation.
  • Intermediate reasoning and generated output.

All of this competes for the available context capacity, depending on
the model and platform.

A practical SRE example

Imagine an incident investigation that retrieves:

Data source Approximate token usage


500 metric samples 15,000
2,000 Loki log lines 80,000
Kubernetes pod information 15,000
Recent deployment information 10,000
Tool definitions and schemas 5,000
Prompt and conversation history 10,000
Total 135,000

These are illustrative estimates, not fixed token counts. Actual usage
depends on the response format, field lengths, and tokenization.

If the model has a 128K-token context window, this investigation could
exceed the available capacity.

Even when a model supports a larger context window, sending thousands of
irrelevant log lines is not necessarily helpful.

More context does not automatically mean better answers.

Large responses can introduce noise, make important evidence harder to
identify, and increase processing costs and latency.

How Code Mode helps

With traditional tool calling, a large tool response may be passed into
the LLM context so that the model can inspect it.

With Code Mode, the runtime can process the response first.

For example:

Prometheus response
        |
        v
Python processing
        |
        v
Identify abnormal time window
        |
        v
Loki query for relevant logs
        |
        v
Group errors by category
        |
        v
Return top 5 findings

Instead of returning 2,000 log lines, the runtime might return:

{
  "total_errors": 2000,
  "top_errors": [
    {
      "type": "Database connection timeout",
      "count": 1450
    },
    {
      "type": "Connection pool exhausted",
      "count": 420
    },
    {
      "type": "Request timeout",
      "count": 130
    }
  ],
  "time_window": "10:30-10:45 AM"
}

Now the LLM receives a much smaller and more useful response.

Code Mode does not increase the model's context window. It helps use
that context more efficiently.

The code itself, tool descriptions, and final results still consume
tokens. The benefit comes from keeping large intermediate datasets
outside the LLM context and returning only what is needed.

For more background, see the OpenAI guide to conversation
state

and the MCP Python SDK
documentation
.

6. Where Code Mode makes sense for SRE teams

Not every operational task needs Code Mode.

For simple tasks, individual MCP tool calls are often sufficient.

For example:

  • Checking whether a service is healthy.
  • Retrieving the current CPU utilization.
  • Getting the status of a particular pod.
  • Querying a specific metric.
  • Looking up a deployment version.

Code Mode becomes more useful when the task requires multiple
operations, conditional logic, or substantial data processing.

Some examples:


SRE use case Why Code Mode helps


Incident investigation Correlates metrics, logs, and
infrastructure state

Root cause analysis Runs multiple queries and compares
results

Capacity planning Processes historical metrics and
calculates trends

Deployment analysis Compares metrics before and after
deployments

Alert investigation Groups related alerts and
identifies common patterns

Log analysis Filters and aggregates large log
responses

SLO analysis Calculates error budgets and burn
rates across services


For an SRE team, the value is not simply executing more tools. It is
reducing the manual effort required to connect evidence from different
systems.

7. Python implementation considerations

If your environment is Python-based, it is important to distinguish
between the MCP server and the Code Mode execution environment.

They are separate responsibilities.

MCP server:

  • Exposes operational capabilities.
  • Handles integrations with Prometheus, Loki, Kubernetes, and other systems.
  • Applies authentication and authorization.
  • Returns structured responses.

Code execution runtime:

  • Receives generated Python code.
  • Executes it in an isolated environment.
  • Provides controlled access to approved tools.
  • Processes intermediate responses.
  • Returns a compact result to the LLM.

A practical architecture could look like this:

                 LLM
                  |
                  v
          Code generation
                  |
                  v
       Isolated Python runtime
                  |
                  v
          Controlled tool bridge
                  |
                  v
              MCP client
                  |
                  v
              MCP server
             /    |     \
            v     v      v
       Prometheus Loki Kubernetes

The Python runtime should not have unrestricted access to production
infrastructure.

Some important safeguards:

  1. Sandbox execution: Never execute arbitrary generated code
    directly inside your MCP server process using unrestricted exec().

  2. Tool allowlisting: Expose only approved operations. For example,
    allow read-only Prometheus queries rather than arbitrary HTTP
    requests.

  3. Authentication: Use scoped credentials and short-lived tokens
    where possible.

  4. Resource limits: Apply execution timeouts, memory limits, and
    response-size limits.

  5. Query restrictions: Prevent expensive or unrestricted Prometheus
    and Loki queries.

  6. Auditability: Record generated code, tool invocations, execution
    results, and the identity or session responsible.

  7. Human approval: Require explicit approval for actions that
    modify production infrastructure.

  8. Output validation: Validate tool responses and generated results
    before returning them to the LLM.

For production SRE workflows, safety and observability are just as
important as the orchestration itself.

8. So, should SRE teams use MCP or Code Mode?

My recommendation is to start with MCP and introduce Code Mode when the
workflow justifies it.

MCP gives you a reusable foundation for exposing operational
capabilities.

Once those capabilities are available, Code Mode can help compose them
into more complex investigations without sending every intermediate
response into the LLM context.

A sensible adoption path:

Phase 1: Expose tools through MCP

Start with read-only tools for Prometheus, Loki, and Kubernetes.

Phase 2: Build useful LLM workflows

Allow the LLM to investigate common operational questions using
individual tool calls.

Phase 3: Identify context-heavy workflows

Look for workflows where the LLM repeatedly calls tools, receives large
responses, and spends significant context processing intermediate data.

Phase 4: Introduce a controlled Python execution runtime

Allow generated code to orchestrate approved MCP tools and process large
responses outside the LLM context.

Phase 5: Measure the improvement

Compare:

  • Number of tool calls.
  • Tokens consumed.
  • Investigation latency.
  • Quality of findings.
  • Accuracy of incident conclusions.
  • Operational safety.

This helps determine whether Code Mode is actually improving the
workflow rather than introducing complexity without measurable value.

Conclusion

MCP and Code Mode address different parts of the problem.

MCP standardizes how an LLM accesses external capabilities.

Code Mode provides a way for an LLM to programmatically orchestrate
those capabilities, process data, and return focused results.

For SRE teams, this distinction matters.

An incident investigation is rarely a single query. It is a sequence of
decisions involving metrics, logs, deployments, and infrastructure
state.

MCP makes those systems accessible. Code Mode can make the investigation
more efficient, particularly when large datasets and multiple tools are
involved.

The interesting direction for SRE is not just giving an LLM access to
more tools. It is giving the LLM a safe way to combine those tools and
reason over the right amount of information.


References

來源:DEV Community · dev.to