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

# Gateway Bridge

> Route tool calls through the gateway with full custody, trace continuity, and agent state.

The **bridge** is the client-side counterpart to the [gateway](/docs/gateway). It provides functions to route tool execution through the gateway while preserving custody chains, agent state, and trace context across network boundaries.

Bridge functions are exported from `sec0-sdk/middleware`.

## `callToolViaGateway`

The standard bridge function for routing tool calls through the gateway:

```typescript theme={null}
import { callToolViaGateway } from "sec0-sdk/middleware";

const result = await callToolViaGateway({
  gatewayBaseUrl: "https://your-gateway:8088",
  server: "vision-mcp",
  toolAtVersion: "fetch@1.0",
  args: {
    url: "https://api.example.com/resource/123",
    method: "PUT",
    body: { status: "approved" },
  },
  authHeader: `Bearer ${userAccessToken ?? process.env.SVC_TOKEN}`,
  cause: { traceId: ctx.traceId, spanId: ctx.spanId },
  agentState: manager.agent.snapshot(),
});
```

### Parameters

| Parameter         | Type              | Required | Description                   |
| ----------------- | ----------------- | -------- | ----------------------------- |
| `gatewayBaseUrl`  | string            | Yes      | Gateway base URL              |
| `server`          | string            | Yes      | Tool server name              |
| `toolAtVersion`   | string            | Yes      | Tool name\@version            |
| `args`            | any               | No       | Tool arguments                |
| `authHeader`      | string            | No       | Authorization header          |
| `cause.traceId`   | string            | Yes      | Parent trace ID               |
| `cause.spanId`    | string            | Yes      | Parent span ID                |
| `agentState`      | AgentStatePayload | No       | Agent state to forward        |
| `tenant`          | string            | No       | Tenant override               |
| `runId`           | string            | No       | Graph run identifier          |
| `nodeId`          | string            | No       | Graph node identifier         |
| `traceparent`     | string            | No       | W3C traceparent header        |
| `baggage`         | string            | No       | W3C baggage header            |
| `idempotencySalt` | string            | No       | Extra entropy for idempotency |
| `timeoutMs`       | number            | No       | Request timeout (ms)          |

### AP2 Mandate Forwarding

```typescript theme={null}
const result = await callToolViaGateway({
  // ...standard options...
  ap2: {
    intent: intentMandateJwt,
    cart: cartMandateJwt,
    bundle: bundlePayload,
  },
});
```

### Identity Context Forwarding

```typescript theme={null}
const result = await callToolViaGateway({
  // ...standard options...
  identity: {
    authorization: "Bearer ...",
    tenant: "acme",
    roles: ["admin", "agent-operator"],
    userId: "user@acme.com",
    userHash: "sha256-of-user-id",
  },
});
```

## `callToolViaGatewayWithAgent`

A convenience wrapper that accepts an `agent` block instead of a raw `agentState`:

```typescript theme={null}
import { callToolViaGatewayWithAgent } from "sec0-sdk/middleware";

const result = await callToolViaGatewayWithAgent({
  gatewayBaseUrl: "https://your-gateway:8088",
  server: "vision-mcp",
  toolAtVersion: "fetch@1.0",
  args: { url: "https://api.example.com/data" },
  authHeader: `Bearer ${userAccessToken ?? process.env.SVC_TOKEN}`,
  cause: { traceId, spanId },
  agent: {
    nodeId: "planner",
    runId: "run-123",
    variables: {
      AGENT: { objective: "Fetch patient records" },
    },
    metadata: { model: "gpt-4o" },
  },
});
```

## `buildIdempotencyKey`

Generate a deterministic idempotency key for a tool call:

```typescript theme={null}
import { buildIdempotencyKey } from "sec0-sdk/middleware";

const key = buildIdempotencyKey({
  runId: "run-123",
  nodeId: "planner",
  toolAtVersion: "fetch@1.0",
  args: { url: "https://api.example.com" },
  salt: "optional-extra-entropy",
});
```

The helper combines `runId`, `nodeId`, `toolAtVersion`, and a short digest of `args`. Pass a stable `runId` and `nodeId` when you want deterministic replay protection; if `runId` is omitted, the helper generates one and the result changes across runs.

## Using Bridge with Instrumentation Decorators

When using decorators, the `AgentManager` makes gateway calls seamless:

```typescript theme={null}
import { sec0, AgentManager } from "sec0-sdk/instrumentation";

class Workflow {
  @sec0.orchestrator()
  async orchestrate(ctx: any, input: any, manager: AgentManager) {
    manager.agent.objective("Process order workflow");

    // Invoke a gateway hop by key; gateway config is resolved from sec0.config.yaml
    await manager.invoke("GatewayHop.forward", {
      server: "orders-mcp",
      toolAtVersion: "createOrder@1.0",
      args: { customerId: input.customerId },
    });

    return { ok: true };
  }
}
```

The `manager.invoke()` call automatically:

1. Resolves the gateway hop config from `app.hops`
2. Builds the agent state from the current context
3. Injects auth headers, idempotency keys, and cause context (per automation flags)
4. Issues the gateway call with full custody chain

For the full bridge options reference, see [Bridge Options Reference](/docs/reference/bridge-options).
