> ## Documentation Index
> Fetch the complete documentation index at: https://docs.impellabs.tech/llms.txt
> Use this file to discover all available pages before exploring further.

# Grok

> A custom connector in the Grok app, and a remote MCP tool from the xAI API.

<img src="https://mintcdn.com/mahadev/-gWik8vU43pna0pu/images/harnesses/grok-dark.svg?fit=max&auto=format&n=-gWik8vU43pna0pu&q=85&s=4facfdbbe67689bd971aa896c0f09992" alt="Grok" width="48" height="48" noZoom className="block dark:hidden" data-path="images/harnesses/grok-dark.svg" />

<img src="https://mintcdn.com/mahadev/-gWik8vU43pna0pu/images/harnesses/grok-light.svg?fit=max&auto=format&n=-gWik8vU43pna0pu&q=85&s=f4164b603e360ff3d355430b4293a73d" alt="Grok" width="48" height="48" noZoom className="hidden dark:block" data-path="images/harnesses/grok-light.svg" />

**Preview.** Grok reaches the server two ways. The app takes a URL and walks you
through authentication; the xAI API takes a **bearer key** you hand it, which is
the shorter path if you are writing backend code.

## In the Grok app

Connectors live at [grok.com/connectors](https://grok.com/connectors). Grok ships
built-in connectors and a catalogue of pre-configured ones; ours is neither, so
it is added as a **custom MCP connector**.

<Steps>
  <Step title="New Connector → Custom">
    At [grok.com/connectors](https://grok.com/connectors), choose **New
    Connector**, then **Custom**.
  </Step>

  <Step title="Enter the server URL and authenticate">
    ```
    https://api.impellabs.tech/mcp
    ```

    Then complete the authentication the connector asks for. The server
    advertises the OAuth 2.1 flow at
    `/.well-known/oauth-protected-resource`, so a client that looks for it finds
    it without configuration — see [Authentication](/connect/authentication).
  </Step>

  <Step title="Grok discovers the tools">
    Grok calls `tools/list` and makes what it finds available in conversation,
    the same way it treats a built-in connector. Ask for something a tool
    answers.
  </Step>
</Steps>

<Note>
  In a **Grok Business or Enterprise** organisation, a team admin provisions a
  connector in the cloud console before anyone else in the organisation can use
  it. That is xAI's rule, not ours.
</Note>

<Warning>
  **Your MCP server must be reachable over the public internet.** xAI's
  documentation says so plainly, and it is the one thing that trips people
  coming from Claude Code. `https://api.impellabs.tech/mcp` is public, so this
  is only a problem if you are pointing Grok at a staging host behind a VPN — in
  which case you need a tunnel, and xAI documents that separately.
</Warning>

## From the xAI API

The API attaches a remote MCP server as an entry in the `tools` array. xAI holds
the connection to us and drives it on the model's behalf; your code sends one
request.

The parameter that matters is `authorization`. xAI's documentation describes it
as *"a token that will be set in the `Authorization` header on requests to the
MCP server"* — which is exactly the header our bearer path reads. **So a `tgcc_`
key works against the xAI API directly**, with no OAuth flow and no connector.

<CodeGroup>
  ```python xai sdk theme={null}
  import os

  from xai_sdk import Client
  from xai_sdk.chat import user
  from xai_sdk.tools import mcp

  client = Client(api_key=os.environ["XAI_API_KEY"])

  chat = client.chat.create(
      model="grok-4.6",
      tools=[
          mcp(
              server_url="https://api.impellabs.tech/mcp",
              server_label="impellabs",
              authorization=os.environ["IMPELLABS_API_KEY"],   # tgcc_…
              allowed_tool_names=["list_agents", "search_knowledge"],
          ),
      ],
  )
  chat.append(user("List the agents in my ImpelLabs workspace."))
  print(chat.sample().content)
  ```

  ```python responses api theme={null}
  import os

  from openai import OpenAI

  client = OpenAI(
      api_key=os.environ["XAI_API_KEY"],
      base_url="https://api.x.ai/v1",
  )

  resp = client.responses.create(
      model="grok-4.6",
      input="List the agents in my ImpelLabs workspace.",
      tools=[{
          "type": "mcp",
          "server_label": "impellabs",
          "server_url": "https://api.impellabs.tech/mcp",
          "authorization": os.environ["IMPELLABS_API_KEY"],   # tgcc_…
          "allowed_tools": ["list_agents", "search_knowledge"],
      }],
  )
  print(resp.output_text)
  ```
</CodeGroup>

<Note>
  The two SDKs spell two of these differently, and it is the first thing that
  fails. xAI's native SDK takes **`allowed_tool_names`** and **`extra_headers`**;
  the OpenAI-compatible Responses API takes **`allowed_tools`** and
  **`headers`**. `server_url`, `server_label` and `authorization` are the same in
  both. `require_approval` and `connector_id` from OpenAI's own Responses API are
  **not** supported by xAI.
</Note>

### Narrow it at both ends

`allowed_tool_names` is xAI's filter, and it is worth setting: without it, every
tool the server exposes is injected into the model's context, which costs tokens
and widens what the model may reach for.

<Warning>
  It is a filter, not a permission. The list is xAI's, applied before the call;
  the **scope on the key** is ours, checked inside the dispatcher on every call.
  A key holding only `agents:read` cannot be talked into spending credits
  whatever the `tools` array says — and that is the guarantee worth relying on.
  See [Authentication](/connect/authentication).
</Warning>

## Transport

xAI supports Streaming HTTP and SSE for remote MCP servers. We speak **Streamable
HTTP** and offer no SSE stream, which is the supported half — there is nothing to
choose and nothing to configure. `GET /mcp` answering **405** is that same fact
seen from the other side, and is not a fault; [Limits](/connect/limits) has the
whole table.

## Two behaviours that will surprise you

<AccordionGroup>
  <Accordion title="Some tools answer with a job id, not a result">
    Extractions, reports, knowledge ingestions and jobs are queued, always. The
    tool hands back a job id and Grok has to poll before it can honestly say the
    work finished. A model that reports "started" and stops is behaving
    correctly; ask it to check the job.
  </Accordion>

  <Accordion title="Uploading a document succeeds before it is readable">
    Upload returns success while parsing continues in the background. Reading
    the document's text straight afterwards returns **409
    `document_not_processed`** until parsing finishes. It did not fail — wait,
    then read again.
  </Accordion>
</AccordionGroup>

Both are described in the tool descriptions themselves, so the model is told.
[Tools](/connect/tools) explains why they work that way.

<CardGroup cols={2}>
  <Card title="Tools" icon="wrench" href="/connect/tools">
    What is callable, and the scope each one demands.
  </Card>

  <Card title="Authentication" icon="key" href="/connect/authentication">
    Bearer keys, the OAuth flow, and the scope split.
  </Card>
</CardGroup>

<Info>
  xAI's own pages for these two paths are
  [Connectors](https://docs.x.ai/grok/connectors) and [Remote MCP
  Tools](https://docs.x.ai/developers/tools/remote-mcp).
</Info>
