ThreatLocker MCP Tools & API Patterns
Overview
The ThreatLocker MCP server wraps the ThreatLocker Portal API
(https://portalapi.g.threatlocker.com/portalapi) and exposes tools
across computers, computer groups, approval requests, audit log
("Action Log" in the UI), and organizations. The API has two quirks
that surprise people: the auth header does NOT use Bearer, and most
"list" endpoints are POSTs against /Entity/EntityGetByParameters with
a structured body — not GETs with query strings.
Connection & Authentication
Raw API Key Header
ThreatLocker authenticates with a raw API key — no Bearer prefix:
| Header | Value |
|---|---|
Authorization | <apiKey> (raw, no prefix) |
ManagedClientId | (optional) for legacy partner setups |
organizationId | (optional) tenant to scope this call to |
Common mistake: Sending
Authorization: Bearer <key>returns 401. Send the key bare.
Environment Variables
export THREATLOCKER_API_KEY="your-raw-api-key"
export THREATLOCKER_BASE_URL="https://portalapi.g.threatlocker.com/portalapi"
Multi-Tenant Routing
ThreatLocker is built for MSPs and uses organizations as the tenant boundary. Three patterns:
- Default org — Omit the
organizationIdheader. The API uses the API key's primary organization. - Specific child org — Set
organizationIdto a child org ID to scope a single call to that tenant. - Fleet-wide fan-out — Set the body flag
childOrganizations: trueon*GetByParametersendpoints to roll up data across all child organizations the API key can see.
For tenant pivots, see the organizations skill.
Available MCP Tools
Computers
| Tool | Description |
|---|---|
threatlocker_computers_list | List computers with pagination/filters |
threatlocker_computers_get | Get full details for one computer |
threatlocker_computers_get_checkins | Recent check-in history |
Computer Groups
| Tool | Description |
|---|---|
threatlocker_computer_groups_list | Full group list with metadata |
threatlocker_computer_groups_dropdown | Slim list for selection UIs |
Approval Requests
| Tool | Description |
|---|---|
threatlocker_approvals_list | List approval requests |
threatlocker_approvals_get | Single approval with full context |
threatlocker_approvals_pending_count | Quick pending-queue size |
threatlocker_approvals_get_permit_application | Application that would be permitted |
Audit Log (Action Log)
| Tool | Description |
|---|---|
threatlocker_audit_search | Search Action Log by time/host/file |
threatlocker_audit_get | Full record for one action |
threatlocker_audit_file_history | All actions for a given file path/hash |
Organizations
| Tool | Description |
|---|---|
threatlocker_organizations_list_children | All child orgs visible to the key |
threatlocker_organizations_get_auth_key | Auth key for a specific org |
threatlocker_organizations_for_move_computers | Orgs eligible as move targets |
POST-Based "GetByParameters" Pattern
Most list endpoints are POST /Entity/EntityGetByParameters with a
JSON body. Request shape:
{
"pageNumber": 1,
"pageSize": 50,
"isAscending": false,
"orderBy": "lastCheckin",
"searchText": "",
"childOrganizations": false
}
Response shape:
{
"totalItems": 1284,
"items": [ /* array of entities */ ]
}
Pagination
ThreatLocker uses page numbers, not cursors:
- Call with
pageNumber: 1,pageSize: 50(or 100/200). - Compute
totalPages = ceil(totalItems / pageSize). - Continue until you have collected
totalItemsrows or reached the last page.
Avoid huge pageSize values — large pages can time out. 50–200 is the
sweet spot.
Sort and Search
orderByis an entity-specific column name (e.g.lastCheckin,computerName).isAscendingtoggles direction.searchTextis a substring match across the entity's searchable columns (computer name, hostname, OS, etc.).
Error Handling
| Code | Meaning | Fix |
|---|---|---|
| 401 | Bad API key OR Bearer prefix included | Send raw key |
| 403 | Key valid, but no access to requested org | Check organizationId |
| 404 | Wrong endpoint or unknown entity ID | Recheck path |
| 429 | Rate limited | Backoff and retry |
| 500 | Portal API hiccup | Retry, then escalate |
Best Practices
- Default to
pageSize: 100and paginate; always checktotalItemsbefore assuming you have the full set. - For multi-tenant reports, fan out with
childOrganizations: truerather than looping per-org when the entity supports it. - Cache the result of
threatlocker_organizations_list_children— child org lists rarely change within a session. - Always pass
organizationIdexplicitly when generating client-facing reports so the source tenant is unambiguous.
Related Skills
- computers — Endpoint inventory
- computer-groups — Policy scoping
- approval-requests — Application approvals
- audit-log — Action Log investigation
- organizations — Multi-tenant pivots