Skip to main content

Documentation Index

Fetch the complete documentation index at: https://glide-9da73dea.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

This page is the single source of truth for the curl auth-header pattern, the TypeScript thin wrapper (glide-client.ts), and the Python thin wrapper (glide_client.py). Paste either file into your project to make every per-tool code example on this site runnable as-is — no extra dependencies beyond fetch (built-in) for TypeScript and httpx for Python.

curl reference

Every curl example on this site follows the same pattern:
curl -X POST https://mcp.glide.co/mcp/{category} \
  -H "Authorization: Bearer $GLIDE_GRANT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"<tool>","params":{...}}'
Replace {category} with read, write, or treasury depending on the tool. The per-tool pages show which endpoint to use in each example. Environment variable: Store your grant token in GLIDE_GRANT_TOKEN. Never hard-code tokens in scripts — they appear in shell history and process listings. Content-Type: Always application/json. The server rejects requests without this header. Idempotency key: For tools that require one (Idempotency key required: yes in the Metadata table), add the header:
-H "Idempotency-Key: <your-idempotency-key>"
The key must also be present in params.idempotency_key for the tool to validate it end-to-end. Base URL: The base URL is category-prefixed. Use https://mcp.glide.co/mcp/read for read tools, https://mcp.glide.co/mcp/write for write tools, and https://mcp.glide.co/mcp/treasury for treasury tools. Calling a tool on the wrong category endpoint returns a confused-deputy error. Each per-tool page shows the correct endpoint in its curl example.

TypeScript wrapper

Save as glide-client.ts in your project. Requires Node 18+ for native fetch.
TypeScript
// glide-client.ts
// Thin JSON-RPC 2.0 wrapper for the Glide MCP API.
// Requires: fetch (Node 18+ built-in, or the `node-fetch` polyfill for Node 16).

export type McpCategory = 'read' | 'write' | 'treasury';

export interface GlideClientOptions {
  /** Glide grant JWT — obtain via the OAuth flow or agent.grant.issue. */
  grantToken: string;
  /** Override the base origin. Defaults to https://mcp.glide.co. */
  baseOrigin?: string;
}

export interface CallOptions {
  /** Idempotency key header — required for non-idempotent tools (payments, cards, schedules). */
  idempotencyKey?: string;
}

/** Returned instead of throwing when the server signals step-up is required (code -32003). */
export class StepUpRequired {
  readonly kind = 'StepUpRequired' as const;
  constructor(
    public readonly stepUpUrl: string,
    public readonly message: string,
  ) {}
}

export interface JsonRpcErrorData {
  reason_id?: string;
  correlation_id?: string;
  retry_after_seconds?: number;
  step_up_url?: string;
  sigil?: string;
}

export class GlideApiError extends Error {
  constructor(
    public readonly code: number,
    message: string,
    public readonly data?: JsonRpcErrorData,
  ) {
    super(`Glide API error ${code}: ${message}`);
    this.name = 'GlideApiError';
  }
}

export class GlideClient {
  private readonly baseOrigin: string;
  private readonly grantToken: string;
  private idSeq = 0;

  constructor(options: GlideClientOptions) {
    this.grantToken = options.grantToken;
    this.baseOrigin = options.baseOrigin ?? 'https://mcp.glide.co';
  }

  /**
   * Call a Glide MCP tool.
   *
   * @param category - 'read', 'write', or 'treasury'. Must match the tool's category
   *   or the server returns a confused-deputy error. See the per-tool page for the
   *   correct category.
   * @param method - JSON-RPC method name (e.g. 'accounts.list').
   * @param params - Tool input params.
   * @param options - Optional idempotency key and other call options.
   *
   * Returns the result on success.
   * Returns a `StepUpRequired` discriminator on error code -32003 instead of
   * throwing — so callers can redirect the user to the step-up URL.
   * Throws `GlideApiError` for all other error responses.
   */
  async call<T = unknown>(
    category: McpCategory,
    method: string,
    params: unknown,
    options?: CallOptions,
  ): Promise<T | StepUpRequired> {
    const id = ++this.idSeq;
    const url = `${this.baseOrigin}/mcp/${category}`;
    const headers: Record<string, string> = {
      'Authorization': `Bearer ${this.grantToken}`,
      'Content-Type': 'application/json',
    };
    if (options?.idempotencyKey) {
      headers['Idempotency-Key'] = options.idempotencyKey;
    }

    const response = await fetch(url, {
      method: 'POST',
      headers,
      body: JSON.stringify({ jsonrpc: '2.0', id, method, params }),
    });

    if (!response.ok) {
      throw new GlideApiError(
        response.status,
        `HTTP ${response.status} ${response.statusText}`,
      );
    }

    const body = (await response.json()) as {
      jsonrpc: '2.0';
      id: number;
      result?: T;
      error?: { code: number; message: string; data?: JsonRpcErrorData };
    };

    if (body.error) {
      const { code, message, data } = body.error;
      // Step-up: return a discriminator so callers can redirect without try/catch.
      if (code === -32003 && data?.step_up_url) {
        return new StepUpRequired(data.step_up_url, message);
      }
      throw new GlideApiError(code, message, data);
    }

    return body.result as T;
  }
}
Usage pattern for step-up tools:
TypeScript
const result = await client.call('write', 'payments.initiate', { ... });

if (result instanceof StepUpRequired) {
  // Redirect the user; collect the sigil from your callback route.
  window.location.href = result.stepUpUrl;
  return;
}
// result is the typed response object.
console.log('Payment enqueued:', result.pending_payment_id);

Python wrapper

Save as glide_client.py. Requires httpx (pip install httpx).
Python
# glide_client.py
# Thin JSON-RPC 2.0 wrapper for the Glide MCP API.
# Requires: httpx (pip install httpx)

from __future__ import annotations

import os
from typing import Any, NamedTuple, Optional

import httpx

DEFAULT_BASE_ORIGIN = "https://mcp.glide.co"


class StepUpRequired(NamedTuple):
    """Returned instead of raising when the server signals step-up required (code -32003)."""
    step_up_url: str
    message: str


class GlideApiError(Exception):
    def __init__(self, code: int, message: str, data: Optional[dict] = None) -> None:
        super().__init__(f"Glide API error {code}: {message}")
        self.code = code
        self.data = data or {}


class GlideClient:
    """
    Synchronous Glide MCP client.

    Args:
        grant_token: Glide grant JWT. Pass explicitly or set GLIDE_GRANT_TOKEN env var.
        base_origin: Override the MCP base origin. Defaults to https://mcp.glide.co.
        timeout: Request timeout in seconds. Defaults to 30.
    """

    def __init__(
        self,
        grant_token: Optional[str] = None,
        base_origin: Optional[str] = None,
        timeout: float = 30.0,
    ) -> None:
        self._grant_token = grant_token or os.environ["GLIDE_GRANT_TOKEN"]
        self._base_origin = base_origin or DEFAULT_BASE_ORIGIN
        self._timeout = timeout
        self._id_seq = 0

    def call(
        self,
        category: str,
        method: str,
        params: Any,
        idempotency_key: Optional[str] = None,
    ) -> Any:
        """
        Call a Glide MCP tool.

        Args:
            category: 'read', 'write', or 'treasury'. Must match the tool's category
                or the server returns a confused-deputy error.
            method: JSON-RPC method name (e.g. 'accounts.list').
            params: Tool input params.
            idempotency_key: Required for non-idempotent tools.

        Returns the result dict on success.
        Returns a StepUpRequired namedtuple on error code -32003 instead of raising —
        so callers can redirect the user to the step-up URL.
        Raises GlideApiError for all other error responses.
        """
        self._id_seq += 1
        url = f"{self._base_origin}/mcp/{category}"
        headers = {
            "Authorization": f"Bearer {self._grant_token}",
            "Content-Type": "application/json",
        }
        if idempotency_key:
            headers["Idempotency-Key"] = idempotency_key

        payload = {
            "jsonrpc": "2.0",
            "id": self._id_seq,
            "method": method,
            "params": params,
        }

        with httpx.Client(timeout=self._timeout) as http:
            response = http.post(url, json=payload, headers=headers)

        response.raise_for_status()
        body = response.json()

        if "error" in body:
            error = body["error"]
            code: int = error["code"]
            message: str = error["message"]
            data: dict = error.get("data", {})

            # Step-up: return a namedtuple instead of raising.
            if code == -32003 and data.get("step_up_url"):
                return StepUpRequired(step_up_url=data["step_up_url"], message=message)

            raise GlideApiError(code, message, data)

        return body["result"]
Usage pattern for step-up tools:
Python
from glide_client import GlideClient, StepUpRequired

client = GlideClient()  # reads GLIDE_GRANT_TOKEN from env

result = client.call("write", "payments.initiate", {
    "counterparty": {"address": "0xd8dA6BF26...", "chain": "base", "token": "USDC"},
    "amount_cents": 150000,
    "currency": "USD",
    "idempotency_key": "payment-may04-001",
})

if isinstance(result, StepUpRequired):
    print(f"Redirect user to: {result.step_up_url}")
else:
    print("Payment enqueued:", result["pending_payment_id"])

Idempotency keys

Set an idempotency key on any tool call that can have side effects — payments, card issuance, scheduled transfers, beneficiary mutations, and yield allocations. The key ensures that retrying a failed request never double-executes the operation. When to set one:
ToolIdempotency key required
payments.initiateyes
cards.issueyes
transfer.scheduleyes
x402.payyes
yield.allocateyes
beneficiary.addyes
payroll.runyes
All read toolsno
agent.grant.issueno
killSwitch.allno
vault.rotateSignerno
Format: Any string 8–128 characters long. Use a deterministic key derived from the operation’s business meaning — payment-{orderId}, sched-payroll-{date}-{recipientId}, x402-{resourceHash}-{agentRunId}. UUIDs work but don’t survive process restarts without persistence. Scope: Keys are scoped to (agent_principal_id, tool_name) — the same key is safe to reuse across different tools.

Reading list

  • OAuth flow — how to obtain a grant token using client_credentials.
  • Policy envelope — the policy contract the server enforces on every call.
  • Step-up flow — the full biometric approval sequence for step-up gated tools.
  • Receipts — the audit trail format for every money-moving tool call.
  • All 22 tools — the complete tool reference table.