MCP server
What is MCP?
The Model Context Protocol (MCP) is an open standard that lets AI assistants and agents — Claude Code, Claude Desktop and many others — use external tools in a uniform way. An application exposes an MCP server; the assistant connects to it, discovers the tools it offers, and calls them when a request needs them.
TRAX LRS includes an MCP server. Once connected, an AI assistant can read your xAPI data and record statements in the stores you give it access to, within the permissions you decide.
How access works
Access is given with two kinds of resources, managed in the TRAX LRS web application under Access → API Consumers:
- MCP Access Keys. A key is the credential of one external access — for example "Claude Desktop — analytics team". The assistant sends it as a bearer token. A key alone grants nothing.
- MCP Clients. A client gives a key access to one store, with its own permissions and xAPI pipeline, like an HTTP client does. Attach several clients to a key to reach several stores.
So a single key can reach several stores, and each call made by the assistant runs as the client of the store it targets: same permissions, same pipeline, same store isolation as any other client.
Configuration
Enable the MCP server
The MCP server is enabled by default in the Extended Edition. It is controlled by an environment variable:
| Variable | Default | Purpose |
|---|---|---|
MCP_API |
true |
Enables the MCP endpoint (/trax/api/mcp). When false, the endpoint does not exist. |
SERVICE_MCP_HOST |
APP_URL |
Only for distributed deployments — the host of the MCP service. In a monolith, leave as is. |
The endpoint accepts up to 120 requests per minute.
Create an MCP access key
- Go to Access → API Consumers → MCP Access Keys and click on the [+ MCP Access Key] button.
- Enter a name and a description. The description is required: explain who will use the key and for what. It is kept for audit purposes.
- Optionally, set an expiry date.
- Copy the token shown after creation. It is shown only once: TRAX LRS stores it hashed and can never display it again.
If a token leaks or is lost, use Regenerate token: a new token is shown once and the previous one stops working immediately. The key keeps its MCP clients, so nothing else has to be reconfigured.
Create MCP clients
- Go to Access → API Consumers → MCP Clients and click on the [+ MCP Client] button.
- Enter a name and a slug. The slug identifies the source of the statements and logs; it is stored
with an
mcp:prefix (e.g.mcp:analytics). A slug is suggested from the name: click it to use it. - Choose the MCP access key. It can't be changed later: this is what makes it possible to know which key recorded what.
- Choose the store. A key can have only one client per store.
- Choose the permissions:
data/all— read the data of the store (all the Data API entities);xapi/statements/write— record statements in the store.
- Adjust the xAPI pipeline and the authority if needed. The authority proposed by default is
mcp, so that the statements recorded through MCP are easy to recognise.
The permissions and the pipeline can be edited at any time. The slug and the key can't.
Revoke and purge
- Revoking a client stops it immediately.
- Revoking a key stops it immediately and revokes all its clients. The keys page shows how many clients each key has, and warns you before confirming.
- Revoked keys and clients are kept for audit: use the revoked filters to browse them. Their slugs are never reused, so the statements recorded with them always point to the right client.
- To delete them for good, use the purge command, for example to remove what was revoked more than a year ago:
php artisan mcp-access:purge --days=365
--days=0 purges everything revoked. There is no purge action in the web application.
Use it from Claude Code
As an example, here is how to connect Claude Code to TRAX LRS. Replace the URL with your TRAX LRS URL, and
<key> with your token:
claude mcp add --transport http --scope local trax http://my-lrs.example.com/trax/api/mcp --header "Authorization: Bearer <key>"
Check the connection with claude mcp list (or /mcp inside Claude Code), then simply ask:
List the reachable TRAX stores.
Claude calls the list_stores tool and shows the stores of your key, with what each one allows. From there,
ask questions about your data, or ask Claude to record statements:
Are these stores empty?
Record a typical cmi5 session in the secondary store, from initialization to termination.
To remove the server: claude mcp remove trax.
Any MCP client supporting the HTTP transport works the same way: declare the endpoint and send the token in
the Authorization: Bearer <key> header. TRAX LRS doesn't use OAuth for MCP.
Available tools
Every tool acting on data takes a store argument: the slug of the store to act on. It may be omitted
when the key reaches a single store.
Stores
| Tool | Purpose |
|---|---|
list_stores |
The stores reachable with the key, and whether each one allows reading data and writing statements. |
Reading data (Data API)
These tools require the data/all permission. Their filters and options are those of the
Data API.
| Tool | Purpose | Reference |
|---|---|---|
data_statements |
Query the statements | Statements |
data_activities |
Query the activities | Activities |
data_agents |
Query the agents | Agents |
data_activity_profiles |
Query the activity profiles | Activity Profiles |
data_agent_profiles |
Query the agent profiles | Agent Profiles |
data_states |
Query the states | States |
data_verbs |
Query the verbs used in the statements | Verbs |
data_activity_types |
Query the activity types | Activity Types |
data_activity_ids |
Query the activity identifiers | Activity IDs |
data_agent_ids |
Query the agent identifiers | Agent IDs |
data_document_ids |
Query the document identifiers (states and profiles) | Document IDs |
The server also exposes the Data API reference as an MCP resource (data_api_reference), so the assistant
can read the full list of filters and response fields.
Recording statements (Standard API)
| Tool | Purpose | Reference |
|---|---|---|
xapi_post_statements |
Record one or several statements, or one statement with a given ID | Statements |
It requires the xapi/statements/write permission. The statements go through the xAPI validation and the
pipeline of the client, as for any other client. To void a statement, record a voiding statement.
Traceability
Everything done through MCP is traceable:
- each statement records the slug of the client that wrote it —
mcp:…for MCP clients — and so, through the client, the key that was used; - the statements carry the authority of the client (
mcpby default); - the logs record
mcpas the service that received the request.
Why only statements can be written
Statements are append-only: once recorded, they are never modified nor deleted — a mistake is corrected by recording a voiding statement, which itself remains in the store. Whatever an assistant writes, the history stays complete and verifiable.
The other resources of the Standard API — states, activity profiles and agent profiles — are documents that are overwritten or deleted, with no history. Letting an AI assistant change them could silently destroy data written by your learning content. They are therefore not writable through MCP.
The Agents and Activities resources of the Standard API are not concerned: they are read-only, and their
content is already accessible through the data_agents and data_activities tools.
Why administration functions are not exposed
The MCP server gives access to data only. Stores, clients, users, connections, jobs, logs and settings are deliberately out of reach.
An AI assistant acts on instructions that may come from content it reads — a web page, a document, a statement. A malicious instruction hidden in such content could ask it to create an access, raise its own permissions or delete data. Keeping administration out of the MCP server means that, whatever happens, an assistant can't change who has access to your LRS, nor go beyond the stores and permissions you gave it.