JustGo MCP server
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., "@JustGo MCP server Is Jo Bloggs's membership active, and which clubs is she in?"
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.
JustGo MCP server
An MCP server that lets Claude, ChatGPT and other MCP clients look things up in a JustGo sports membership platform: members, their memberships and credentials (coaching and officiating qualifications, licences, with expiry dates), events and event bookings, and clubs and other organisations. With writes enabled, it can also change the dates of one member's membership. It is built from JustGo's public API documentation only: the OpenAPI 3.0.1 document "JustGo API" 2.2 at api.justgo.com/swagger/v2.2/swagger.json, shown in the Swagger UI at api.justgo.com/index.html. The spec has no servers block; the base URL https://api.justgo.com is inferred from where the spec is served.
Once it's connected, someone at a governing body or club can ask things like:
"Is Jo Bloggs's membership active, and which clubs is she in?"
"Which of Jo's coaching qualifications expire before the end of the year?"
"Which members are suspended?"
"What competitions are published, how many places are left on the Autumn Gala, and who has booked?"
"Which clubs in the South West hold the SwimMark accreditation, and when does it expire?"
With writes enabled: "Extend Jo's Adult Competitive membership to 31 March 2027."
Tools
Tool | What it does | API calls |
| Search members with every filter the endpoint documents: |
|
| One member with their memberships, organisations (with roles), credentials, event bookings and linked family members. |
|
| Memberships held by members: name, category, classification, type, status, start and end dates, membership number, owner. Filters |
|
| Credentials held by members: name, type, status, reference number, start and end (expiry) dates. Filters |
|
| Events with dates, booking deadline, venue, category, status, organiser, details and stages. Filters |
|
| One event with its tickets (price, booked, remaining places), promoters and stages. |
|
| Bookings (the API calls them candidates): who booked which ticket, booking status and dates. Filters |
|
| Clubs and other organisations: number, type, status, town, region, country, website, join link. Filters |
|
| One organisation with its awards (organisation credentials, granted and expiry dates) and memberships. |
|
| Changes the start and/or end date of one member's membership. Reads the membership first, sends the date that was not given unchanged, refuses locally when the end would be before the start, and returns the previous dates so the change can be reverted. Only registered when writes are enabled. |
|
The list tools take page (default 1), page_size (1 to 100, default 50) and max_pages (default 2). The page size stays fixed within a call so page numbers line up; when more remains, the result says which page to continue from. If the API applies a smaller page size than the one asked for, the result reports it as page_size_applied.
Not covered on purpose: every other write (creating or updating members, suspending members, adding members to clubs, creating credentials, memberships, events, stages, promoters and bookings, deleting anything), profile image upload, Members/LogInCheck, Members/PasswordReset and Members/ChangePassword (end users' passwords), competitions and rankings, shops and orders, rewards links, the /Schema endpoints, credential and membership definitions, and organisation-level credentials and memberships.
Related MCP server: Amiqus MCP server
Setup
Requires Node 18 or later.
npm install
npm run buildYou need the API secret JustGo issues for your organisation's account. The spec documents the exchange but not how the secret is issued: the "Published API" appears as a plan capability on justgo.com, so ask JustGo. The server posts the secret to POST /api/v2.2/Auth as {"secret": "..."} and sends the JWT it gets back as Authorization: Bearer … on every other request.
Claude Desktop: add this to claude_desktop_config.json:
{
"mcpServers": {
"justgo": {
"command": "node",
"args": ["/absolute/path/to/justgo-mcp/dist/index.js"],
"env": { "JUSTGO_SECRET": "your-secret" }
}
}
}Claude Code:
claude mcp add justgo -e JUSTGO_SECRET=your-secret -- node /absolute/path/to/justgo-mcp/dist/index.jsVariable | Required | Meaning |
| yes | The API secret, exchanged at |
| no |
|
| no | Defaults to |
Safety defaults
Read-only unless
JUSTGO_ALLOW_WRITES=true. The nine read tools carry the MCPreadOnlyHintannotation.update_membership_datesis markeddestructiveHint: true(it overwrites the stored dates) andidempotentHint: true(repeating it with the same dates changes nothing further).Members of sports governing bodies and clubs include children, so by default a person (member, linked family member, booker, event promoter) is identified by ID, member number and name only. Email addresses, phone numbers, postal addresses, dates of birth, gender, login names, last-login times and parents' names and emails are only returned when a tool is called with
include_contact_details=true. A club's email, phone number, street address, postcode and map position are treated the same way, because they are often a volunteer's own; its town, region, country, website and join link are returned. An event's venue address is returned by default: it is where the event takes place.Never returned, even on request: the untyped
additionalDetailsmember of members, events and organisations and the untypedoptinmember of members. The spec gives them no schema, and custom-form answers of this kind can hold medical, safeguarding, emergency-contact or consent information. When a record has them, the output lists their names undernot_returned, so the assistant can say the record holds more than it was shown. No file is ever downloaded, and no bank, card or payment data is requested: none of the endpoints used returns it.In free text, email addresses are replaced with
[email redacted]and phone-number-like sequences with[phone redacted]. In people's names (members, linked family members, bookers, promoters), event and course names and details, venue and location text, stage names and descriptions, and the organisation names shown by the organisation and event tools this is the default, and the raw text is returned withinclude_contact_details. Some free text is always redacted, even on request: the names of memberships, credentials, tickets, awards and club memberships, the names of the organisations on a member's record, the roles of club members and event promoters, linked family members' references, and JustGo's own error messages. The phone match is a heuristic: it covers international numbers written with+or00, with or without a bracketed trunk prefix or area code (+44 (0)7700 …,+1 (555) 123-4567,+61 (02) 9876 5432), numbers with a bracketed UK or North American area code such as(020) 7946 0958or(555) 123-4567, and UK-style0…numbers of 9 to 11 digits with spaces, dots or hyphens between groups. Other digit strings starting with0are redacted too, while UUIDs, numeric IDs, timestamps and hyphenated references are left alone. Credential reference numbers, ticket codes, award and club-membership references and websites are structured values and are returned unredacted. Note that afind_memberssearch on an email address still confirms that the address is registered, even though it is not shown.The secret and the JWT are never written to a log or an error message; if JustGo ever echoed the secret or the current token in an error, it would be replaced with
[redacted]. From an error response only the documented JSON fields (message, and theerrorsanddetailsmaps) are passed on; a non-JSON body (a gateway page, a login page) is never quoted.Arguments are checked before any call. An argument a tool does not declare (a misspelt or invented filter such as
first_nameorlastName) is refused with its name, so it never turns into an unfiltered search. Every ID on the endpoints used is typedformat: uuidin the spec, so only UUIDs are accepted; the one exception islist_events'sorganisation_id, which the spec types as a plain string of up to 500 characters and which is passed as given. String filters use the spec'smaxLengthwhere it gives one; where it gives none (SuspendStatus,EventNumber, and the membershipStatus,Category,ClassificationandOwnerType), 500 characters is this server's own cap.modified_after/modified_beforeare typeddate-timein the spec: a date-time with seconds and a time zone (2026-09-01T00:00:00Z,2026-09-01T10:30:00+01:00) is sent as given, a bare date (2026-09-01) is sent as midnight UTC that day (2026-09-01T00:00:00Z), and a date-time without seconds or a time zone is refused rather than guessed; impossible dates such as 2026-02-30 are refused. The dates forupdate_membership_datesmust be full date-times with seconds and a time zone, for the same reason.JustGo documents no rate limit: neither the spec nor the Swagger UI says anything about one. Requests are spaced 250 ms apart (about four per second). A 429 is retried at most twice for any method, on the assumption that a rate-limited request was not processed, waiting for
Retry-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; if JustGo asks for a longer wait the call gives up at once and the message says how long to wait. A tool call that makes several requests (pages, lookups) can still run past the MCP client's default 60-second request timeout.502, 503 and 504 are retried the same way for
GETand forPOST /Auth(asking for a token again changes nothing). When all three attempts fail the error says the service may be unavailable. The membershipPUTis never retried after a gateway error, because it may already have been applied; the error says to check the membership first.The JWT is cached. If its
expclaim is present (read, not verified), a new one is fetched a minute before it expires (or halfway through its remaining life when that is under two minutes); withoutexpit is kept until the API answers 401. On a 401 the server fetches one fresh JWT and retries once; if that is refused too, the message says to check that the secret is still active.A 200 whose body is not a JSON object is reported as an error naming
JUSTGO_BASE_URL, never as an empty list. A get-by-ID that answers 200 without a record is reported as not found.
Tests
npm testThe suite builds the server and runs test/e2e.mjs (32 checks, about 40 seconds):
Validates every fixture record against the component schemas in JustGo's published spec (
MemberListV2_2Dto,MemberV2_2Dto,MemberMembershipListDtoV2_2,MemberSingleMembershipDtoV2_2,MemberCredentialDtoV2_2,EventResponseDtoListV2_2,EventDtoSingleV2_2,EventCandidateDtoV2_2,ClubDtoV2_2,ClubSingleDtoV2_2and everything they embed) with Ajv andajv-formats. Every one of these schemas setsadditionalProperties: false, so a fixture key the spec does not declare fails; negative controls prove an undeclared key and a malformed UUID are rejected. One deliberate loosening: OpenAPI 3.0 allowsnullable: truewithout a type, which Ajv refuses, so on the spec's eleven untyped members (theadditionalDetails,optin,additionalDataand onedatamember) that marker is dropped and they are validated as "any value". The spec is saved asspec.jsonand downloaded fromapi.justgo.com/swagger/v2.2/swagger.jsonon the first run when missing. The spec has no examples, so the fixture values are invented; only their shape comes from the spec. It then checks the built redaction helper on UK, international and North American phone forms (and that UUIDs, timestamps and references are left alone), that a dotted string such asapi.justgo.comor2.2.0is not taken for a JWT, and when a cached JWT is replaced for a givenexp(a minute early, or halfway through when under two minutes remain).Starts a local mock of the API:
POST /api/v2.2/Authtaking{ secret }and returning a JWT built at run time (401 for a wrong secret, 400 for an empty one),Bearerchecks on every other route with 401 for an unknown token, the documentedPageNumber/PageSizepaging withpageNumber,pageSize,totalPagesandtotalRecords(each of the last three can be left out, and the page size capped, to test the fallbacks), 400 for aModifiedAfter/ModifiedBeforethat is not an RFC 3339 date-time, the documented single-record envelope{ statusCode, message, object, data }, 400 in the documentedHttp400BadRequestResponseshape for a malformed ID, 404 in theHttp404NotFoundResponseshape for an unknown one, a one-off 429 withRetry-After, and it records every request (method, path, query, headers, body). The mock's list, detail, update, 400, 401 (in theHttp401UnAuthorizedResponseshape, which the spec documents for 403) and 404 responses are validated against the schemas the spec names for each operation. One mock answer is deliberately outside the spec: a get-by-ID answering 200 withdata: null, to test the server's handling of an unknown ID in that form; the suite asserts that this answer does not match the documented schema.Drives the built server over stdio with the official MCP client: tools/list and annotations; writes absent with
JUSTGO_ALLOW_WRITESunset orfalse; the token request in its documented form, without anAuthorizationheader, with the JWT reused across calls; paging across pages 1, 2 and 3 with a full last page, stopping attotalPageswith no fourth request, with requests at least 250 ms apart; withouttotalPages, stopping oncetotalRecordsrecords are fetched, following a smaller page size the API applies (reported inpageSizeor not), and withouttotalRecordseither, stopping at a short page or after an empty one; continuation fromnext_page; every documented filter of all six list tools passed through under its documented name and value, with bare dates sent as midnight-UTC date-times; redaction of contact details, dates of birth, addresses and parents' details by default and their return on request; emails and phone numbers typed into a member's first or last name, a linked family member's name, a booker's name and a promoter's role redacted by default (the role even on request);additionalDetailsandoptincontent never returned, even on request; club contact details and promoters' contacts only on request; emails and phone numbers (including a+1 (555) …number) in event details and stage descriptions redacted; ID and date validation before any call, including date-times without seconds or a time zone and unknown or misspelt argument names; the not-found message for a 404 and for a 200 without a record; the membershipPUTpreceded by aGET, its body validated againstMemberLicensePutDto, the unchanged date carried over and the change visible afterwards; the local refusals (end before start, no stored date, nothing to change) with noPUTsent; a 429 on thePUTretried once and a 502 on thePUTnot retried; a 400's message anderrorspassed on with contact details redacted and the secret scrubbed, and the current JWT scrubbed when a message echoes it; the 403 message; a revoked JWT replaced once on 401 and a persistent 401 reported without a loop; the JWT found in a text, JSON-string or JSON-object/Authresponse, including one whose envelope also holds dotted strings such asapi.justgo.com, and a response without one reported by its keys only; a 429 and a 502 from/Authretried; two parallel first calls sharing one token request; a JWT refreshed from itsexpclaim and one withoutexpreused; 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 a wait above the cap; a 502 retried forGET; three 503s reported with advice and without the gateway HTML; a non-JSON 200 reported as an error; a wrong secret reported with a message namingJUSTGO_SECRETand not repeating it; and, as the last check, that every request the MCP servers made during the run used a documented method, path and query parameter names, with a JWT the mock issued asBeareron every call except/Auth.
The mock applies only some filters to its data (LastName, Email, memberNumber, MemberId, Status, EventCategory, EventId, BookingStatus, Type, OrganisationId, and the modified dates on members, credentials, events and organisations); for the others the suite checks that they reach the API exactly as documented, not what JustGo does with them.
Status
This is a working prototype. It has not been run against the live API, because it was built without a JustGo account (JustGo offers no trial; the API is a plan capability). Everything below comes from the published spec and should be confirmed on a real account:
The
/Authresponse. The spec documents only "200 Success" with no body, so the server looks for a JWT (the whole body, or a string inside a JSON object'sdatamember or at its top level, members named liketokenfirst) and only accepts a value whose first segment decodes to a JWT header with analg. Which form JustGo uses, whether the JWT carriesexp, how long it lasts, and what a wrong secret gets (the mock answers 401; during research an empty secret got 400 from the live API) are unconfirmed.How the secret is issued, what it can see (one organisation or a whole governing body) and when the API answers 403.
Paging: that
PageNumberis 1-based (assumed), the default and maximumPageSize(the server sends at most 100, its own cap), thatpageSize,totalPagesandtotalRecordsare always filled (the spec lists them but marks none required), and what a page past the end returns. WithouttotalPagesthe server stops oncetotalRecordsrecords are accounted for, and without either at a page shorter than the page size. If the API applied a smaller page size than asked without reporting it inpageSize, the server infers it from a short page whiletotalRecordssays more follow; a call that starts past page 1 in that situation could stop early.What the API answers for an unknown ID. The spec documents no 404 for these endpoints (only
GET /Events/{eventId}/Promotershas one); the server handles a 404 and a 200 without a record, and a 400 is passed on with JustGo's message.Filter semantics: whether
LastName,Email,MembershipandMembershipNamematch exactly or partially, the allowed values ofStatus,Category,Classification,OwnerType,SuspendStatus,BookingStatus,TypeandEventSubcategory(the spec lists none), whetherModifiedAfter/ModifiedBeforeare inclusive and whether the API reads them in UTC (the server sends a bare date as midnight UTC, which is an hour off UK local midnight in summer), and whetherlist_events'sOrganisationIdtakes a UUID or an organisation number (it is typed as a plain string).The sort order of every list. The spec documents none; the server returns whatever order the API uses.
Date formats. The spec types dates as
dateordate-time; the fixtures use2026-08-01and2026-08-01T09:00:00Z. If the live API emits date-times without a time zone (common for .NET services) or dates of birth as date-times, the server passes them through unchanged, but the suite's schema check would fail on such values.Which fields the live API actually fills, and what
additionalDetailsandoptincontain. The server never returns either.PUT /Memberships/Member/{membershipId}: whether bothstartDateandendDateare required (the server always sends both), how the time zone is read, whether the change triggers emails, renewals, payments or status changes in JustGo, whetherapplication/jsonis accepted (the spec lists it alongsideapplication/json-patch+json), and what the 201 body contains (the spec saysHttp200UpdateResponse).The wording of JustGo's error messages and whether any of them echo request data; the texts in the mock are its own, because the spec has no examples.
A 429 is retried for the
PUTtoo, on the assumption that a rate-limited request was not applied; JustGo documents no 429 at all.How many requests per second the API tolerates; nothing is documented, so the 250 ms spacing is a guess on the polite side.
Going to production
This version runs locally over stdio with the organisation's own API secret. For governing bodies and clubs to connect from claude.ai or ChatGPT without handling secrets, the next step is a remote server (Streamable HTTP) behind OAuth, hosted by JustGo, so each user's own permissions apply, and then a listing in the Claude and ChatGPT connector directories. Further write tools (suspensions, credential updates, bookings) can follow once they can be tested on a real account.
Licence
MIT. Built by Alexandru Dragoș (alexandru.dragos96@gmail.com) with an AI agent (Claude) working under his direction.
Available Tools
9 toolsfind_membersFind membersARead-only
Search members with JustGo's documented member filters (email, member number, login ID, last name, organisation, credential, event, membership, suspension status, modified dates). Returns ID, member number, name, member status and suspension level; contact details, date of birth, address and parents' details only with include_contact_details. Note that a match on an email filter still confirms that such an address is registered, even though the address itself is not shown.
Inputs: page, email, event_id, login_id, +11 more.
get_eventGet eventARead-only
One event with its tickets (price, places booked and remaining), promoters (names and roles; contact details only on request) and stages.
Inputs: event_id (required), include_contact_details.
get_memberGet memberARead-only
One member with their memberships, organisations (with roles), credentials, event bookings and linked family members. Names and statuses by default; contact details, date of birth, address and parents' details only with include_contact_details. Free-form additional details and opt-in answers are never returned.
Inputs: member_id (required), include_contact_details.
get_organisationGet organisationBRead-only
One club or organisation with its awards (organisation credentials, with granted and expiry dates) and memberships.
Inputs: organisation_id (required), include_contact_details.
list_event_bookingsList event bookingsARead-only
Bookings (candidates) on events: who booked which ticket, booking status and dates. Names by default, email addresses only with include_contact_details.
Inputs: page, category, event_id, max_pages, +6 more.
list_eventsList eventsCRead-only
Events (courses, competitions and the like) with dates, booking deadline, venue, category, status, organiser and stages, filtered with the documented parameters.
Inputs: page, status, category, max_pages, +7 more.
list_member_credentialsList member credentialsARead-only
Credentials held by members, such as coaching or officiating qualifications and licences, with status, reference number, start date and end (expiry) date. Pass member_id for one member's credentials.
Inputs: page, status, category, max_pages, +5 more.
list_member_membershipsList member membershipsARead-only
Memberships held by members (name, category, classification, status, start and end dates, owning organisation), filtered with the documented parameters. Pass member_id for one member's memberships.
Inputs: page, status, category, owner_id, +8 more.
list_organisationsList organisationsARead-only
Clubs and other organisations with number, type, status, town, region, website and join link. Email, phone, street address, postcode and map position only with include_contact_details (a club's contact details are often a volunteer's own).
Inputs: page, type, status, max_pages, +8 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 9 tools
Each tool targets a distinct resource (organisations, members, memberships, credentials, events, bookings) with clear list/get or search semantics. Minor overlap risk between find_members and list_member_memberships/list_member_credentials, but the descriptions distinguish member records from their sub-resources.
Strong verb_noun pattern throughout (list_organisations, get_organisation, list_events, get_event, list_event_bookings) with consistent British spelling. The only deviation is find_members, which uses 'find' instead of the otherwise uniform list/get verbs.
Nine tools is well-scoped for a domain spanning organisations, members, memberships, credentials, events and bookings. Each tool earns its place by covering a distinct entity or sub-resource, with no redundant entries.
Good read coverage: list+get for organisations, members and events, plus list for memberships, credentials and bookings. Minor gaps exist (no get for memberships/credentials/bookings and no write operations), but the surface appears intentionally read-oriented and supports core discovery workflows.
Related MCP Connectors
Spacebring MCP server. Look up members, bookings, invoices, subscriptions, events and more, and take everyday actions such as creating events or replying to support tickets, from MCP-compatible AI assistants that support remote servers with OAuth.
Discover, plan and run tools across your connected business systems through one OAuth MCP endpoint
MCP server unifying ERPs, CRMs, APIs and knowledge base for Claude, ChatGPT and Gemini.
Build and run AI workflows, agents, data tables and 1000+ API integrations from any MCP client.
Related MCP Servers
- 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 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
- AlicenseAqualityCmaintenanceEnables MCP clients such as Claude and ChatGPT to read events, performances, seating, packages, visits, transactions, and organisation context from a ticketing channel, and, when writes are enabled, create and release reservations.10MIT
- AlicenseBqualityCmaintenanceEnables Claude, ChatGPT and other MCP clients to read practice-management data including organization, clinicians, diaries, availability, bookings, patients, invoices, payments, staff tasks, services, and locations, and optionally create staff tasks, create bookings, and cancel bookings.15MIT