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.
// 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:
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).
# 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:
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:
| Tool | Idempotency key required |
|---|
payments.initiate | yes |
cards.issue | yes |
transfer.schedule | yes |
x402.pay | yes |
yield.allocate | yes |
beneficiary.add | yes |
payroll.run | yes |
| All read tools | no |
agent.grant.issue | no |
killSwitch.all | no |
vault.rotateSigner | no |
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.