Line-Up MCP server
Summary: Explore a Line-Up ticketing channel read-only through MCP — events, performances, seating, packages, visits, transactions and organisation setup.
Events: list events (name, description, run time, venue with address, tags) with filters for venue and packages, sorting by id, name or venue name; get one event in full including booking info, currency, gallery and seat-view URL.
Performances: list or get performances with start/end, time zone, total and remaining capacity, and pricing per price band and variant (including the
price_ida reservation needs); filter by event, venue, date ranges, tags, days of week and codes.Seating: seating groups (areas, sections, blocks, rows) with capacity remaining, plus optionally individual available seats with price band and seat type, capped by
max_seatsand summarised per group.Packages and add-ons: packages per event or performance with capacity remaining and total price; with a
transaction_id, also the products and add-ons available to that basket.Visits: list visits (which performances a customer holds tickets to, with ticket items and their transaction reference, lead booker and status), filtered to upcoming or past with a buffer; get one visit including shared-ticket claim status.
Transactions: get one transaction by its
txn_id — status, reference, totals, customer name, ticket items with seat, price and barcode status, product, delivery, payment, add-on, package and adjuster items, coupons and staff notes.Organisation context: currency, venue plans with admission type, payment methods, seat types and (with a transaction) delivery methods.
Read-only: every registered tool carries
readOnlyHint; no reservation-creation or release tools are exposed here.Paged results: pass
page, cap fetches withmax_results, and continue vianext_page.Privacy defaults: emails and phone numbers in any free text are redacted, and customer/share contact details withheld, unless
include_contact_details=true; barcode codes only withinclude_barcodes=true; payment provider data is never returned.
Handles payment processing through Adyen as one of the supported payment providers; payment items are reported as method type, amount, currency and status, though Adyen session data and client keys are never returned.
Handles payment processing through Square as one of the supported payment providers; payment items are reported as method type, amount, currency and status, though Square application and location ids are never returned.
Handles payment processing through Stripe as one of the supported payment providers; payment items are reported as method type, amount, currency and status, though the Stripe continuation secret, publishable key and account id are never returned.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Line-Up MCP server What's on next Friday and how many seats are left?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Line-Up MCP server
An MCP server that lets Claude, ChatGPT and other MCP clients work with a Line-Up ticketing channel: events, performances with pricing and capacity, seating, packages, visits (who is coming to a performance), transactions, the organisation's venue plans, payment, delivery and seat types, and (when enabled) creating and releasing reservations. It is built from Line-Up's public Transactional API documentation: the OpenAPI 3.1 document the API serves at https://api.line-up.tickets/api/openapi.json (Swagger UI at /api/docs).
Once it's connected, someone at the venue can ask things like:
"What's on in the next two weeks, and how many seats are left for each night?"
"How much is a concession in the stalls for Friday's Macbeth?"
"Which rows in Stalls Left still have seats together?"
"Who is coming tonight? Show me booking LU-TEST1 and its notes."
"What packages do we sell for Macbeth, and what payment methods does this channel take?"
With writes enabled: "Hold two adult stalls seats for tonight for 15 minutes under the name Box office hold."
Tools
Tool | What it does | API calls |
| Events with description, run time, venue and address, tags. Filters |
|
| One event in full: description, booking information, organisation currency, gallery, seat-view base URL. |
|
| Performances with start/end, time zone, total capacity and remaining, and pricing per price band and variant (including the |
|
| One performance with the same pricing and capacity detail. |
|
| Seating groups (areas, sections, blocks, rows) with capacity and capacity remaining; optionally the individual available seats with price band, seat type and group, capped and summarised per group. Filters |
|
| Packages per performance for one event (paged) or for one performance, with capacity remaining and total price; with a |
|
| Visits: for each performance a customer holds tickets to, the event, the performance and the ticket items with their transaction (reference, lead booker name, status). Filters |
|
| One visit with every ticket item and, for shared tickets, whether the share was claimed. |
|
| One transaction: status, reference, totals, customer name, ticket items with seat, price and barcode status (paged), product, delivery, payment, add-on, package and adjuster items, coupons, staff notes (paged). |
|
| The organisation's currency, venue plans with admission type, payment methods by name and type, seat types (optionally for one performance) and, with a |
|
| Creates a transaction, then adds one ticket item per request (reserved seat, general admission or best available). Refuses locally when seat fields do not match the reservation type. Only registered when writes are enabled. |
|
| Deletes a transaction, releasing the seats it holds. Marked destructive. Writes only. |
|
Not covered on purpose: customer accounts, login and password reset, addresses, opt-ins, forms, discounts, payments and payment actions, terminal readiness, completing a transaction, product/package/delivery/add-on items on a basket, notes creation and editing, and the PUT/PATCH transaction updates. The spec's x-purchase-flow-id header and the group_preset/group_by query parameters are not sent. GET /health is not called by any tool (the test suite checks the mock serves it unauthenticated, as the live API does: an anonymous curl https://api.line-up.tickets/api/health answers {"status":"ok"}, while /meta/ answers 401; the spec itself lists the bearer scheme on /health, with no scopes, so the open access is an observation, not documentation).
Related MCP server: TicketSource MCP server
Setup
Requires Node 18 or later.
npm install
npm run buildYou need a channel API key from Line-Up. Keys are not self-serve: Line-Up issues one per sales channel on request to their support (see their guide on setting up a third-party seller).
Claude Desktop: add this to claude_desktop_config.json:
{
"mcpServers": {
"lineup": {
"command": "node",
"args": ["/absolute/path/to/lineup-mcp/dist/index.js"],
"env": { "LINEUP_API_KEY": "your-channel-key" }
}
}
}Claude Code:
claude mcp add lineup -e LINEUP_API_KEY=your-channel-key -- node /absolute/path/to/lineup-mcp/dist/index.jsVariable | Required | Meaning |
| yes | Your channel API key, sent as |
| no |
|
| no | An integer sent as the optional |
| no |
|
| no | Defaults to |
Safety defaults
Read-only unless
LINEUP_ALLOW_WRITES=true. Read tools carry the MCPreadOnlyHintannotation;release_reservationis marked destructive.Customer names are returned by default. The customer's email address, postal address and phone number on a transaction, and the purchaser's and recipient's email addresses on a shared ticket, are only returned when a tool is called with
include_contact_details=true. The same flag governs one rule for text: every string a person typed, whether a customer or the organisation (event, venue, performance, package, product, add-on, venue plan, payment method, delivery method, seat type, price band, variant and adjuster names and descriptions, seat and seating group labels, tag names, seat type notes, coupon codes, transaction references and source references, lead booker names, customer names, staff notes, API warnings and error messages), has email addresses replaced with[email redacted]and phone-number-like sequences with[phone redacted]by default; IDs, external IDs, enums, dates, times, colours and URLs are returned as stored. Every read tool takesinclude_contact_details;create_reservationalways returns the redacted form. The phone match is a heuristic: it covers international numbers written with+or00(including the+44 (0)7700 …form), UK numbers with a bracketed area code such as(020) 7946 0958, and UK-style0…numbers of 9 to 11 digits with spaces, dots or hyphens between groups; other digit strings starting with0are redacted too, while public IDs such astxn_test1, numeric IDs and timestamps are left alone. Only emails and phone numbers are matched: a postcode, a date of birth or a document number typed into a staff note, a lead booker name or a reference is returned as stored. A venue's address is a business address and is returned.Ticket barcode codes (what gets scanned at the door) are only returned with
include_barcodes=true; their status (type, redeemed, scan status) is always returned.Payment provider data is never returned: the Stripe continuation secret, Adyen session data, additional actions, payment references, the SOLT
lastFourdigits, and the provider keys on payment methods (Stripe publishable key and account id, Adyen client key, Square application and location ids). A payment item is reported as method type, amount, currency and status. The customer's identity-provider id (idpId) is never returned either.Input is checked before any call is made: integer IDs must be positive whole numbers; transaction IDs must match the spec's
txn_[a-zA-Z0-9]+and visit IDs^vis_\d+$; dates must be real calendar dates inYYYY-MM-DD; enum parameters (sort_by,sort_direction,time_filter,reservation_type) must be one of the documented values;page,max_results,performance_buffer_minutes,day_of_week,max_seats,max_notesandseconds_to_bookmust be within their documented or stated ranges.create_reservationrefuses locally aseating_object_idon anything butRESERVEDand aseating_group_idon anything butBEST_AVAILABLE(the spec'sReservedTicketCreateandBestAvailableTicketCreate). Line-Up documents no idempotency key, so none is sent.Line-Up documents no rate limit anywhere in the OpenAPI document or the older docs. Requests are spaced 250 ms apart (about four per second). A 429 is retried at most twice for any method, including the two
POSTs ofcreate_reservation, on the assumption that a rate-limited request was not processed (see Status). The retry waits forRetry-After(whole or fractional seconds, or an HTTP-date; 2 s then 4 s when the header is absent or unreadable). Each wait is capped at 10 seconds, so one request waits at most 20 seconds in all; a tool call that makes several requests (pages, lookups) can still run past the MCP client's default 60-second request timeout. Past the cap: if Line-Up asks for a longer wait the call gives up at once and the message says how long to wait.502, 503 and 504 are retried the same way for
GETonly; when all three attempts fail the error says the service may be unavailable and to try again in a few minutes, without the gateway's HTML. APOSTorDELETEis never retried after a gateway error, because the request may already have been processed and a retry could reserve seats twice; the error tells the assistant to check withget_transactionfirst.A 200 whose body is not JSON (a proxy or a login page in the way), or whose JSON is not the documented shape (a list without the
Pageenvelope'smetadataanddata; a record or transaction withoutdata), is reported as an error namingLINEUP_BASE_URLand the keys it did get, never as an empty list or an empty transaction.A rejected API key produces a message that says which variable to fix and which scheme was used (Bearer by default, suggesting
LINEUP_AUTH=basic; or Basic, suggesting the default); a 403 says the key lacks the scope (api_read,api_write,api_list,api_deletein the spec); a 422 is passed on with FastAPI's field-level messages.
Tests
npm testThe test suite:
Validates every fixture record against the component schemas in Line-Up's OpenAPI document (
Event,EventDetail,PerformancePricing,SeatingGroupCapacity,PerformanceSeatingObjectDetail,PerformancePackages,ProductPricing,AddOn,VisitSummary,Visit,Transaction,TicketTransactionItem,NoteDetail,Meta,VenuePlanListItem,DeliveryMethod,PaymentMethod,SeatType) with Ajv 2020 (the document is OpenAPI 3.1). The document is downloaded fromapi.line-up.tickets/api/openapi.jsontospec.jsonon the first run. One format is relaxed: the spec typesstartTime/endTimeasformat: time, which ajv-formats reads as RFC 3339 full-time with a mandatory zone, while FastAPI serialises a naive time as19:30:00; the suite acceptsHH:MM:SSwith an optional fraction and zone.Starts a local mock of the API under
/apithat serves those fixtures with the documentedpage/sizepagination andMetaData, serves/healthwithout auth (as the live API does; the spec lists the bearer scheme on it), answers a wrong key with the live API's unauthenticated401body ({"detail":"Could not validate credentials"}andWWW-Authenticate: Bearer, which anyone can observe), unknown routes and ids with{"detail":"Not Found"}(the spec documents 404 with no body schema), invalid input with the spec'sHTTPValidationError, and the firstGET /event/with a 429. Every list, detail, write and error response of the mock is validated against the spec's response schemas.Starts the built server and drives it over stdio with the official MCP client: 32 checks (34 in all with the two above) covering every tool, tool annotations, page-based pagination stopping at the documented
totalPages(events, performances, packages, ticket items, notes) and reportingnext_page, every exposed filter passed through under its documented name (including repeated keys for array parameters), redaction of contact details by default (customer email, address and phone; share emails; lead booker names; notes; event text) and their return on request, a probe that types a phone number and an email address into every text field the fixtures carry (names, descriptions, labels, notes, tag names, coupon codes, on every record type) and checks that no tool returns them by default and every read tool returns them withinclude_contact_details, barcodes withheld by default, payment provider data and keys absent from every output, the 429 retry waiting forRetry-Afterin the seconds, fractional-seconds and HTTP-date forms, giving up after three attempts on a persistent 429 and at once on aRetry-Afterabove the cap, a 429 onPOST /transaction/retried once, a 502 retried forGETand never forPOST, a 503 onDELETEnot retried, aGETfailing three times with 503 reported with advice and without the gateway HTML, a 200 with a non-JSON body and a 200 whose JSON lacks thePageordataenvelope reported as errors, the write gate with the variable unset and set tofalse, thePOST /transaction/body validated againstTransactionCreateand each ticket-item body compared field by field with the documented shape (the spec's branches allow extra properties, so schema validation alone would not catch a stray seat field), the local refusal of mismatched seat fields, a refused later ticket item reported with the transaction id, theDELETE, refusal before any call of bad IDs, unknown enum values, out-of-range numbers and impossible dates, the 401 message in both auth schemes, the 403 and 404 messages,LINEUP_AUTH=basic,LINEUP_CHANNELsent exactly on the operations the spec declaresx-channelon (checked against the spec) and not on/meta/,/venue-plan/,/visit/and/visit/{id}/, that the main session used only the Bearer key and every call template it should, and that every request of the run, later sessions included, hit a documented method and path with its trailing slash, without thex-purchase-flow-idheader.
Status
This is a working prototype. It has not yet been run against the live API, because it was built without a Line-Up channel key (keys are issued by Line-Up on request, not self-serve). Everything below is taken from the published OpenAPI document and should be confirmed on a real channel:
Authentication: whether the channel key is accepted as a Bearer token (the OpenAPI document's scheme, and what the unauthenticated 401 advertises) or must be sent as the HTTP Basic username (the older docs' scheme,
LINEUP_AUTH=basic); whetherPOST /purchase-channel/{key}/(a token exchange the spec lists) is needed first; what a 403 looks like when a key lacks a scope; and whether thex-channelheader is needed at all.Pagination: that
pageis 1-based andsizeup to 1000 are honoured as documented, thattotalPagesandnumberOfResultsare filled (the spec allows null; the server then ends at a short page), and what a page past the end returns (the mock answers an emptydata).The sort order of every list. The spec documents
sort_by/sort_directiononly on events andsort_directionon visits; the server returns whatever order the API uses.The meaning of
codeon performances, seats and products (typed as a list of strings; the mock records it and does not interpret it), the numbering ofday_of_week, theexpandparameter onGET /performance/(not exposed), and whetherhasPackage=falsemeans "no filter" or "events without packages" (the server only sends the parameter when given).Which id is
priceIdfor a ticket item. The server reports a pricing variant'sprice.idasprice_idbecause a ticket item'sPricein a transaction has the same{id, value, priceBand, priceVariant}shape; the variant's own id is reported asvariant_id. Confirm which onePOST .../ticket-item/expects.The reservation flow: the default and maximum
secondsToBook, the status a new transaction has (IN_BASKETorRESERVATIONin the enum), whether ticket items can be added one request at a time as this server does (the spec also acceptsticketItemsinsideTransactionCreate), what a refused ticket item answers (the mock uses 422 for an unknown price and 404 for an unknown seat), and whetherDELETE /transaction/{id}/releases a basket (the spec calls it "Delete Transaction", describes it as "Patch an existing transaction" and answers with the object's id; what it does to a completed transaction is undocumented, so only release reservations you created).GET /product/without atransaction_id(the spec makes it optional; the server only calls it with one), and whetherGET /add-on/andGET /delivery-method/really need a transaction (they are required parameters in the spec).Time and date formats:
startTimewith or without a zone (see Tests), andtimeZonevalues.Whether
GET /transaction/{id}/ticket-item/fillsbarcodefor reservations and completed bookings alike, and which fields the live API fills onTransaction(customer,address,phoneNumber,parentTransaction,coupons).The wording of Line-Up's error messages and whether any echo request data; the server passes on FastAPI's
detailstrings and redacts contact details from them regardless.Rate limits: nothing is documented, so the 250 ms spacing is a guess on the polite side, and a 429 on
POSTis retried on the assumption that a rate-limited request was not processed. Confirm on a live channel that Line-Up never creates the transaction before answering 429.
Going to production
This version runs locally over stdio, with the channel's own API key. For venues to connect from claude.ai or ChatGPT without handling keys, the next step is a remote server (Streamable HTTP) behind OAuth, hosted by Line-Up, and then a listing in the Claude and ChatGPT connector directories. Customer-facing flows (customer accounts, payment, completing a transaction) can follow once they can be tested on a real channel.
Licence
MIT. Built by Alexandru Dragoș (alexandru.dragos96@gmail.com) with an AI agent (Claude) working under his direction.
Available Tools
10 toolsget_eventGet eventARead-onlyIdempotent
One event in full: description, booking information, organisation and currency, venue with address, tags, gallery, seat-view base URL. Uses GET /event/{event_id}/.
Inputs: event_id (required), include_contact_details.
get_organisation_contextOrganisation contextARead-onlyIdempotent
What the channel is set up with: the organisation's currency (GET /meta/), venue plans with admission type (GET /venue-plan/), payment methods by name and type without any provider keys (GET /payment-method/), seat types (GET /seat-type/, optionally for one performance) and, when a transaction_id is given, the delivery methods available to that basket (GET /delivery-method/, which the API scopes to a transaction).
Inputs: performance_id, transaction_id, include_contact_details.
get_performanceGet performanceARead-onlyIdempotent
One performance with its pricing per price band and variant, capacity and capacity remaining, venue plan id. Uses GET /performance/{performance_id}/.
Inputs: performance_id (required), codes, include_contact_details.
get_performance_seatingPerformance seatingARead-onlyIdempotent
Seating availability for one performance: the seating groups (areas, sections, blocks, rows) with capacity and capacity remaining, from GET /performance/{id}/seating-group/, and optionally the individual available seats (seating objects with price band, seat type and group) from GET /performance/{id}/seating-object/. Seat lists can be large, so seats are off by default and capped by max_seats; a per-group summary is always included when seats are fetched.
Inputs: performance_id (required), codes, max_seats, package_id, +4 more.
get_transactionGet transactionARead-onlyIdempotent
One transaction (basket, reservation or completed booking) by its txn_ id: status, reference, totals (gross, tax, paid, balance), customer name, every ticket item with seat, price and barcode status (GET /transaction/{id}/ticket-item/, paged), product, delivery, payment, add-on, package and adjuster items, coupons, and the staff notes (GET /transaction/{id}/note/, paged). The customer's email, address and phone number only with include_contact_details; barcode codes only with include_barcodes; payment provider data is never returned.
Inputs: transaction_id (required), max_notes, include_barcodes, max_ticket_items, +1 more.
get_visitGet visitARead-onlyIdempotent
One visit with every ticket item, its transaction and, for tickets that were shared with someone, the share (created, claimed). The purchaser's and recipient's email addresses only with include_contact_details. Uses GET /visit/{visit_id}/.
Inputs: visit_id (required), include_contact_details.
list_eventsList eventsARead-onlyIdempotent
Events on this channel (shows, productions, exhibitions): name, short description, run time, venue with address, tags, image. Filter by venue and by whether the event has packages; sort by id, name or venue name. Uses GET /event/.
Inputs: page, sort_by, venue_id, has_package, +3 more.
list_packages_and_add_onsPackages, products and add-onsARead-onlyIdempotent
Packages (bundles priced per performance, with capacity remaining and total price) for one event (GET /package/, paged) or one performance (GET /performance/{id}/package/). With a transaction_id, also the products available to that basket (GET /product/) and its add-ons such as booking protection (GET /add-on/); the API scopes both to a transaction, so without one they are not fetched. Give event_id or performance_id.
Inputs: page, event_id, package_id, max_results, +5 more.
list_performancesList performancesARead-onlyIdempotent
Performances (dated showings) with start and end, time zone, total capacity and capacity remaining, and pricing per price band and variant (the price_id values a reservation needs). Filter by event, venue, date range, tags, days of the week. The spec says this endpoint 'bypasses Pydantic due to performance requirements', so the shape is documented but not validated by Line-Up on the way out. Uses GET /performance/.
Inputs: page, tags, codes, event_id, +9 more.
list_visitsList visitsARead-onlyIdempotent
Visits: for each performance a customer holds tickets to, the event, the performance and the ticket items with their transaction (reference, lead booker name, status). Filter to upcoming or past performances with a buffer in minutes around the start time. Uses GET /visit/.
Inputs: page, max_results, time_filter, sort_direction, +2 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 10 tools
The list_/get_ pattern cleanly separates collection vs. detail for events, performances, visits and transactions, and get_performance_seating and get_organisation_context are clearly distinct. The only slight ambiguity is list_packages_and_add_ons, which merges packages, products and add-ons with conditional behavior depending on event_id/performance_id/transaction_id.
Every tool follows a consistent verb_noun snake_case convention (list_events, get_event, list_performances, get_performance, get_visit, etc.). The pattern is predictable throughout with no mixed styles or vague verbs.
Ten tools is well within the ideal range and each earns its place, covering the read/query surface for events, performances, seating, packages, visits, transactions and org context without redundancy.
The lifecycle for querying the domain is well covered: list/detail for events, performances, seating, packages, visits and transactions plus configuration context. It is a read-only surface with no reservation/booking creation or update tools, but the descriptions imply a query-oriented purpose rather than a gap.
Maintenance
Related MCP Connectors
MCP server unifying ERPs, CRMs, APIs and knowledge base for Claude, ChatGPT and Gemini.
Talk to your live-events CRM (campaigns, analytics, paid ads, segments) in Claude and ChatGPT.
AI marketplace — flights, tours, activities, transport & more via MCP. No auth required.
Agent communication platform for agent to agent messaging via MCP. Messages, channels, skills.
Related MCP Servers
- AlicenseAqualityCmaintenanceExposes FreeTicket's B2B domain (events, sales, tickets, etc.) as tools for MCP clients like Claude Code, using the same authentication as the CLI.6MIT
- AlicenseAqualityCmaintenanceEnables MCP clients like Claude and ChatGPT to query and manage TicketSource box office data, including events, performances, bookings, customers, and seats, through natural language.7MIT
- AlicenseAqualityCmaintenanceEnables MCP clients to search availability, read services, resources, bookings and customers, and, when writes are enabled, reserve slots, create or cancel bookings, and add or update customers.10MIT
- AlicenseAqualityCmaintenanceEnables Claude, ChatGPT and other MCP clients to read an Amiqus ID account—clients, onboarding records and steps, check results, templates, case status counts and webhooks—and, when writes are enabled, create records.9MIT