Skip to main content
Lesson 10 of 12 · Remote MCP: Connect External Tools

Combine MCP and Built-in Tools

Lesson 10 of 12 Updated July 29, 2026 Developer
On this page
  1. Two tool families, one catalog
  2. Mixing them: nothing extra to learn
  3. Orchestration happens automatically
  4. Two typical compositions
  5. The hidden cost of abundance
  6. Key takeaways

Two tool families, one catalog

MCP isn’t the only way to give Grok capabilities. The xAI API includes native tools, called built-in tools, that the model can call without involving any external server. You don’t have to choose between the two families: you declare them in the same place and combine them freely in a single configuration.

Four native tools cover most needs.

  • Web search: real-time web search
  • Code execution: Python code execution in a sandbox
  • Image analysis: image analysis and description
  • File parsing: file content reading and extraction

You declare them in the tools array by type alone, without a URL or label—which makes sense, since there’s no remote server to designate.

Mixing them: nothing extra to learn

The syntax requires no special construction. You place MCP objects and native objects side by side in the same array.

from xai_sdk import Client
from xai_sdk.tools import mcp

client = Client(api_key=os.getenv("XAI_API_KEY"))

chat = client.chat.create(
    model="grok-4.20-0309-reasoning",
    tools=[
        # Remote MCP tool
        mcp(
            server_url="https://mcp.deepwiki.com/mcp",
            server_label="deepwiki",
            server_description="Documentation for GitHub projects"
        ),
        # Native tool: web search
        {"type": "web_search"},
    ],
)

The Responses API in OpenAI format follows the same logic, with the MCP tool simply taking its typed dictionary form.

response = client.responses.create(
    model="grok-4.20-0309-reasoning",
    input=[{"role": "user", "content": "Compare React and Vue based on the official docs and current trends"}],
    tools=[
        {
            "type": "mcp",
            "server_url": "https://mcp.deepwiki.com/mcp",
            "server_label": "deepwiki"
        },
        {"type": "web_search"},
    ],
)

Orchestration happens automatically

From the model’s perspective, MCP and native tools form a single catalog. Grok doesn’t distinguish between a tool that goes over the network to a third-party server and one executed by xAI infrastructure: it sees capabilities, with names and descriptions, and selects the one that advances the response at each step.

Take the query “compare the routing configuration in Next.js with current best practices.” Grok first calls deepwiki__search to read the routing documentation in the Next.js repository, then web_search to find recent articles on current practices, and finally synthesizes both sources into a coherent response. At no point did you specify this order, or even that these two tools should be used together. The model decides the sequence alone, and you have no orchestration logic to write.

Two typical compositions

A technical research agent leverages reference documentation, web access, and code verification capabilities.

tools = [
    mcp(
        server_url="https://mcp.deepwiki.com/mcp",
        server_label="deepwiki",
        server_description="Documentation and source code for GitHub projects"
    ),
    {"type": "web_search"},
    {"type": "code_interpreter"},
]

This trio lets you consult project documentation, search for additional information online, and then execute code to validate a solution before proposing it. The third tool changes the nature of the response: instead of claiming a snippet works, the agent verifies it.

An internal technical assistant follows a different logic, where two private servers hold the company’s knowledge and the web serves only as a backup.

tools = [
    mcp(
        server_url="https://kb.monentreprise.com/mcp",
        server_label="kb",
        server_description="Internal knowledge base",
        authorization=f"Bearer {os.getenv('KB_TOKEN')}"
    ),
    mcp(
        server_url="https://jira.monentreprise.com/mcp",
        server_label="jira",
        server_description="Jira tickets and projects",
        authorization=f"Bearer {os.getenv('JIRA_TOKEN')}",
        allowed_tool_names=["search_issues", "get_issue"]
    ),
    {"type": "web_search"},
]

The assistant searches the knowledge base, consults related Jira tickets, and supplements with a web search if information is missing internally. Note the restriction on Jira, limited to read-only access: without it, a malicious instruction slipped into the body of a ticket could push the model toward a write operation.

The hidden cost of abundance

Every added tool, MCP or native, takes up space in the context window to store its definition. A generous configuration therefore costs you in available space for conversation, processing time, and selection accuracy.

Three habits are enough to keep this in check. Limit the total number of tools, and resist the temptation to connect five servers with fifty tools when your use case requires ten. Apply allowed_tool_names on each MCP server to keep only relevant tools. And don’t add a native tool “just in case”: if your agent has no reason to execute code, code_interpreter isn’t a free option, it’s consumed context and an additional opportunity to pick the wrong tool.

Key takeaways

  • MCP tools and native tools (web search, code execution) coexist in the same tools array
  • Grok automatically orchestrates calls between MCP and native tools based on the query
  • The combination lets you create powerful agents that leverage both internal sources (MCP) and external sources (web search)
  • Limit the total number of tools to preserve context and model accuracy
  • Use allowed_tool_names for each MCP server to reduce noise