MCPUpdated 2026-08-14

MCP Server

How to read and change PentaTrail CTEM data from an AI tool you have approved. This page covers connecting and approving, and what each tool does with a worked example.

Connecting

Endpoint
https://api.pentatrail.co/mcp
  1. 1. Register the endpoint

    Add https://api.pentatrail.co/mcp to your MCP-capable AI tool as a remote server. No key or user name is needed.

  2. 2. Approve it in your browser

    When the tool connects, your browser opens the PentaTrail sign-in and approval screen. The screen lists what that connection can actually do. Read it and choose “Approve”.

  3. 3. The tools become available

    Once approved, the tools on this page are callable from your AI tool. If you hold more than one contract, use ctem_list_my_contracts to find the contract_id and pass it to the other tools.

  4. 4. You can revoke it at any time

    Approved tools can be revoked at any time from Settings in the admin console (admin.pentatrail.co). Once revoked, that tool can read nothing.

Read tools

Tools that answer questions about the current state, bundled so one call is usually enough.

This page lists the required arguments and what each action needs. Optional arguments such as filters and sort keys are described by the tools themselves — the tool list your AI client receives (tools/list) is the authority for the full set.

ctem_list_domains

The monitored domains and their verification state. Start here — every id in the default result can be passed to the other tools as domain_id.

Arguments

contract_idoptionalOptional when you belong to a single contract. Required only if you belong to more than one.
include_archivedoptionalAlso return domains removed from monitoring (default false). Ids that are not active cannot be used as domain_id elsewhere.
domain_idoptionalWhen given, the WHOIS registration facts for that domain are included.
Success
ctem_list_domains()

{
  "data": { "domains": [ … ], "plan": { … } }
}
ctem_get_domain_overview

The current state of one domain: asset counts, open findings by Threat Discovery Level, and what changed recently — in one call.

Arguments

contract_idoptionalOptional when you belong to a single contract. Required only if you belong to more than one.
domain_idrequiredThe domain to work on. Pass an id returned by ctem_list_domains.
Success
ctem_get_domain_overview({ domain_id: "…" })

{
  "data": {
    "assets_counts": { … },
    "findings_severity": { … },
    "changes": [ … ]
  }
}
ctem_list_assets

Lists discovered assets. Pick what to look at with kind (hosts, IPs, URLs, ports, technologies, buckets, exclusions, and the hosts approved for active scanning).

Arguments

contract_idoptionalOptional when you belong to a single contract. Required only if you belong to more than one.
domain_idrequiredThe domain to work on. Pass an id returned by ctem_list_domains.
kindrequiredWhich assets to list: host / ip / url / port / port_group / tech / tech_group / bucket / exclusion / scan_scope. exclusion is the only place exclusion ids come from, and scan_scope lists the hosts approved for active scanning.
pageoptionalPage number (default 1).
limitoptionalItems per page (default 20).
searchoptionalKind-specific search. Filters a kind does not accept are rejected rather than silently ignored.
Success
ctem_list_assets({ domain_id: "…", kind: "host" })

{
  "data": { "assets": [ … ] },
  "pagination": { "page": 1, "limit": 20, … }
}
ctem_list_findings

Lists findings, highest Threat Discovery Level first. With status omitted you get open findings only, excluding informational ones.

Arguments

contract_idoptionalOptional when you belong to a single contract. Required only if you belong to more than one.
domain_idrequiredThe domain to work on. Pass an id returned by ctem_list_domains.
pageoptionalPage number (default 1).
limitoptionalItems per page (default 20).
statusoptionalFilter by status. Pass all to see every status.
Success
ctem_list_findings({ domain_id: "…" })

{
  "data": { "findings": [ … ], "matrix": [ … ] },
  "pagination": { … }
}
ctem_get_finding

One finding in detail, together with its detection history and the AI deep scan jobs tied to it.

Arguments

contract_idoptionalOptional when you belong to a single contract. Required only if you belong to more than one.
finding_idrequiredThe finding to read. Pass an id returned by ctem_list_findings. This tool takes no domain — the finding id is enough.
Success
ctem_get_finding({ finding_id: "…" })

{
  "data": {
    "finding": { … },
    "detection_history": { "first_detected": "…", "events": [ … ] },
    "deep_scan_jobs": [ … ]
  }
}
ctem_get_prioritization

What to work on next: risk bands, the hosts behind them, owners, classification, and attack-path chokepoints — in one call.

Arguments

contract_idoptionalOptional when you belong to a single contract. Required only if you belong to more than one.
domain_idrequiredThe domain to work on. Pass an id returned by ctem_list_domains.
fqdnoptionalOptional. When given, the detail for that host is included as well.
asset_typeoptionalOptional. When given, the classification tags for that asset type are included as well.
Success
ctem_get_prioritization({ domain_id: "…" })

{
  "data": {
    "bands": [ … ],
    "hosts": [ … ],
    "host_owners": [ … ],
    "chokepoints": { "rows": [ … ], "uncovered_finding_count": … }
  }
}
ctem_list_groups

Groups, their members, and the people on the contract. Pass group_id to include that group’s members as well.

Arguments

contract_idoptionalOptional when you belong to a single contract. Required only if you belong to more than one.
domain_idrequiredThe domain to work on. Pass an id returned by ctem_list_domains.
group_idoptionalOptional. When given, that group’s members are included as well.
Success
ctem_list_groups({ domain_id: "…" })

{
  "data": {
    "groups": [ … ],
    "contract_members": [ … ],
    "triage_summary": { … }
  }
}
ctem_get_validation_state

Whether AI deep scanning is running — and if not, why. Includes the batches in flight and the history.

Arguments

contract_idoptionalOptional when you belong to a single contract. Required only if you belong to more than one.
domain_idrequiredThe domain to work on. Pass an id returned by ctem_list_domains.
Success
ctem_get_validation_state({ domain_id: "…" })

{
  "data": {
    "origin_state": { … },
    "active_batches": [ … ],
    "finding_stats": { … },
    "history": [ … ]
  }
}
ctem_list_tasks

The remediation tasks and how far they have got. Pass task_id to also learn which page a single task is on.

Arguments

contract_idoptionalOptional when you belong to a single contract. Required only if you belong to more than one.
domain_idrequiredThe domain to work on. Pass an id returned by ctem_list_domains.
pageoptionalPage number (default 1).
limitoptionalItems per page (default 20).
task_idoptionalOptional. When given, the location of that one task is included as well.
Success
ctem_list_tasks({ domain_id: "…" })

{
  "data": { "tasks": [ … ], "progress": { … } },
  "pagination": { … }
}
ctem_get_executive_summary

The executive view: score trend and the weekly summary. With week_start omitted it uses the latest week available. When a contract has no week to choose from, weekly_snapshot and week_start are absent from the reply rather than null; when a week exists but carries no summary, weekly_snapshot is null, and the briefing is null until one has been produced.

Arguments

contract_idoptionalOptional when you belong to a single contract. Required only if you belong to more than one.
domain_idrequiredThe domain to work on. Pass an id returned by ctem_list_domains.
week_startoptionalOptional. When omitted the latest available week is used. If no week is available, the weekly section is skipped.
Success
ctem_get_executive_summary({ domain_id: "…" })

{
  "data": {
    "score_trend": [ … ],
    "snapshot_weeks": [ … ],
    "weekly_snapshot": { … },
    "briefing": { … }
  }
}

Write tools

Tools that change state. Related operations share one tool; pick the operation with action.

ctem_manage_domain

Start monitoring a domain, ask for ownership verification, or remove it from monitoring.

actionregisterrequest_verificationarchive

Arguments

contract_idoptionalOptional when you belong to a single contract. Required only if you belong to more than one.
actionrequiredWhich operation to perform: register / request_verification / archive. Each action needs its own arguments; when one is missing the tool tells you which.
domainoptionalFor action="register": the domain name to start monitoring.
origin_domain_idoptionalFor action="request_verification" / "archive": which monitored domain.
Success
ctem_manage_domain({ action: "register", domain: "example.com" })

{
  "data": { "domain_id": "…", "domain": "example.com", "status": "active" }
}
ctem_manage_exclusions

Exclude assets from monitoring, or restore them — one at a time or in bulk. The exclusion ids you need to restore come from ctem_list_assets({ kind: "exclusion" }).

actionexcludeexclude_bulkrestorerestore_bulk

Arguments

contract_idoptionalOptional when you belong to a single contract. Required only if you belong to more than one.
actionrequiredWhich operation to perform: exclude / exclude_bulk / restore / restore_bulk. Each action needs its own arguments; when one is missing the tool tells you which.
domain_idoptionalFor action="exclude": which domain the asset belongs to.
origin_domain_idoptionalFor action="exclude_bulk" / "restore_bulk": which domain the assets belong to.
categoryoptionalFor action="exclude" / "exclude_bulk" / "restore_bulk": the asset category.
category_keyoptionalFor action="exclude": the single asset key.
category_keysoptionalFor action="exclude_bulk" / "restore_bulk": the asset keys.
exclusion_idoptionalFor action="restore": which exclusion to lift.
Success
ctem_manage_exclusions({ action: "restore", exclusion_id: "…" })

{
  "data": null
}
ctem_manage_group

Create, change and delete groups, assign hosts to them, and add or remove people.

actioncreateupdatedeleteassign_hostsadd_memberremove_member

Arguments

contract_idoptionalOptional when you belong to a single contract. Required only if you belong to more than one.
actionrequiredWhich operation to perform: create / update / delete / assign_hosts / add_member / remove_member. Each action needs its own arguments; when one is missing the tool tells you which.
group_idoptionalFor every action but create: which group. If you omit it with action="assign_hosts", the assets you list are removed from their current group.
nameoptionalFor action="create" (required) / "update": the group name.
user_idoptionalFor action="add_member" / "remove_member": which person.
asset_typeoptionalFor action="assign_hosts": host or ip.
asset_idsoptionalFor action="assign_hosts": which assets.
Success
ctem_manage_group({ action: "create", name: "公開Web" })

{
  "data": { "group_id": "…" }
}
ctem_classify_asset

Add and remove classification tags, and set the management type.

actionadd_tagsremove_tagsset_management_type

Arguments

contract_idoptionalOptional when you belong to a single contract. Required only if you belong to more than one.
actionrequiredWhich operation to perform: add_tags / remove_tags / set_management_type. Each action needs its own arguments; when one is missing the tool tells you which.
tagsoptionalFor action="add_tags": the tag rows to write.
asset_typeoptionalFor action="remove_tags": host or ip.
asset_idsoptionalFor action="remove_tags": which assets.
tag_keyoptionalFor action="remove_tags": which tag.
host_idoptionalFor action="set_management_type": which host.
management_typeoptionalFor action="set_management_type": the new management type.
Success
ctem_classify_asset({ action: "set_management_type", host_id: "…", management_type: "…" })

{
  "data": null
}
ctem_manage_validation

Only the stopping side of AI deep scanning. ⚠ Starting it stays in the console — approving hosts and consenting to automatic runs are done there.

actionrevoke_host_approvalrevoke_autorun_consentdisablecancel_batch

Arguments

contract_idoptionalOptional when you belong to a single contract. Required only if you belong to more than one.
actionrequiredWhich operation to perform: revoke_host_approval / revoke_autorun_consent / disable / cancel_batch. Each action needs its own arguments; when one is missing the tool tells you which.
origin_domain_idoptionalWhich domain (needed by every action but cancel_batch).
fqdnsoptionalFor action="revoke_host_approval": the hosts whose approval is taken back.
batch_idoptionalFor action="cancel_batch": which batch.
confirmoptionalFor action="disable" this must be true. Turning deep scanning off for a domain cannot be undone from here.
Success
ctem_manage_validation({ action: "revoke_host_approval", origin_domain_id: "…", fqdns: ["www.example.com"] })

{
  "data": {
    "approved_count": 0,
    "revoked_count": 1,
    "purged_jobs": 0,
    "skipped": []
  }
}
ctem_manage_task

Complete a remediation task, reopen it, change its status, or set the owner and due date.

actioncompletereopenset_statusset_assignment

Arguments

contract_idoptionalOptional when you belong to a single contract. Required only if you belong to more than one.
actionrequiredWhich operation to perform: complete / reopen / set_status / set_assignment. Each action needs its own arguments; when one is missing the tool tells you which.
task_idoptionalWhich task. Pass an id returned by ctem_list_tasks.
statusoptionalFor action="set_status": the new status.
assignee_user_idoptionalFor action="set_assignment": who owns it now.
Success
ctem_manage_task({ action: "complete", task_id: "…" })

{
  "data": null
}

Connection helper

One extra tool, separate from the CTEM set, used when you first connect.

ctem_list_my_contracts

Lists the contracts you belong to. Use it to find the contract_id to pass to the other tools when you belong to more than one. If you belong to none it returns an empty list rather than failing.

Success
ctem_list_my_contracts()

{
  "contracts": [
    { "contract_id": "…", "name": "…" }
  ]
}

Contact us