> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.eyelevel.ai/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.eyelevel.ai/_mcp/server.

# Connect Hosted GroundX MCP Tools

This page is for connecting your AI agent (or your own app) to GroundX's hosted
tools, so it can do GroundX work for you. It covers the address to connect to,
how to sign in, which tools you get, and how to reach the more advanced ones.

GroundX supports the Model Context Protocol (MCP), a standard way for AI agents
and other clients to call GroundX through a set of ready-made tools. Connecting
these hosted tools is optional; you can also work with GroundX entirely from
your own code through the [Direct SDK/API Quickstart](/documentation/get-started/direct-sdk-api-quickstart). Whether the
hosted tools fit depends on: whether your client supports remote MCP or
connectors, whether the connection is available, and whether the tool you need
is one of the ones GroundX makes available. See
[SDK/REST Fallback](/documentation/agent-harness/verify-and-troubleshoot#sdkrest-fallback)
for the full breakdown.

## Setup

### Endpoint

> **Note**
>
> On Claude Code and Codex, [GroundX Agent Harness](/documentation/agent-harness/install-ground-x-agent-harness)
> registers this server for you. Configuring it again attaches the same server twice.

Configure your MCP client to connect to the GroundX MCP endpoint:

```http
https://api.groundx.ai/mcp
```

The same server is also reachable at the equivalent path:

```http
https://api.groundx.ai/api/v1/mcp
```

Either URL works. Use whichever form your client's configuration expects.

For authenticated GroundX operations, connect to the product endpoint
`https://api.groundx.ai/mcp` (this page).

### Authentication

GroundX MCP supports two auth paths:

* **OAuth**: for interactive clients that can open a browser (for example Claude
  Desktop or Codex Desktop). The client discovers OAuth metadata, redirects to a
  GroundX-hosted authorization page, and receives short-lived MCP tokens. You never
  handle a raw key in this flow after the initial authorization.
* **`X-API-Key` transport**: for headless or non-interactive clients (for example
  Claude Code CLI, Codex CLI, Cursor, Replit, or CI runners). The key is sent as an
  `X-API-Key` HTTP header on the MCP transport connection:

```json
{
  "mcpServers": {
    "groundx": {
      "url": "https://api.groundx.ai/mcp",
      "headers": {
        "X-API-Key": "${GROUNDX_API_KEY}"
      }
    }
  }
}
```

Never place a raw API key inside a tool argument. The key belongs only in the
transport-layer header or the OAuth flow, never in `call_operation`, `search_content`,
or any other tool call payload.

## Available Tools

### Default Tools

A regular customer key sees the 12 default tools below. Which are **visible** in a given
session depends on the scopes granted to the connecting API key (see [Scope and Visibility](#scope-and-visibility) below), so a higher-scope key (for example a
Partner-tier key) may register additional tools beyond this set.

| Tool                               | Method | Path                                    | Derived scope    |
| ---------------------------------- | ------ | --------------------------------------- | ---------------- |
| `document_ingestremote`            | POST   | `/v1/ingest/documents/remote`           | `groundx:ingest` |
| `document_getprocessingstatusbyid` | GET    | `/v1/ingest/{processId}`                | `groundx:ingest` |
| `document_list`                    | GET    | `/v1/ingest/documents`                  | `groundx:ingest` |
| `document_get`                     | GET    | `/v1/ingest/document/{documentId}`      | `groundx:ingest` |
| `search_content`                   | POST   | `/v1/search/{id}`                       | `groundx:write`  |
| `search_documents`                 | POST   | `/v1/search/documents`                  | `groundx:write`  |
| `bucket_create`                    | POST   | `/v1/bucket`                            | `groundx:write`  |
| `bucket_list`                      | GET    | `/v1/bucket`                            | `groundx:read`   |
| `group_create`                     | POST   | `/v1/group`                             | `groundx:write`  |
| `group_list`                       | GET    | `/v1/group`                             | `groundx:read`   |
| `group_addbucket`                  | POST   | `/v1/group/{groupId}/bucket/{bucketId}` | `groundx:write`  |
| `health_get`                       | GET    | `/v1/health/{service}`                  | `groundx:read`   |

Always call these tools using the normalized lowercase name shown in the left column
(for example `document_ingestremote`), never a PascalCase `operationId` form.

### Always-Present Tools

In addition to the 12 default tools, 4 tools are always registered regardless of the
session's granted scopes:

* `groundx_account_context`
* `list_operations`
* `describe_operation`
* `call_operation`

`list_operations`, `describe_operation`, and `call_operation` are the 3 discovery
meta-tools that make advanced operations reachable. `groundx_account_context` takes no
input and returns the resolved account type, mode, granted scopes, base URL, and enabled
tool groups for the current session.

### Local-File Upload Tool

`document_uploadlocal` requires the `groundx:ingest` scope — the same scope
`document_ingestremote` requires, since a session that can't call
`document_ingestremote` to do anything with an uploaded file shouldn't be able to get
an upload target for one either. It isn't one of the 12 default tools above and isn't
reachable through `call_operation`. It takes `fileName` and `fileType`, and returns a
pre-signed upload target: the URL to PUT the file bytes to, the HTTP method, a
`header` map, and the hosted URL to submit to `document_ingestremote`.

This only works for MCP hosts that can read the local file and perform the HTTP PUT
themselves — not every MCP client can. A host limited to tool-calling alone can't
complete this flow, whether or not the tool exists.

`header` entries fall into three buckets:

* `Host` — the S3 upload host; HTTP clients normally set this automatically from
  `url`, so no action is usually needed.
* `GX-HOSTED-URL` (if present) — the same value as `hostedUrl`, riding along in
  `header` for convenience. It's the value to use as `sourceUrl` later — **not** a
  header to send to S3.
* Any other entries — send them as request headers on the PUT.

See [Local Files](#local-files) below for the full flow.

### Scope And Visibility

Which tools you see depends on your key's permissions. The rule that decides this, `operationAllowedByScopes(path,
method)`, applied both when filtering visible default tools and inside
`call_operation` before dispatch:

1. If the path contains `/ingest` → the required scope is `groundx:ingest`.
2. Otherwise, if the method is a write verb (POST, PUT, PATCH, or DELETE) → the
   required scope is `groundx:write`.
3. Otherwise → the required scope is `groundx:read`.

Both search tools (`search_content`, `search_documents`) use POST, so they require
`groundx:write`, not `groundx:read`. This is intentional.

A session granted only `groundx:read` sees a reduced set of the 12 default tools, only
the tools whose derived scope is `groundx:read`:

* `bucket_list`
* `group_list`
* `health_get`

All ingest-scoped and write-scoped default tools, including both search tools, are hidden
in a read-only session. The 4 always-present tools (the 3 discovery meta-tools plus
`groundx_account_context`) are present regardless of scope, but `call_operation` still
enforces `operationAllowedByScopes` before dispatch — a read-only session can't execute
write or ingest operations through it either. `document_uploadlocal` is a separate,
fifth tool that is **not** always-present: it requires `groundx:ingest`, as noted above.

The visible tools always follow the connecting key's scopes: a narrower key sees fewer of
the 12 default tools, and a higher-scope key (such as a Partner-tier key) registers
additional tools beyond them.

### Advanced Operations

Operations outside the default 12 (including bucket deletion, document deletion,
workflow management, and API key management) aren't registered as named MCP tools.
Reach them through the three always-present discovery meta-tools, in order:

1. **`list_operations({})`**: returns every operation exposed through MCP discovery,
   each with its `operationId`, `method`, `path`, `summary`, and `description`.
2. **`describe_operation({ "operationId": "<id>" })`**: returns the full parameter
   schema (`parameters[]` and `inputSchema`) for one operation, so you can build a
   valid `args` object.
3. **`call_operation({ "operationId": "<id>", "args": { ... } })`**: executes the
   operation and returns the proxied GroundX API result.

```json
call_operation({
  "operationId": "Bucket_delete",
  "args": { "bucketId": 12345 }
})
```

**The argument name is `operationId` in both `describe_operation` and
`call_operation`, never `operation_id`.** This is a common mistake; the underscored
form doesn't work.

Scope enforcement still applies inside `call_operation`, using the same rule
described above. A session with only `groundx:read` gets a scope error if it
attempts a write- or ingest-scoped operation this way; discovery doesn't bypass scope
checks. A few operations are further restricted regardless of scope: managing existing
API keys (listing, updating, or deleting) requires `groundx:admin`, and creating a new
API key isn't available through MCP at all; it's hidden from `list_operations` and
rejected by `call_operation` for every scope.

## Usage Notes

### Ingest And Search Workflow

The default tools above cover the standard bucket-create, ingest, poll, and search
sequence for answering questions from your own documents. For a full walkthrough of building an
agent-driven workflow that answers questions from your documents on top of
GroundX's hosted tools, see [Use GroundX With Your Agent](/documentation/agent-harness/ingest-search-and-answer-with-an-agent).

### Local Files

This works only if your MCP host can read the local file and perform the HTTP PUT
itself — not every MCP client can. If your host is limited to tool-calling with no
such capability, this path isn't reachable for it — fall back to the direct SDK/API
instead (below).

Call `document_uploadlocal({ "fileName": "...", "fileType": "..." })` to get a
pre-signed upload target, PUT the file's bytes to the returned `url` (sending the
`header` entries that need it — see [Local-File Upload Tool](#local-file-upload-tool)
above for which ones), then call `document_ingestremote` with the returned `hostedUrl`
as `sourceUrl`. This matches how the Python SDK's `client.ingest()` handles local files
internally.

```json
document_uploadlocal({ "fileName": "invoice", "fileType": "pdf" })
// → {
//     "url": "https://eyelevel-upload.s3.us-west-2.amazonaws.com/...",
//     "method": "PUT",
//     "header": {
//       "Host": ["eyelevel-upload.s3.us-west-2.amazonaws.com"],
//       "Gx-Hosted-Url": ["https://upload.eyelevel.ai/prod/file/ssp/....pdf"]
//     },
//     "hostedUrl": "https://upload.eyelevel.ai/prod/file/ssp/....pdf"
//   }
```

If you're integrating from application code rather than an MCP client, the GroundX SDKs
handle this pre-signed upload flow automatically. See [GroundX SDKs](/sdks/ground-x-sd-ks) and the [in-depth ingest guide](/documentation/guides/ingest-tutorial) for the direct-SDK equivalent.