Custom clients and SDKs

Custom clients and SDKs

MCP is an open standard. Any conforming client connects with the details below: another editor, an agent framework, or code you wrote yourself.

Server URL
https://mcp.glitchads.ai/mcp

The connection contract

Transport Streamable HTTP: POST and GET on the single /mcp endpoint. The deprecated HTTP and SSE transport is not offered.
Sessions Stateless. No Mcp-Session-Id is required: every request authenticates with its own bearer token.
Auth, interactive OAuth 2.1 with PKCE (S256). Discovery through /.well-known/oauth-protected-resource/mcp, which names the authorization server https://api.glitchads.ai. Public clients only: token_endpoint_auth_method is none. Dynamic Client Registration and Client ID Metadata Documents are both supported, and the authorization server metadata advertises client_id_metadata_document_supported. The authorization request must send resource (RFC 8707) with the value https://mcp.glitchads.ai/mcp.
Auth, headless Authorization: Bearer glads_live_… with an API key. Test keys (glads_test_) are not available yet.
Instructions The initialize response carries instructions that tell the assistant to ask which organization to use and to show a preview before making a change.
Tools Twenty-one, all annotated. List tools paginate.
Arguments Unknown arguments are dropped without an error. A misspelled dry_run is ignored, so the call returns a preview instead of making the change.
Errors Tool errors return isError: true with a structured envelope.

Generic configuration

Most MCP capable applications take one of these shapes. Only the key name varies between them: url, serverUrl, or a type of http.

{ "mcpServers": { "glitch": { "url": "https://mcp.glitchads.ai/mcp" } } }
// headless: add the header, and reference the key from the environment
{
  "mcpServers": {
    "glitch": {
      "url": "https://mcp.glitchads.ai/mcp",
      "headers": { "Authorization": "Bearer ${GLITCH_API_KEY}" }
    }
  }
}

Python

# pip install "mcp>=2"
import asyncio
import os

import httpx2
from mcp import Client
from mcp.client.streamable_http import streamable_http_client

async def main():
    headers = {"Authorization": f"Bearer {os.environ['GLITCH_API_KEY']}"}
    async with httpx2.AsyncClient(headers=headers, timeout=httpx2.Timeout(30, read=300)) as http:
        transport = streamable_http_client("https://mcp.glitchads.ai/mcp", http_client=http)
        async with Client(transport) as client:
            tools = await client.list_tools()  # 21 glitch_* tools
            result = await client.call_tool(
                "glitch_get_performance",
                {"organization": "acme", "from": "2026-07-01", "to": "2026-07-07"},
            )
            print(result.content[0].text)

asyncio.run(main())

TypeScript

// npm install @modelcontextprotocol/sdk zod
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";

const transport = new StreamableHTTPClientTransport(
  new URL("https://mcp.glitchads.ai/mcp"),
  { requestInit: { headers: { Authorization: `Bearer ${process.env.GLITCH_API_KEY}` } } }
);

const client = new Client({ name: "my-agent", version: "1.0.0" });
await client.connect(transport);

const res = await client.callTool({
  name: "glitch_run_detector",
  arguments: { organization: "acme", campaign: "acme-prospecting", detector: "no_conversion_keywords" },
});

Agent frameworks

Frameworks with MCP support take the same URL plus the Authorization header. One rule for anyone building a loop that runs on its own:

  • Honour the annotations. A tool with readOnlyHint: false can change things, and destructiveHint: true marks the four that change a running campaign. Gate those behind human confirmation, or run them with dry_run: true and read the preview in code. The server side guardrails hold regardless, but your users will thank you.

Test keys (glads_test_) are not available yet, so there is no sandbox organization to build against. Until there is, use dry_run previews to check what a write would do.

If you do not need MCP semantics at all, the REST API exposes the same operations directly.

Check it worked

  • tools/list returns the tools.
  • glitch_list_organizations returns the organizations the connection covers, with your role in each; every other tool that takes organization requires it.
  • An unauthenticated request returns 401 with a WWW-Authenticate header pointing at the resource metadata, which means discovery is working.
  • The tool list shows 21 tools named glitch_*.

Ask: "List my Glitch organizations." You should get back the organizations your connection covers, with your role in each.

Troubleshooting

401 with a key set The server answers 401 only when the header is missing or malformed. Check it is exactly Authorization: Bearer glads_live_…, with the Bearer prefix and the whole key.
Tools list, but every call returns unauthorized The server does not validate API keys when you connect: it passes them to the API with each tool call. A revoked or expired key still connects and lists the tools, and every tool call returns isError: true with unauthorized. Check the key is active and unexpired, and that the user who created it still belongs to the organization.
insufficient_scope The error names the scope that is missing. Create a key carrying it, or reconnect and approve it. If your Glitch role does not allow it, ask an organization Admin or Owner.
org_access_denied The organization slug is wrong, your Glitch user is not a member of that organization, or the membership ended. glitch_list_organizations shows the slugs you can use.
Revoking access Revoke the key or the connection in Glitch under Account, API Keys, where connections are listed under Connected apps. Either stops access on the next request.
OAuth fails at discovery Your client has to fetch /.well-known/oauth-protected-resource/mcp, follow it to the authorization server at https://api.glitchads.ai, and support PKCE S256. It must register or identify itself as a public client (token_endpoint_auth_method none), through Dynamic Client Registration or a Client ID Metadata Document, and send resource set to https://mcp.glitchads.ai/mcp on the authorization request. Without resource the request fails with invalid_target. A client without OAuth support should use an API key.
It works locally and fails from a server The endpoint is public, so check your egress rules. Tokens are audience bound: one minted for another service will be refused.

Next