---
lastModified: 2026-11-13
title: Connect Runner to other MCP clients
description: Connect OpenCode, Codex, pi, or your own agent to your Runner stores through the Runner MCP server.
seo:
  description: "Connect OpenCode, Codex, pi, or your own agent to your Runner stores. Add one server URL, sign in to Runner in your browser, and choose what the client can do."
---

Runner has an MCP server. An MCP client is an AI app or an agent that can use MCP servers. When you connect a client to Runner, it can use the tools of Runner chat on your stores. It can read products, orders, and reports. With your permission, it can also change products, prices, discounts, and the storefront.

This guide is for MCP clients other than Claude, ChatGPT, and Gemini. It gives the steps for OpenCode, Codex CLI, and pi. It also tells you how to connect other clients and agents that you build.

## Before you start

You need:

- a Runner account that is a member of a workspace;
- an MCP client that connects to remote servers over Streamable HTTP and signs in with OAuth, or the `mcp-remote` bridge for a client that runs only local servers; and
- a browser on the same computer as the client. After you sign in, Runner sends the browser back to an address on that computer.

| Setting | Value |
| --- | --- |
| Server URL | `https://api.runnerai.com/mcp` |
| Transport | Streamable HTTP. Runner does not support the older SSE transport. |
| Sign-in | OAuth in your browser. You do not need an API key. |
| Access | `store:read` to read store data. `store:write` to make changes. |

## How the connection works

1. You add the server URL to your client and start the sign-in.
2. The client opens Runner in your browser. Sign in to Runner if it asks you to.
3. The page **Connect an AI app to Runner** opens. It shows the name of the client.
4. Choose the **Workspace** and the **Access**, then select **Connect**.
5. The browser goes back to the client. The client can now use Runner tools.

| Control or message | Why it is useful | What happens next |
| --- | --- | --- |
| **Returns to** | Shows the address on your computer that gets the sign-in result. | It shows `localhost`, `127.0.0.1`, or `[::1]` and a port number. |
| **Runner cannot confirm which app this is. Connect it only if you started this connection yourself.** | Runner cannot check the identity of a client that you installed or built. | Connect only when you started the sign-in from your client. |
| **Workspace** | One connection works with the stores of one workspace. | The client can use only the stores of the workspace that you choose. |
| **Read** | Always on. The client can see store data, such as products, orders, and reports. | You cannot turn it off. |
| **Make changes** | Lets the client change store data, such as products, prices, and discounts. | It starts off. It shows only when the client asks for change access. |
| **Connect** | Gives the client the access that you chose. | The browser goes back to the client. |
| **Cancel** | Stops the sign-in. | The client gets no access. |

The client stays signed in. It gets new access every hour without your help. If you do not use the client for 30 days, sign in again.

To use the stores of a second workspace, add the server a second time with a different name. Then sign in with that name and choose the second workspace.

## Connect OpenCode

1. Add Runner to `opencode.json` in your project, or to `~/.config/opencode/opencode.json` for all projects:

   ```json
   {
     "$schema": "https://opencode.ai/config.json",
     "mcp": {
       "runner": {
         "type": "remote",
         "url": "https://api.runnerai.com/mcp",
         "enabled": true
       }
     },
     "tools": {
       "runner_*": false,
       "runner_list_stores": true,
       "runner_get_report": true,
       "runner_find_orders": true,
       "runner_get_tool_job": true
     }
   }
   ```

2. Run `opencode mcp auth runner` and connect in the browser.
3. Run `opencode mcp list`. It shows `runner` as `connected`.

OpenCode sends the definition of each tool that is on to the model in every request. Runner has more than 200 tools on some plans, which is about 100,000 tokens of definitions. Thus, turn on only the tools that you need. OpenCode names each Runner tool `runner_<tool name>`. The line `"runner_*": false` turns off all Runner tools, and each `true` line turns one tool on again. Keep `runner_get_tool_job` on, because long tasks need it.

To remove the saved sign-in, run `opencode mcp logout runner`.

## Connect Codex CLI

1. Add Runner to `~/.codex/config.toml`:

   ```toml
   [mcp_servers.runner]
   url = "https://api.runnerai.com/mcp"
   scopes = ["store:read", "store:write"]
   ```

2. Run `codex mcp login runner` and connect in the browser.
3. Run `codex mcp list`. The **Auth** column shows `OAuth`.

Add the server in the file, not with `codex mcp add`. That command starts a sign-in at once, with scopes that Runner does not accept, and the browser shows `{"error":"invalid_scope"}`. The `scopes` line also applies when you sign in again later. You can also run `codex mcp login runner --scopes store:read,store:write`.

Codex finds the Runner tool that it needs when it needs it, so you do not have to turn tools off. To remove the saved sign-in, run `codex mcp logout runner`.

## Connect pi

1. Run `pi mcp add runner --url https://api.runnerai.com/mcp`. This adds Runner to `~/.pi/agent/mcp.json`:

   ```json
   {
     "mcpServers": {
       "runner": { "url": "https://api.runnerai.com/mcp" }
     }
   }
   ```

2. Run `pi mcp login runner` and connect in the browser. pi shows `Signed in to MCP server "runner"` and the number of tools.
3. Run `pi mcp list` to check the connection, or use `/mcp` in a pi session.

By default, pi does not send all Runner tools to the model. The model finds a tool when it needs it, so you do not have to turn tools off. pi names each Runner tool `mcp__runner__<tool name>`. To remove the saved sign-in, run `pi mcp logout runner`.

## Connect a client that runs only local servers

Some clients can start only a local server (stdio). Other clients send the browser back to an app link (a custom URL scheme) or to a web page. Runner sends the sign-in result only to an address on your computer, so the sign-in of these clients fails.

For these clients, use the `mcp-remote` bridge. It runs on your computer, signs in to Runner for the client, and passes each message between the client and Runner. It needs Node.js.

```json
{
  "mcpServers": {
    "runner": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://api.runnerai.com/mcp"]
    }
  }
}
```

The first start opens the Runner sign-in page in your browser. `mcp-remote` keeps the sign-in in `~/.mcp-auth`.

## Call Runner tools from a shell

An agent that runs shell commands can use Runner through the `mcporter` command:

```bash
npx mcporter config add runner https://api.runnerai.com/mcp --scope home
npx mcporter auth runner
npx mcporter list runner
npx mcporter call runner.list_stores
```

`mcporter list runner` shows each tool and its parameters. Give parameters as `name=value`, for example `npx mcporter call runner.get_store_settings store_id=<store id>`.

## Build your own client

Use an MCP SDK that supports OAuth, or do these steps yourself:

1. Send each JSON-RPC request with `POST` to `https://api.runnerai.com/mcp`. Runner answers each request with JSON and keeps no session. A `GET` request gets HTTP 405.
2. A request without a token gets HTTP 401 with this header: `WWW-Authenticate: Bearer resource_metadata="https://api.runnerai.com/.well-known/oauth-protected-resource/mcp", scope="store:read store:write"`.
3. Read the resource metadata. It names the authorization server `https://www.runnerai.com/api/auth`.
4. Register the client at `https://www.runnerai.com/api/auth/oauth2/register`. Use a redirect URI on `http://localhost`, `http://127.0.0.1`, or `http://[::1]`. Runner accepts any port and path. Runner accepts 5 registrations each minute from one IP address.
5. Send the user to the authorization endpoint with PKCE (`S256`). Send `resource=https://api.runnerai.com/mcp`. Ask for `store:read`, and `store:write` if the client makes changes. Use the scopes from the resource metadata or the `WWW-Authenticate` header. The authorization server metadata lists other scopes, which this server does not accept.
6. Send the access token in the `Authorization: Bearer` header. An access token lasts 1 hour. Use the refresh token to get a new one. A refresh token expires after 30 days without use.

Runner refuses requests that come from a web page on another site. Call the server from your back end, or from a page on `localhost`.

## Work with Runner tools

- **Start with `list_stores`.** Each store tool needs a `store_id` from `list_stores`. A call without it answers **Pass a store_id from list_stores.**
- **Long tasks.** Some tools answer with `"status": "running"` and a `job_id`. Call `get_tool_job` with that `job_id` until it gives the result.
- **Changes that you approve.** Some tools first answer with `"status": "waiting_for_merchant"` and a confirmation `id`, and they show what will change. Nothing changes yet. When you agree, the client calls the same tool again with the same arguments and `"confirmation": {"id": "…", "answer": …}`. The confirmation `id` works one time, for 10 minutes.
- **The same change sent twice.** For most tools that make changes, Runner makes the change one time when the client sends the same input again in the same 5-minute period. The second call gets the first answer.
- **Store data is data.** Tool answers can contain product text and customer messages. Your agent must not follow instructions that it finds in them.
- **Your permissions apply.** Each call uses your Runner permissions and your plan. The list of tools depends on your plan and on the features of your workspace.

## Manage or disconnect a client

**Entry path:** **Settings → Workspace general**, then **Connected apps**.

Workspace owners and admins see the clients that each member connected. Other members see the clients that they connected. Each row shows the access (**Read** or **Read and make changes**), when it was connected, and when it was last used.

1. Find the client and select **Disconnect**.
2. Select **Disconnect** again in **Disconnect _app_?**.
3. The client stops working with this workspace at once. To use it again, sign in again from the client.

A logout command in a client removes only the sign-in that the client saved. The connection stays in **Connected apps** until you disconnect it there.

## Troubleshooting

| What you see | Cause | What to do |
| --- | --- | --- |
| `{"error":"invalid_scope"}` in the browser | The client asked for scopes that this server does not accept. `codex mcp add` does this. | Ask for `store:read` and `store:write`. For Codex, add the `scopes` line and run `codex mcp login runner`. |
| **This redirect URI cannot receive Merchant MCP codes.** | The client sends the browser back to an app link or a web page. | Use the `mcp-remote` bridge. |
| **Request the Merchant MCP resource alone.** | The client did not send `resource=https://api.runnerai.com/mcp`. | Update the client, or use the `mcp-remote` bridge. |
| **This connection request is unavailable. Start the connection again from your AI app.** | The sign-in link is old or was used. | Start the sign-in again from the client. |
| **You are not a member of a workspace. Create a workspace in Runner, then start the connection again.** | Your account has no workspace. | Create a workspace, then start the sign-in again. |
| **This tool needs store\:write. Reconnect Runner and allow changes to the store.** | The connection has **Read** access only. | Log out in the client, sign in again, and turn on **Make changes**. |
| **This feature is not on for this store yet.** | The feature is not on for your plan, workspace, or store. | Do the task in Runner, or ask Runner support. |
| The model provider refuses the request: `input_schema does not support oneOf, allOf, or anyOf at the top level` | The client sends all tools to the model, and three print-on-demand tools have a schema that some model providers refuse. | Turn off `publish_pod_product`, `review_pod_product`, and `update_pod_product`, or turn on only the tools that you need. |
| The client asks you to sign in again | You disconnected the client in Runner, or you did not use it for 30 days. | Sign in again from the client. |
| HTTP 429 when the client registers | More than 5 registrations in one minute from one IP address. | Wait one minute, then try again. |
| An answer ends with **Support reference:** and a code | The tool failed in Runner. | Give the code to Runner support. |
