Skip to main content

Connect your agent to Ticketlayer

Ticketlayer ships a remote MCP server so you can point your own AI agent - Claude Desktop, Claude Code, an MCP Inspector session, or anything that speaks MCP - at your Ticketlayer account and have it read your catalogue, orders and customers, query your analytics, and (with the right permission) create and update events.

The agent acts as you. Every tool call carries your own credential to the same permissioned API the dashboard uses, so an agent can never do more than your own role allows, and never sees another organisation's data.

Endpointhttps://mcp.staging.t9r.dev/mcp (staging; production is not deployed yet)
TransportStreamable HTTP
AuthOAuth 2.1 - Dynamic Client Registration + PKCE
Connect scopemcp

Where it runs today

The staging server is at https://mcp.staging.t9r.dev/mcp and is public. Its authorization server, Stagedoor (stagedoor.staging.t9r.dev), is published only on the Ticketlayer team tailnet, and the OAuth flow below has to reach it from your browser. So today:

  • from a machine on the tailnet, every client below connects and authenticates;
  • from anywhere else, the client registers and starts the login, and the browser redirect to Stagedoor does not resolve, so the connection cannot complete.

Production, where Stagedoor is public, is not stood up yet. An API-key mode for the MCP server (so a server-side agent can connect without the browser flow) is planned in the platform plan and not built. When you run the stack locally with tt dev, the endpoint is https://mcp.staging.t9r.dev/mcp.

How it works

your agent ──OAuth 2.1 (register → log in → consent)──▶ stagedoor (identity)
│ issues access token
│ Streamable HTTP + Bearer token (org chosen at login)

Ticketlayer MCP server ──forwards your token──▶ Ticketlayer API
· validates the token + `mcp` scope · your RBAC permissions
· org taken from the token · scope limits writes
  1. Your MCP client discovers the server's metadata at /.well-known/oauth-protected-resource/mcp and finds the authorization server.
  2. It registers itself automatically (Dynamic Client Registration - no pre-configuration, no client secret) and starts an OAuth login.
  3. You log in, choose which organisation the agent may act for, and consent to the scopes it requested.
  4. The agent receives an access token and calls tools. The MCP server validates the token and forwards it to the Ticketlayer API under your organisation and your permissions.

The organisation is baked into the signed token, never chosen by the agent - so an agent connected to one org can't reach another.

Connect your client

The server URL is https://mcp.staging.t9r.dev/mcp. Every client below discovers auth and runs the login/consent flow in your browser the first time - there is no API key to paste and nothing to pre-register. (Read the note above about the tailnet first: the browser step needs to reach Stagedoor.)

Claude Code (CLI)

Add the server, then authenticate from inside a session:

# Add it (available in the current project)
claude mcp add --transport http ticketlayer https://mcp.staging.t9r.dev/mcp

# …or make it available across all your projects
claude mcp add --scope user --transport http ticketlayer https://mcp.staging.t9r.dev/mcp
# Start Claude Code, then run the /mcp command:
claude
> /mcp
# Select "ticketlayer" → Authenticate. Your browser opens to log in + consent;
# the token is stored and refreshed automatically.

Manage it:

claude mcp list                 # shows connection / auth status
claude mcp get ticketlayer # details for one server
claude mcp remove ticketlayer # remove it

To share it with a repo, commit a project-scoped .mcp.json at the repo root (use --scope project when adding, or write the file directly):

{
"mcpServers": {
"ticketlayer": {
"type": "http",
"url": "https://mcp.staging.t9r.dev/mcp"
}
}
}

Claude Desktop

Settings → ConnectorsAdd custom connector → name it ticketlayer and paste https://mcp.staging.t9r.dev/mcp. Claude Desktop registers itself and opens the browser for login + consent. (Custom connectors require a paid plan.)

If you prefer a config file, or your Claude Desktop only supports stdio servers, bridge through mcp-remote in claude_desktop_config.json (Settings → Developer → Edit Config):

{
"mcpServers": {
"ticketlayer": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://mcp.staging.t9r.dev/mcp"]
}
}
}

Cursor

Add to ~/.cursor/mcp.json (global) or .cursor/mcp.json (project):

{
"mcpServers": {
"ticketlayer": {
"url": "https://mcp.staging.t9r.dev/mcp"
}
}
}

Then open Settings → MCP and authenticate the server.

VS Code (GitHub Copilot)

code --add-mcp '{"name":"ticketlayer","type":"http","url":"https://mcp.staging.t9r.dev/mcp"}'

…or commit .vscode/mcp.json (note VS Code uses the servers key):

{
"servers": {
"ticketlayer": {
"type": "http",
"url": "https://mcp.staging.t9r.dev/mcp"
}
}
}

MCP Inspector (to test)

npx @modelcontextprotocol/inspector

Open it, choose transport Streamable HTTP, enter https://mcp.staging.t9r.dev/mcp, and Connect - it walks you through the OAuth flow and lets you call tools by hand.

Any other (stdio-only) client

For a client that only speaks stdio, bridge to the remote server with mcp-remote (it handles the OAuth flow for you):

{
"mcpServers": {
"ticketlayer": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://mcp.staging.t9r.dev/mcp"]
}
}
}

Codex CLI

Add to ~/.codex/config.toml:

[mcp_servers.ticketlayer]
url = "https://mcp.staging.t9r.dev/mcp"

Once connected (any client), ask things like "list my upcoming events" or "how many orders did the jazz night take?".

Scopes & permissions

Access is bounded twice: by the OAuth scopes you consent to, and by your own role (RBAC). An agent gets the intersection of the two.

ScopeGrants
mcpConnect, and read across your catalogue, orders and customers
events.writeCreate and update events
orders.read, customers.readGranular read access (alternative to broad mcp)
  • Reads work with the mcp scope alone.
  • Writes require the matching write scope (e.g. events.write). If your token doesn't carry it, the write tool returns a clear error telling you to reconnect and grant it - your agent can prompt you to re-authorise.
  • Admin operations and sensitive actions are never reachable through an agent token, regardless of your role.

Tools

Read (run automatically): events, occurrences, price schemes, venues and layouts, inventory and reservations, orders and order passes, customers, sales channels and listings, accounts, your own profile/permissions, and analytics (see below).

Write (require approval + a write scope):

ToolAction
createEventCreate a new event
updateEventUpdate an event's details or status

Write tools are marked destructive, so your MCP client asks you to confirm each one before it runs - that confirmation is the human-in-the-loop gate. Pricing and seating-layout edits are not yet exposed as agent tools.

Analytics & reporting

The agent can answer data questions ("how did the jazz night sell?", "revenue by channel last month") through Insights - the governed Reporting layer that serves the same numbers your dashboards show. These are read tools, available with the mcp scope; no writes, no approval needed.

The pattern is always two steps:

  1. getReportsMeta - discover the available data models, measures and dimensions. Always call this first; you can only query members it lists.
  2. runReportsQuery - run an ad-hoc query built from those members.

runReportsQuery takes a query object:

{
"query": {
"measures": ["sales_line_items.grossRevenue", "sales_line_items.ticketsSold"],
"dimensions": ["sales_line_items.eventName"],
"order": { "sales_line_items.grossRevenue": "desc" },
"limit": 10
}
}

…with optional timeDimensions (e.g. [{ "dimension": "orders.createdAt", "dateRange": "last 30 days", "granularity": "day" }]) and filters. Other read tools cover saved reports and dashboards (listSavedReports / runSavedReport, listDashboards / getDashboard, listReportTemplates) and pre-baked rollups (getReportsSummary, getReportsTimeseries, getReportsInventory).

Two conventions to read results correctly:

  • Money is in integer minor units ("grossRevenue": "229350" = £2,293.50) and carries a currency dimension - never sum across currencies.
  • Timestamps are ISO 8601 UTC; render in the venue/org timezone for display.

Everything is tenant-scoped automatically - a query only ever sees your own organisation's data, enforced server-side in the Reporting layer.

Security model

  • You can't exceed yourself. Tools call the same permissioned routes the UI uses, with your token. RBAC, the 404-not-403 rule, and the platform's field-stripped views all apply unchanged.
  • One org per connection. The org is carried in the signed token; switching orgs means logging in again.
  • Least privilege. Agent tokens are capped to their granted scopes, so even an organisation owner's agent only does what it was consented to do.
  • No raw data path. The MCP server holds no database connection and no model key - it only forwards your authenticated calls.

Limitations (today)

  • Read-first: only createEvent / updateEvent writes are exposed.
  • One organisation per token.
  • Self-registered (DCR) agents are public PKCE clients with https or loopback redirect URIs only.