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

# Remote MCP (hosted)

> Connect Grok Bot, cloud runners, and any MCP client that cannot run a local process to OneShot's hosted endpoint

## When to use it

The [local MCP server](/sdk/mcp) runs on your machine and signs x402 payments with your wallet. That works for Claude Desktop, Cursor, and Claude Code, which spawn a local process. It does not work for agents that run in someone else's cloud — Grok Bot, hosted runners, agent platforms — because they cannot reach a process on your machine, and you should never paste a wallet key into a third-party cloud.

The hosted endpoint is the same 50 tools over **Streamable HTTP**, authenticated with an **agent access token** and billed to your agent's **credit balance**.

|           | Local server                                     | Hosted endpoint                                          |
| --------- | ------------------------------------------------ | -------------------------------------------------------- |
| Transport | stdio (`npx @oneshot-agent/mcp-server`)          | Streamable HTTP, `POST https://win.oneshotagent.com/mcp` |
| Identity  | your wallet (signs x402 + read proofs)           | an access token minted by your wallet                    |
| Pays with | USDC from your wallet                            | your agent's prepaid credits                             |
| Budgets   | `ONESHOT_BUDGET_*` env, read-only from the model | set from a wallet session, read-only from the token      |

Staging: `https://api-stg.oneshotagent.com/mcp`.

## 1. Mint an access token

From any wallet session of the TypeScript SDK (≥ 0.33.0):

```typescript theme={null}
import { OneShot } from '@oneshot-agent/sdk';

const agent = await OneShot.create({ cdp: true }); // or { privateKey }
const { token, id } = await agent.createAccessToken({ name: 'grok-bot' });
console.log(token); // oneshot_… — shown once, never stored server-side
```

A token is a delegated, revocable credential. It identifies your agent, can spend only from the agent's credit balance under the agent's stored budget, and can never sign x402, change budgets, or mint other tokens. Revoke it any time with `agent.revokeAccessToken(id)`; `agent.listAccessTokens()` shows each token's label, last use, and credit-funded spend today.

<Note>
  Prefer the SDK, but the raw routes are `POST/GET/DELETE /v1/agents/me/access-tokens`, wallet-signed (`X-Agent-ID` + `x-agent-proof`). Operators can also mint for a partner via `POST /v1/tools/internal/agents/access-tokens`.
</Note>

## 2. Add credits

Hosted sessions pay from credits only. Until self-serve top-up ships, credits are added by the OneShot operator (`POST /v1/tools/internal/credits/grant`). A call the balance cannot cover comes back as a tool result with `isError: true` and this body:

```json theme={null}
{
  "error": "insufficient_credits",
  "message": "This call costs $0.010000 USDC but the credit balance is $0.002500 …",
  "required_usdc": "0.010000",
  "credits_balance": "0.002500",
  "shortfall_usdc": "0.007500"
}
```

Top up and retry — unlike `budget_exceeded`, nothing about the call itself was refused.

## 3. Connect a client

<Tabs>
  <Tab title="Grok Bot">
    In Grok Bot's MCP/tools settings choose **Add server** and enter:

    * **Name**: `oneshot`
    * **URL**: `https://win.oneshotagent.com/mcp`
    * **Header**: `Authorization: Bearer oneshot_…`

    Grok Bot connects, lists the 50 tools, and runs them against your agent's credits. No OAuth step is involved.
  </Tab>

  <Tab title="Cursor">
    `.cursor/mcp.json` (keep the token in an environment variable, not in the file):

    ```json theme={null}
    {
      "mcpServers": {
        "oneshot": {
          "url": "https://win.oneshotagent.com/mcp",
          "headers": { "Authorization": "Bearer ${env:ONESHOT_ACCESS_TOKEN}" }
        }
      }
    }
    ```
  </Tab>

  <Tab title="Claude Code">
    ```bash theme={null}
    claude mcp add --transport http oneshot https://win.oneshotagent.com/mcp \
      --header "Authorization: Bearer $ONESHOT_ACCESS_TOKEN"
    ```
  </Tab>

  <Tab title="Any MCP client">
    Streamable HTTP, stateless, POST only. Send `Accept: application/json, text/event-stream` and `Authorization: Bearer <token>`; responses stream as SSE. With the TypeScript MCP SDK:

    ```typescript theme={null}
    import { Client } from '@modelcontextprotocol/sdk/client/index.js';
    import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';

    const transport = new StreamableHTTPClientTransport(new URL('https://win.oneshotagent.com/mcp'), {
      requestInit: { headers: { Authorization: `Bearer ${process.env.ONESHOT_ACCESS_TOKEN}` } },
    });
    const client = new Client({ name: 'my-agent', version: '1.0.0' });
    await client.connect(transport);
    const { tools } = await client.listTools(); // 50
    const result = await client.callTool({ name: 'oneshot_web_search', arguments: { query: 'oneshot agent' } });
    ```
  </Tab>
</Tabs>

## Budgets

Budgets set on the agent (`agent.budgets`, `PUT /v1/agents/me/budgets` from a wallet session) apply to hosted sessions too, and for them **credit-funded spend counts** toward the daily cap — credits are what a hosted session pays with. When the cap is hit a tool call returns `isError: true` with:

```json theme={null}
{ "error": "budget_exceeded", "reason": "daily", "cap": 5, "spent": 5, "charge": 0.01, "resets_at": "2026-09-09T00:00:00.000Z" }
```

`oneshot_budget_status` works from a hosted session and reports spend the same way the gate measures it. Budgets cannot be changed from a token — a cap the model could raise is not a cap.

## Local server with a token

The local `@oneshot-agent/mcp-server` (≥ 0.20.0) also accepts `ONESHOT_ACCESS_TOKEN` in place of wallet credentials, for the same credits-only behaviour on your own machine. `ONESHOT_BUDGET_*` cannot be combined with it.

## Troubleshooting

| Symptom                               | Cause                                                                           |
| ------------------------------------- | ------------------------------------------------------------------------------- |
| `401` with `WWW-Authenticate: Bearer` | Missing, malformed, unknown, or revoked token (`error` says which).             |
| `405`                                 | GET or DELETE: the endpoint is stateless, POST only.                            |
| `406`                                 | `Accept` must include both `application/json` and `text/event-stream`.          |
| `429 too_many_attempts`               | Repeated bad tokens from one IP lock that token prefix for 1 minute → 24 hours. |
| tool result `insufficient_credits`    | Add credits to the agent.                                                       |
| tool result `budget_exceeded`         | Raise the budget from a wallet session or wait for `resets_at`.                 |
