You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fleet-wide audit of every plugin's documented MCP tool names against the tool names its shipped server actually registers. Audited against main @ 44c57a4 (post-#175), so the anti-trigger/GOVERNANCE pass (#161–#175) is included.
This issue is an audit only. No SKILL.md was edited. Corrections are a separate non-additive pass.
Headline
64 vendor-backed plugins audited (76 total minus 12 pack/meta plugins with no single vendor server).
18 have confirmed drift. 34 verified clean. 12 could not be verified.
The "reported clean" list mostly holds — 14 of 15 confirmed; kaseya/it-glue is a false clean (1 drifted name in its GOVERNANCE.md).
The rootly finding was reported backwards. The gateway routes rootly to mcp.rootly.com; it is the local-repo-shaped skills that are wrong, and 4 skills document names that exist on neither upstream.
pax8's local repo is deliberate dead code, not a routing error — with a live CI hazard attached.
Severity: critical = an agent following the primary path fails on most calls; high = a named agent/command breaks; medium = reference tables wrong, primary path works; structural = wrong server documented, not a rename.
vendor
real tools
doc'd
drifted
renamed / absent
uses
classification
severity
rootly
253 (hosted)
~60
~45
— / many
many
wrong-upstream
critical
email-security/proofpoint
44
45
31
28 / 3
105
renamed + absent
critical
email-security/knowbe4
34
36
27
22 / 5
72
renamed + absent
critical
abnormal/abnormal-security
10
31
21
18 / 3
29
renamed + absent
critical
domotz/domotz
21
38
17
15 / 2
66
renamed + absent
critical
ironscales/ironscales
9
15
6
5 / 1
51
renamed + absent
critical
sherweb/sherweb
15
21
6
4 / 2
35
renamed + absent
high
saas-alerts/saas-alerts
30
36
6
6 / 0
19
renamed
high
spamtitan/spamtitan
9
12
3
3 / 0
20
renamed
high
inforcer/inforcer
19
22
3
3 / 0
20
renamed
high
mimecast/mimecast
10
11
1
1 / 0
12
renamed
high
freshdesk/freshdesk
66
69
3
3 / 0
5
renamed
medium
threatlocker/threatlocker
17
19
2
2 / 0
2
renamed
medium
connectwise/manage
51
53
2
2 / 0
2
absent (governance)
medium
huntress/huntress
32
33
1
0 / 1
2
absent
medium
timezest/timezest
14
15
1
1 / 0
1
renamed
medium
kaseya/it-glue
24
25
1
1 / 0
1
renamed (governance)
medium
quickbooks/quickbooks-online
133
63
1
1 / 0
1
absent (governance)
medium
pax8/pax8
unverified
15
—
—
—
structural (dead local server)
high
"Uses" counts every occurrence across all doc files, not distinct names — it is the better proxy for how often an agent would actually hit a bad name.
The two structural cases
1. rootly — the reported finding is inverted
What is actually served.mcp-gateway/src/credentials/vendor-config.ts:2313-2318 sets containerUrl: 'https://mcp.rootly.com'. The validate() in the same entry POSTs to https://mcp.rootly.com/mcp and carries the comment "/mcp is what the gateway actually proxies against." The plugin has no .mcp.json; its README points at https://mcp.wyre.ai/v1/rootly/mcp, which proxies to Rootly. The local rootly-mcp repo is not in the request path at all.
Verified, not inferred. Unauthenticated probe → HTTP 401 (Authorization header with a valid Bearer token is required). With a real token from cortex-secret: initialize → HTTP 200, serverInfo {"name":"Rootly","version":"3.4.5"}; tools/list → 253 tools. Confirmed by dispatch, not merely by absence from a list:
tools/call
server response
incidents_get
Unknown tool: 'incidents_get'
severities_get
Unknown tool: 'severities_get'
rootly_list_postmortems
Unknown tool: 'rootly_list_postmortems'
list_severities
dispatched (upstream 404 on token scope) — not "Unknown tool"
Per-skill verdict:
skill
verdict
oncall
correct — all 5 names verified present. Ship as-is.
api-patterns
7 of 31 names real. Also claims "25 dynamically generated tools"; live count is 253.
incidents
AI/on-call names right, every CRUD name wrong.
postmortems
0 of 8 names exist on either upstream.
services
0 of 5.
alerts
0 of 4.
workflows
0 of 6.
The rootly_* names in those four skills are not the local repo's names either — the local repo uses rootly_<domain>_<verb> (rootly_alerts_list), the skills use rootly_<verb>_<noun> (rootly_list_alerts). Word order reversed. These names exist nowhere.
All 5 commands reference at least one nonexistent tool; service-status and action-items are 100% nonexistent. Both agents additionally declare tools: ["Bash","Read","Write","Glob","Grep"] in frontmatter with no mcp__* entry — even with corrected names they could not call Rootly. Separate bug.
Name mapping for the fix: incidents_get→list_incidents/search_incidents, incidents_post→create_incident, ..._alerts_get→list_incident_alerts, ..._alerts_post→attach_alert, ..._action_items_get→list_incident_action_items, ..._action_items_post→create_incident_action_item, severities_get→list_severities, services_get→list_services, teams_get→list_teams, users_get→list_users, users_me_get→get_current_user, alerts_get→list_alerts, workflows_get→list_workflows, environments_get→list_environments, functionalities_get→list_functionalities, incident_types_get→list_incident_types. The postmortems skill needs a rewrite against Rootly's retrospectives model (list_retrospective_processes, get_incident_retrospective_step, update_incident_retrospective_step, list_all_incident_action_items) — Rootly has no "postmortem" resource.
Side findings: README lists 6 skills but 7 exist (oncall, the only correct one, is missing from the table); README line 67 tells users to "Add the .mcp.json from this plugin" and no such file exists; plugin.json says 0.2.3 while the README changelog stops at 0.1.0; the gateway sets isStateful: true but the live server issues no mcp-session-id and serves tools/call without one.
2. pax8 — dead code, deliberate, with a live CI hazard
Verdict: dead code, not a routing error. The replacement was an explicit decision recorded in both repos:
msp-claude-plugins/CHANGELOG.md:99 — "Switched to Pax8's official hosted MCP server at https://mcp.pax8.com/v1/mcp — replaces our custom pax8-mcp server"
mcp-gateway/CHANGELOG.md:975 — "pax8: use official hosted MCP server with token auth" (6ba6c23)
mcp-gateway/CLAUDE.md:113 — "Hosted first-party MCPs (Rootly …, PagerDuty …, Pax8, BetterStack, etc.) must NOT be in this array"
check
result
az containerapp show --name gwp-pax8 -g mcp-gateway-prod
ResourceNotFound (53 ACAs exist; gwp-huntress present as control)
azure/main.bicepvendors array
pax8 absent
docker-compose.yml (48 services)
no pax8-mcp
.harness/vendors.json (12 vendors)
pax8 absent
ghcr.io/wyre-technology/pax8-mcp
exists — 12 versions, v1.1.2 + latest, 2026-07-24
release deploy job
never run — skipped in all 18 Release runs
There is also a credential incompatibility that makes routing impossible in principle: pax8-mcp/src/index.ts:10-11 requires PAX8_CLIENT_ID/PAX8_CLIENT_SECRET (OAuth2 partner API) via X-Pax8-Client-ID/X-Pax8-Client-Secret; the gateway supplies mcpToken → x-pax8-mcp-token. Different credential, different header, different auth system. So pax8_orders_create and pax8_subscriptions_update are unreachable — not a live write exposure.
⚠️Live hazard, worth its own issue on pax8-mcp:pax8-mcp/.github/workflows/release.yml still carries a deploy job pinned to vendor-slug: pax8 running az containerapp update --name gwp-pax8 -g mcp-gateway-prod. It has been masked purely by upstream job failures (MCP Registry + Security Scan). If those are ever fixed the deploy fires and fails on ResourceNotFound — and the obvious "fix" (creating gwp-pax8, or adding { slug: 'pax8' } to the bicep vendors array) would set VENDOR_URL_PAX8=http://gwp-pax8, clobber https://mcp.pax8.com/v1, and break the working hosted vendor. That is exactly the failure CLAUDE.md:113 documents. The repo is actively maintained (Dependabot through 2026-08-03), so this will resurface.
Docs status — cannot be closed out yet. The plugin documents 15 hyphen-delimited names (pax8-list-companies, pax8-get-company-by-uuid, …); grep "pax8_" across the whole plugin returns zero matches, so it is at least in the right namespace for the hosted server. But the "15 read-only tools" claim traces solely to skills/api-patterns/SKILL.md:18 — no Pax8-authored source confirms the count or the read-only property. Two counter-signals: the gateway's own cache allowlist (mcp-gateway/src/proxy/result-cache.ts:577-585) contains a 16th name, pax8-lookup-product, that the plugin does not list; and Pax8's OAuth metadata advertises scope Manage:Pax8Data — "Manage", not "Read". POST https://mcp.pax8.com/v1/mcp → HTTP 401 (Missing x-pax8-mcp-token header) and cortex-secret holds no Pax8 token, so the real surface stays unverified. Also: README.md:11 promises "Provision, modify, and cancel cloud subscriptions" with no write tool behind it, and both agents declare tools: ["Bash","Read","Write","Glob","Grep"] with no mcp__* entry, so neither can reach Pax8 at all.
Governance allowlists inherited the drift
This is the reason a governance allowlist has to be generated from tools/list rather than written from skills.
proofpoint — GOVERNANCE.md:31 Destructive row lists proofpoint_forensics_search_destroy, which does not exist. The real destructive tool, proofpoint_forensics_pull_messages ("Auto-pull (search & destroy) messages from mailboxes"), appears in no doc file, including the allowlist. 34 of proofpoint's 105 drifted uses are inside GOVERNANCE.md.
knowbe4 — 23 drifted uses inside GOVERNANCE.md; the entire Read row was transcribed from the drifted skill names.
connectwise/manage, kaseya/it-glue, quickbooks — their only drift is in GOVERNANCE.md: cw_delete_time_entry, cw_update_time_entry, itglue_create_document (real name is unprefixed create_document), qbo_invoices_update. All four verified nonexistent by grep against the server sources.
domotz is the counter-example and the model to copy — its GOVERNANCE.md:27 correctly classifies domotz_power_outlet_control as Destructive, and lines 107-108 explicitly warn that the skills "describe some tools under older names (for example domotz_list_devices or domotz_scan_network) that the current server does not expose." The governance author saw the drift and documented it rather than fixing it. (Two of domotz's GOVERNANCE.md "hits" in the table below are that warning, not new drift.)
Correction to the brief:domotz_power_outlet_control is no longer undocumented as of #167 — it is in the allowlist, correctly classified. It was undocumented at #160.
Undocumented tools (server exposes it, no doc mentions it)
Where a plugin has a GOVERNANCE.md the gap is now mostly closed. What remains:
proofpoint_forensics_pull_messages — DESTRUCTIVE, removes delivered mail
email-security/knowbe4
25 of 34
1
knowbe4_execute_tool (arbitrary tool dispatch)
email-security/checkpoint-avanan
13 of 13
4
hec_delete_exception — DESTRUCTIVE, IRREVERSIBLE; plus hec_restore_emails, hec_restore_events, hec_update_exception. Plugin has no GOVERNANCE.md and names no tools anywhere.
email-security/checkpoint-avanan is the highest-risk remaining gap: an allowlist built from its docs today would contain nothing, while the server ships an irreversible delete.
Per-vendor detail
Nearest-real-name is a similarity heuristic (segment Jaccard + Levenshtein). It is a starting point, not an authority — e.g. domotz_list_alerts is matched to domotz_alerts_profiles_list where domotz_alerts_device_list is more likely correct. Verify each before applying. — no equivalent exists means nothing scored above threshold: the documented capability is absent from the server, so the fix is to delete the claim, not rename it.
Expand all 17 script-detected vendors
abnormal/abnormal-security — server abnormal-mcp, 10 real tools (source: static+runtime)
documented (wrong)
real name
class
uses
first site
abnormal_list_cases
abnormal_cases_list
renamed
3
agents/email-threat-analyst.md:20
abnormal_list_threats
abnormal_threats_list
renamed
3
agents/email-threat-analyst.md:18
abnormal_cases_action
abnormal_cases_get
renamed
2
GOVERNANCE.md:95
abnormal_manage_remediation
abnormal_remediation_manage
renamed
2
agents/email-threat-analyst.md:18
abnormal_messages_headers
abnormal_messages_get
renamed
2
GOVERNANCE.md:96
abnormal_threats_remediate
abnormal_threats_get
renamed
2
GOVERNANCE.md:95
abnormal_ato_activity
— no equivalent exists
absent
1
skills/account-takeover/SKILL.md:92
abnormal_ato_cases_get
abnormal_cases_get
renamed
1
skills/account-takeover/SKILL.md:91
abnormal_ato_cases_list
abnormal_cases_list
renamed
1
skills/account-takeover/SKILL.md:90
abnormal_ato_remediate
— no equivalent exists
absent
1
skills/account-takeover/SKILL.md:93
abnormal_cases_actions
abnormal_cases_get
renamed
1
skills/cases/SKILL.md:113
abnormal_get_abuse_reports
abnormal_abuse_list
renamed
1
agents/email-threat-analyst.md:20
abnormal_get_message
abnormal_messages_get
renamed
1
agents/email-threat-analyst.md:18
abnormal_get_threat
abnormal_cases_get
renamed
1
agents/email-threat-analyst.md:18
abnormal_list_messages
abnormal_messages_list
renamed
1
agents/email-threat-analyst.md:18
abnormal_threats_actions
abnormal_threats_get
renamed
1
skills/threats/SKILL.md:120
abnormal_threats_unremediate
abnormal_threats_get
renamed
1
skills/threats/SKILL.md:122
abnormal_vendors_activity
— no equivalent exists
absent
1
skills/vendors/SKILL.md:93
abnormal_vendors_get
abnormal_messages_get
renamed
1
skills/vendors/SKILL.md:92
abnormal_vendors_list
abnormal_messages_list
renamed
1
skills/vendors/SKILL.md:91
abnormal_vendors_threats
abnormal_threats_get
renamed
1
skills/vendors/SKILL.md:94
connectwise/manage — server connectwise-manage-mcp, 51 real tools (source: static+runtime)
documented (wrong)
real name
class
uses
first site
cw_delete_time_entry
cw_create_time_entry
renamed
1
GOVERNANCE.md:49
cw_update_time_entry
cw_create_time_entry
renamed
1
GOVERNANCE.md:50
domotz/domotz — server domotz-mcp, 21 real tools (source: static+runtime+live-gw)
documented (wrong)
real name
class
uses
first site
domotz_list_devices
domotz_devices_list
renamed
11
GOVERNANCE.md:107
domotz_list_agents
domotz_agents_list
renamed
9
commands/alert-status.md:14
domotz_get_agent
domotz_agents_get
renamed
7
commands/device-inventory.md:14
domotz_list_alerts
domotz_alerts_profiles_list
renamed
6
commands/alert-status.md:14
domotz_scan_network
domotz_network_interfaces
renamed
5
GOVERNANCE.md:108
domotz_search_devices
domotz_devices_get
renamed
5
commands/device-lookup.md:14
domotz_get_device
domotz_devices_get
renamed
4
commands/device-inventory.md:14
domotz_list_eyes
domotz_agents_list
renamed
4
commands/site-overview.md:14
domotz_get_alert
domotz_agents_get
renamed
2
commands/alert-status.md:14
domotz_list_alert_profiles
domotz_alerts_profiles_list
renamed
2
skills/alerts/SKILL.md:118
domotz_list_eye_results
— no equivalent exists
absent
2
skills/api-patterns/SKILL.md:95
domotz_list_ports
domotz_agents_list
renamed
2
skills/api-patterns/SKILL.md:86
domotz_list_snmp_data
domotz_metrics_snmp_sensors_list
renamed
2
skills/api-patterns/SKILL.md:85
domotz_run_speed_test
— no equivalent exists
absent
2
skills/api-patterns/SKILL.md:87
domotz_get_agent_status
domotz_status
renamed
1
skills/api-patterns/SKILL.md:61
domotz_get_device_status
domotz_status
renamed
1
skills/api-patterns/SKILL.md:70
domotz_get_eye
domotz_agents_get
renamed
1
skills/api-patterns/SKILL.md:94
email-security/knowbe4 — server knowbe4-mcp, 34 real tools (source: static+runtime)
documented (wrong)
real name
class
uses
first site
knowbe4_training_list_campaigns
knowbe4_training_campaigns_list
renamed
6
GOVERNANCE.md:28
knowbe4_training_list_enrollments
knowbe4_training_enrollments_list
renamed
6
GOVERNANCE.md:28
knowbe4_phishing_list_campaigns
knowbe4_phishing_campaigns_list
renamed
4
GOVERNANCE.md:28
knowbe4_training_get_campaign
knowbe4_training_campaigns_get
renamed
4
GOVERNANCE.md:28
knowbe4_groups_list_members
knowbe4_groups_members
renamed
3
GOVERNANCE.md:28
knowbe4_phishing_get_campaign
knowbe4_phishing_campaigns_get
renamed
3
GOVERNANCE.md:28
knowbe4_phishing_get_recipient
knowbe4_phishing_campaigns_get
renamed
3
GOVERNANCE.md:28
knowbe4_phishing_get_security_test
knowbe4_phishing_security_test_get
renamed
3
GOVERNANCE.md:28
knowbe4_phishing_list_recipients
knowbe4_phishing_campaigns_list
renamed
3
GOVERNANCE.md:28
knowbe4_phishing_list_security_tests
knowbe4_phishing_security_tests_list
renamed
3
GOVERNANCE.md:28
knowbe4_training_list_modules
knowbe4_training_campaigns_list
renamed
3
GOVERNANCE.md:28
knowbe4_training_list_users
knowbe4_users_list
renamed
3
agents/security-awareness-analyst.md:20
knowbe4_users_list_events
knowbe4_users_list
renamed
3
GOVERNANCE.md:28
knowbe4_phishing_get_template
knowbe4_phishing_campaigns_get
renamed
2
GOVERNANCE.md:28
knowbe4_phishing_list_templates
knowbe4_phishing_campaigns_list
renamed
2
GOVERNANCE.md:28
knowbe4_reporting_account_summary
knowbe4_reporting_phishing_summary
renamed
2
GOVERNANCE.md:28
knowbe4_reporting_department_breakdown
— no equivalent exists
absent
2
GOVERNANCE.md:28
knowbe4_reporting_ppp_trend
— no equivalent exists
absent
2
GOVERNANCE.md:28
knowbe4_training_get_enrollment
knowbe4_training_enrollments_get
renamed
2
GOVERNANCE.md:28
knowbe4_training_get_module
knowbe4_training_campaigns_get
renamed
2
GOVERNANCE.md:28
knowbe4_training_get_store_purchase
knowbe4_training_enrollments_get
renamed
2
GOVERNANCE.md:28
knowbe4_training_list_phishing_tests
knowbe4_phishing_security_tests_list
renamed
2
agents/training-enforcer.md:22
knowbe4_training_list_store_purchases
knowbe4_store_purchases_list
renamed
2
GOVERNANCE.md:28
knowbe4_training_list_training_campaigns
knowbe4_training_campaigns_list
renamed
2
agents/training-enforcer.md:20
knowbe4_phisher_bulk_action
— no equivalent exists
absent
1
agents/security-awareness-analyst.md:18
knowbe4_phisher_get_message
— no equivalent exists
absent
1
agents/security-awareness-analyst.md:18
knowbe4_phisher_list_messages
— no equivalent exists
absent
1
agents/security-awareness-analyst.md:18
email-security/proofpoint — server proofpoint-mcp, 44 real tools (source: static+runtime)
documented (wrong)
real name
class
uses
first site
proofpoint_forensics_search_destroy
proofpoint_forensics_search_messages
renamed
6
GOVERNANCE.md:31
proofpoint_forensics_get_evidence
proofpoint_forensics_get_threat
renamed
5
GOVERNANCE.md:29
proofpoint_forensics_get_report
proofpoint_forensics_get_threat
renamed
5
GOVERNANCE.md:29
proofpoint_quarantine_bulk_release
proofpoint_quarantine_release
renamed
5
GOVERNANCE.md:31
proofpoint_quarantine_preview
proofpoint_quarantine_delete
renamed
5
GOVERNANCE.md:29
proofpoint_tap_get_all_events
proofpoint_tap_get_all_threats
renamed
5
GOVERNANCE.md:29
proofpoint_threat_get_indicators
proofpoint_threat_get_iocs
renamed
5
GOVERNANCE.md:29
proofpoint_url_get_clicks
proofpoint_tap_get_clicks_blocked
renamed
5
GOVERNANCE.md:29
proofpoint_threat_search_campaigns
proofpoint_threat_get_campaign
renamed
4
GOVERNANCE.md:29
proofpoint_url_batch_decode
proofpoint_url_decode
renamed
4
GOVERNANCE.md:29
proofpoint_forensics_auto_pull_status
proofpoint_forensics_pull_messages
renamed
3
GOVERNANCE.md:29
proofpoint_forensics_get_operation
proofpoint_forensics_get_campaign
renamed
3
GOVERNANCE.md:29
proofpoint_forensics_get_sandbox_report
proofpoint_forensics_get_threat
renamed
3
GOVERNANCE.md:29
proofpoint_forensics_message_trace
— no equivalent exists
absent
3
GOVERNANCE.md:29
proofpoint_get_campaign
proofpoint_threat_get_campaign
renamed
3
agents/email-security-auditor.md:19
proofpoint_get_siem_clicks
proofpoint_tap_get_clicks_blocked
renamed
3
agents/email-security-auditor.md:19
proofpoint_get_siem_messages
proofpoint_tap_get_messages_blocked
renamed
3
agents/email-security-auditor.md:19
proofpoint_people_get_attack_index
proofpoint_people_get_vap
renamed
3
GOVERNANCE.md:29
proofpoint_people_list_vip
proofpoint_people_get_vap
renamed
3
GOVERNANCE.md:29
proofpoint_quarantine_bulk_delete
proofpoint_quarantine_delete
renamed
3
GOVERNANCE.md:31
proofpoint_threat_get_family
proofpoint_threat_get_campaign
renamed
3
GOVERNANCE.md:29
proofpoint_threat_get_landscape
proofpoint_threat_get_campaign
renamed
3
GOVERNANCE.md:29
proofpoint_threat_search_indicators
— no equivalent exists
absent
3
GOVERNANCE.md:29
proofpoint_url_get_verdict
proofpoint_url_decode
renamed
3
GOVERNANCE.md:29
proofpoint_forensics_list_operations
— no equivalent exists
absent
2
GOVERNANCE.md:29
proofpoint_get_email_stats
proofpoint_events_get_stats
renamed
2
agents/email-security-auditor.md:21
proofpoint_list_orgs
proofpoint_list_categories
renamed
2
agents/email-security-auditor.md:21
proofpoint_people_set_vip
proofpoint_people_get_vap
renamed
2
GOVERNANCE.md:30
proofpoint_quarantine_get
proofpoint_quarantine_list
renamed
2
GOVERNANCE.md:29
proofpoint_tap_get_top_clickers
proofpoint_people_get_top_clickers
renamed
2
GOVERNANCE.md:29
proofpoint_threat_get_actor
proofpoint_threat_get_iocs
renamed
2
GOVERNANCE.md:29
freshdesk/freshdesk — server freshdesk-mcp, 66 real tools (source: static+runtime)
documented (wrong)
real name
class
uses
first site
freshdesk_sla_policies_list
freshdesk_sla_list
renamed
2
README.md:76
freshdesk_tickets_conversations
freshdesk_tickets_list_conversations
renamed
2
README.md:59
freshdesk_solutions_articles_search
freshdesk_solutions_articles_create
renamed
1
README.md:73
huntress/huntress — server huntress-mcp, 32 real tools (source: static+runtime+prod-schema)
documented (wrong)
real name
class
uses
first site
huntress_back
— no equivalent exists
absent
2
skills/api-patterns/SKILL.md:48
inforcer/inforcer — server inforcer-mcp, 19 real tools (source: static+runtime)
documented (wrong)
real name
class
uses
first site
inforcer_secure_scores
inforcer_secure_scores_get
renamed
10
GOVERNANCE.md:51
inforcer_audit_events_search
inforcer_audit_search
renamed
6
GOVERNANCE.md:51
inforcer_tenant_policies_list
inforcer_policies_list
renamed
4
GOVERNANCE.md:52
ironscales/ironscales — server ironscales-mcp, 9 real tools (source: static+runtime)
documented (wrong)
real name
class
uses
first site
ironscales_classify_email
ironscales_email_classify
renamed
11
agents/phishing-responder.md:19
ironscales_get_company_stats
ironscales_stats_company
renamed
10
agents/crowdsourced-intel-harvester.md:21
ironscales_get_incident
ironscales_incidents_get
renamed
10
agents/phishing-responder.md:19
ironscales_list_incidents
ironscales_incidents_list
renamed
8
agents/phishing-responder.md:36
ironscales_remediate_incident
— no equivalent exists
absent
7
agents/phishing-responder.md:19
ironscales_manage_allowlist
ironscales_allowlist_manage
renamed
5
agents/phishing-responder.md:21
kaseya/it-glue — server itglue-mcp, 24 real tools (source: static+prod-schema+live-gw)
documented (wrong)
real name
class
uses
first site
itglue_create_document
create_document
renamed
1
GOVERNANCE.md:81
mimecast/mimecast — server mimecast-mcp, 10 real tools (source: static)
documented (wrong)
real name
class
uses
first site
mimecast_get_queue
mimecast_get_queue_status
renamed
12
GOVERNANCE.md:113
quickbooks/quickbooks-online — server qbo-mcp, 133 real tools (source: static+runtime)
documented (wrong)
real name
class
uses
first site
qbo_invoices_update
qbo_invoices_create
renamed
1
GOVERNANCE.md:130
saas-alerts/saas-alerts — server saas-alerts-mcp, 30 real tools (source: static+runtime)
documented (wrong)
real name
class
uses
first site
saas_alerts_users_get
saas_alerts_users_get_msp
renamed
7
README.md:54
saas_alerts_devices_get
saas_alerts_customers_get
renamed
4
README.md:57
saas_alerts_billing_get
saas_alerts_billing_get_details
renamed
2
README.md:60
saas_alerts_billing_list
saas_alerts_billing_list_dates
renamed
2
README.md:60
saas_alerts_devices_list
saas_alerts_devices_list_orgs
renamed
2
README.md:57
saas_alerts_users_list
saas_alerts_users_list_partner
renamed
2
README.md:54
sherweb/sherweb — server sherweb-mcp, 15 real tools (source: static+runtime)
documented (wrong)
real name
class
uses
first site
sherweb_billing_get_billing_periods
— no equivalent exists
absent
9
commands/billing-summary.md:14
sherweb_billing_get_payable_charges
sherweb_billing_payable_charges
renamed
8
commands/billing-summary.md:14
sherweb_customers_get_accounts_receivable
sherweb_customers_accounts_receivable
renamed
8
commands/list-customers.md:14
sherweb_billing_get_invoices
— no equivalent exists
absent
5
skills/api-patterns/SKILL.md:177
sherweb_billing_get_invoice_details
sherweb_billing_charge_details
renamed
3
skills/api-patterns/SKILL.md:178
sherweb_billing_get_charge_details
sherweb_billing_charge_details
renamed
2
skills/api-patterns/SKILL.md:176
spamtitan/spamtitan — server spamtitan-mcp, 9 real tools (source: static+runtime)
documented (wrong)
real name
class
uses
first site
spamtitan_list_allowlist
spamtitan_manage_allowlist
renamed
9
GOVERNANCE.md:126
spamtitan_list_blocklist
spamtitan_manage_blocklist
renamed
8
GOVERNANCE.md:126
spamtitan_get_domain_stats
spamtitan_get_stats
renamed
3
GOVERNANCE.md:127
threatlocker/threatlocker — server threatlocker-mcp, 17 real tools (source: static+prod-schema)
documented (wrong)
real name
class
uses
first site
threatlocker_computer_groups_get
threatlocker_computer_groups_list
renamed
1
README.md:60
threatlocker_organizations_get
threatlocker_organizations_get_auth_key
renamed
1
README.md:73
timezest/timezest — server timezest-mcp, 14 real tools (source: static+live-gw)
documented (wrong)
real name
class
uses
first site
timezest_resources_get
timezest_resources_list
renamed
1
skills/resources/SKILL.md:62
Recommended fix order
Ordered by agent-breakage, not by count.
rootly — 4 skills (postmortems, services, alerts, workflows) document a server that does not exist. Delete or rewrite; do not rename. Then fix api-patterns (24 of 31 names fabricated, "25 tools" → 253) and incidents. Leave oncall alone. Add mcp__* entries to both agents' frontmatter.
email-security/proofpoint then email-security/knowbe4 — highest absolute breakage (105 and 72 uses), and their GOVERNANCE allowlists must be regenerated from tools/list, not patched by hand. Proofpoint first: its Destructive row is wrong in both directions.
abnormal/abnormal-security — 21 of 31 documented names wrong against a 10-tool server. Whole skills (vendors, account-takeover) describe capability the server does not have.
domotz/domotz — 100% of skill and command names wrong, 66 uses. Governance is already correct, so this is a mechanical skills-and-commands rename.
ironscales/ironscales — 51 uses against a 9-tool server; every name in agents/phishing-responder.md is wrong.
email-security/checkpoint-avanan — not drift, but the largest governance gap: 13 tools, 4 write-capable, 1 irreversible, zero documented.
pax8 — docs unblocked only after someone generates an x-pax8-mcp-token and captures the real tools/list. Separately, file the release.ymldeploy-job hazard against pax8-mcp.
Confirming / refuting the prior reports
Reported drifted (14): confirmed for inforcer, saas-alerts, threatlocker, abnormal, ironscales, mimecast, spamtitan, domotz, freshdesk, sherweb, rootly — 11. rootly confirmed but inverted, see above. betterstack and pagerdutycould not be verified (hosted, no credentials). pax8 is structural rather than name-drift, and its hosted surface is unverified.
Twelve plugins where ground truth could not be established. All are hosted upstreams or vendors with no local server repo. None should be treated as clean.
plugin
upstream
why unverified
pax8/pax8
https://mcp.pax8.com/v1
401 Missing x-pax8-mcp-token; no token in cortex-secret
pagerduty/pagerduty
https://mcp.pagerduty.com
401 on unauthenticated initialize; documents 8 pagerduty_* names
betterstack/betterstack
https://mcp.betterstack.com
404 on unauthenticated POST /mcp — worth a separate look, since the gateway's validate() uses that exact path; documents 5 betterstack_* names
hubspot/hubspot
https://mcp.hubspot.com/anthropic/v1/mcp
OAuth-gated; documents 26 names
slack/slack
https://mcp.slack.com
OAuth-gated; documents 0 tool names
stripe/stripe
https://mcp.stripe.com
OAuth-gated; documents 0 tool names
pandadoc/pandadoc
https://mcp.pandadoc.com/v1/mcp
OAuth-gated; documents 0 tool names
warmly/warmly
https://opps-api.getwarmly.com/api/mcp
auth-gated; documents 0 tool names
runzero/runzero
https://console.runzero.com/mcp
auth-gated; documents 19 runzero_* names
blackpoint/blackpoint
http://blackpoint-mcp
sidecar in vendor-config, no local repo available; documents 15 names
immybot/immybot
http://immybot-mcp
sidecar in vendor-config, no local repo available; documents 68 names
clio/clio
—
not in vendor-config.ts at all; documents 26 clio_* names
blackpoint, immybot and clio are the cheapest to resolve (check out the repo / add the vendor entry), and immybot documents 68 tool names with nothing currently verifying them.
Also flagged, not drift: mimecast, spamtitan, ironscales, sherweb, scalepad and connectwise-cpq ship plugins but have no entry in mcp-gateway/vendor-config.ts, so gateway users cannot reach them at all regardless of tool names.
Method
Ground truth, union of four sources per vendor:
runtime — spawn each <vendor>-mcp/dist/index.js over stdio, initialize → tools/list. 50 of 61 repos answered. Authoritative but incomplete for progressive-disclosure servers: 12 gate their surface behind a *_navigate call and advertise only 1–2 entrypoints at init (pax8-mcp returns exactly pax8_navigate).
static — scan src/** for MCP Tool object literals (name: "…" with an adjacent inputSchema) and server.registerTool(…) calls. Recovers the post-navigation surface. prompts.ts is excluded — MCP prompt argument definitions have the identical { name: '…' } shape and produced false tools (client_name, incident_id, customer_id) on the first pass.
prod-schema — mcp-gateway/schemas/<vendor>.json, pinned to the prod image digests in .harness/vendors.json. 12 vendors.
live-gw — tool names observed on the live mcp.wyre.ai connector during the audit. This is what resolved sentinelone (22 tools, no vendor prefix — list_alerts, powerquery, purple_ai), which both other sources missed.
Cross-check: the script reports staticMissed (runtime tools the static scan did not find). qbo-mcp and scalepad-mcp register from generated registries the static scan cannot see — for those two, runtime is authoritative and static alone would badly under-report.
Documented names — backtick-quoted snake_case tokens from each plugin's skills/**/SKILL.md, references/*.md, agents/*.md, commands/*.md, and root-level README.md / GOVERNANCE.md, filtered to tokens whose first segment matches a prefix the server actually uses.
Diff — set difference, plus a similarity score to split renamed (near-match exists) from absent (nothing close).
Hosted vendors — vendor-config.tscontainerUrl decides the real upstream. Where that is a vendor host, the local repo is ignored entirely; that is how the rootly and pax8 determinations were reached.
Verified vs inferred. Everything in the summary table and per-vendor detail is verified against server source or a live tools/list. Rootly's 253-tool surface was verified with a real token and confirmed per-name by tools/call dispatch. Pax8's hosted surface is inferred only — the "15 read-only tools" claim has no vendor-authored source. Everything in the Unverified section is explicitly not established.
Known limits of the script. It only sees names written in backticks; prose mentions are missed. The nearest-name suggestion is a heuristic. It cannot reach OAuth-gated hosted upstreams. Servers with no dist/ and no recognizable registration pattern fall through (3cx-mcp, float-mcp, nable-mcp, pco-mcp, autotask-projects-mcp).
The script
Two files. probe-tools.mjs builds the runtime source; tool-drift-audit.mjs does the diff and exits 1 on drift, so it can gate CI. A separate PR proposes adding it to scripts/ alongside check-marketplace-drift.mjs.
Fleet-wide audit of every plugin's documented MCP tool names against the tool names its shipped server actually registers. Audited against
main@44c57a4(post-#175), so the anti-trigger/GOVERNANCE pass (#161–#175) is included.This issue is an audit only. No SKILL.md was edited. Corrections are a separate non-additive pass.
Headline
kaseya/it-glueis a false clean (1 drifted name in its GOVERNANCE.md).mcp.rootly.com; it is the local-repo-shaped skills that are wrong, and 4 skills document names that exist on neither upstream.proofpoint_forensics_search_destroy(does not exist) while the real search-and-destroy tool,proofpoint_forensics_pull_messages, is absent from the allowlist entirely.Summary table
Severity: critical = an agent following the primary path fails on most calls; high = a named agent/command breaks; medium = reference tables wrong, primary path works; structural = wrong server documented, not a rename.
rootlyemail-security/proofpointemail-security/knowbe4abnormal/abnormal-securitydomotz/domotzironscales/ironscalessherweb/sherwebsaas-alerts/saas-alertsspamtitan/spamtitaninforcer/inforcermimecast/mimecastfreshdesk/freshdeskthreatlocker/threatlockerconnectwise/managehuntress/huntresstimezest/timezestkaseya/it-gluequickbooks/quickbooks-onlinepax8/pax8"Uses" counts every occurrence across all doc files, not distinct names — it is the better proxy for how often an agent would actually hit a bad name.
The two structural cases
1. rootly — the reported finding is inverted
What is actually served.
mcp-gateway/src/credentials/vendor-config.ts:2313-2318setscontainerUrl: 'https://mcp.rootly.com'. Thevalidate()in the same entry POSTs tohttps://mcp.rootly.com/mcpand carries the comment "/mcpis what the gateway actually proxies against." The plugin has no.mcp.json; its README points athttps://mcp.wyre.ai/v1/rootly/mcp, which proxies to Rootly. The localrootly-mcprepo is not in the request path at all.Verified, not inferred. Unauthenticated probe → HTTP 401 (
Authorization header with a valid Bearer token is required). With a real token fromcortex-secret:initialize→ HTTP 200,serverInfo {"name":"Rootly","version":"3.4.5"};tools/list→ 253 tools. Confirmed by dispatch, not merely by absence from a list:tools/callincidents_getUnknown tool: 'incidents_get'severities_getUnknown tool: 'severities_get'rootly_list_postmortemsUnknown tool: 'rootly_list_postmortems'list_severitiesPer-skill verdict:
oncallapi-patternsincidentspostmortemsservicesalertsworkflowsThe
rootly_*names in those four skills are not the local repo's names either — the local repo usesrootly_<domain>_<verb>(rootly_alerts_list), the skills userootly_<verb>_<noun>(rootly_list_alerts). Word order reversed. These names exist nowhere.All 5 commands reference at least one nonexistent tool;
service-statusandaction-itemsare 100% nonexistent. Both agents additionally declaretools: ["Bash","Read","Write","Glob","Grep"]in frontmatter with nomcp__*entry — even with corrected names they could not call Rootly. Separate bug.Name mapping for the fix:
incidents_get→list_incidents/search_incidents,incidents_post→create_incident,..._alerts_get→list_incident_alerts,..._alerts_post→attach_alert,..._action_items_get→list_incident_action_items,..._action_items_post→create_incident_action_item,severities_get→list_severities,services_get→list_services,teams_get→list_teams,users_get→list_users,users_me_get→get_current_user,alerts_get→list_alerts,workflows_get→list_workflows,environments_get→list_environments,functionalities_get→list_functionalities,incident_types_get→list_incident_types. Thepostmortemsskill needs a rewrite against Rootly's retrospectives model (list_retrospective_processes,get_incident_retrospective_step,update_incident_retrospective_step,list_all_incident_action_items) — Rootly has no "postmortem" resource.Side findings: README lists 6 skills but 7 exist (
oncall, the only correct one, is missing from the table); README line 67 tells users to "Add the.mcp.jsonfrom this plugin" and no such file exists;plugin.jsonsays 0.2.3 while the README changelog stops at 0.1.0; the gateway setsisStateful: truebut the live server issues nomcp-session-idand servestools/callwithout one.2. pax8 — dead code, deliberate, with a live CI hazard
Verdict: dead code, not a routing error. The replacement was an explicit decision recorded in both repos:
msp-claude-plugins/CHANGELOG.md:99— "Switched to Pax8's official hosted MCP server athttps://mcp.pax8.com/v1/mcp— replaces our custom pax8-mcp server"mcp-gateway/CHANGELOG.md:975— "pax8: use official hosted MCP server with token auth" (6ba6c23)mcp-gateway/CLAUDE.md:113— "Hosted first-party MCPs (Rootly …, PagerDuty …, Pax8, BetterStack, etc.) must NOT be in this array"az containerapp show --name gwp-pax8 -g mcp-gateway-prodgwp-huntresspresent as control)azure/main.bicepvendorsarraydocker-compose.yml(48 services)pax8-mcp.harness/vendors.json(12 vendors)ghcr.io/wyre-technology/pax8-mcpv1.1.2+latest, 2026-07-24deployjobThere is also a credential incompatibility that makes routing impossible in principle:
pax8-mcp/src/index.ts:10-11requiresPAX8_CLIENT_ID/PAX8_CLIENT_SECRET(OAuth2 partner API) viaX-Pax8-Client-ID/X-Pax8-Client-Secret; the gateway suppliesmcpToken→x-pax8-mcp-token. Different credential, different header, different auth system. Sopax8_orders_createandpax8_subscriptions_updateare unreachable — not a live write exposure.pax8-mcp:pax8-mcp/.github/workflows/release.ymlstill carries adeployjob pinned tovendor-slug: pax8runningaz containerapp update --name gwp-pax8 -g mcp-gateway-prod. It has been masked purely by upstream job failures (MCP Registry + Security Scan). If those are ever fixed the deploy fires and fails on ResourceNotFound — and the obvious "fix" (creatinggwp-pax8, or adding{ slug: 'pax8' }to the bicepvendorsarray) would setVENDOR_URL_PAX8=http://gwp-pax8, clobberhttps://mcp.pax8.com/v1, and break the working hosted vendor. That is exactly the failureCLAUDE.md:113documents. The repo is actively maintained (Dependabot through 2026-08-03), so this will resurface.Docs status — cannot be closed out yet. The plugin documents 15 hyphen-delimited names (
pax8-list-companies,pax8-get-company-by-uuid, …);grep "pax8_"across the whole plugin returns zero matches, so it is at least in the right namespace for the hosted server. But the "15 read-only tools" claim traces solely toskills/api-patterns/SKILL.md:18— no Pax8-authored source confirms the count or the read-only property. Two counter-signals: the gateway's own cache allowlist (mcp-gateway/src/proxy/result-cache.ts:577-585) contains a 16th name,pax8-lookup-product, that the plugin does not list; and Pax8's OAuth metadata advertises scopeManage:Pax8Data— "Manage", not "Read".POST https://mcp.pax8.com/v1/mcp→ HTTP 401 (Missing x-pax8-mcp-token header) andcortex-secretholds no Pax8 token, so the real surface stays unverified. Also:README.md:11promises "Provision, modify, and cancel cloud subscriptions" with no write tool behind it, and both agents declaretools: ["Bash","Read","Write","Glob","Grep"]with nomcp__*entry, so neither can reach Pax8 at all.Governance allowlists inherited the drift
This is the reason a governance allowlist has to be generated from
tools/listrather than written from skills.GOVERNANCE.md:31Destructive row listsproofpoint_forensics_search_destroy, which does not exist. The real destructive tool,proofpoint_forensics_pull_messages("Auto-pull (search & destroy) messages from mailboxes"), appears in no doc file, including the allowlist. 34 of proofpoint's 105 drifted uses are inside GOVERNANCE.md.cw_delete_time_entry,cw_update_time_entry,itglue_create_document(real name is unprefixedcreate_document),qbo_invoices_update. All four verified nonexistent by grep against the server sources.GOVERNANCE.md:27correctly classifiesdomotz_power_outlet_controlas Destructive, and lines 107-108 explicitly warn that the skills "describe some tools under older names (for exampledomotz_list_devicesordomotz_scan_network) that the current server does not expose." The governance author saw the drift and documented it rather than fixing it. (Two of domotz's GOVERNANCE.md "hits" in the table below are that warning, not new drift.)Correction to the brief:
domotz_power_outlet_controlis no longer undocumented as of #167 — it is in the allowlist, correctly classified. It was undocumented at #160.Undocumented tools (server exposes it, no doc mentions it)
Where a plugin has a GOVERNANCE.md the gap is now mostly closed. What remains:
scalepad/scalepad⚠ DESTRUCTIVE — IRREVERSIBLE, incl.scalepad_lm_deliverables_delete,scalepad_cm_governance_delete,scalepad_lm_assessments_deletequickbooks/quickbooks-onlineqbo_sales_receipts_create/update,qbo_vendor_credits_create/updateemail-security/proofpointproofpoint_forensics_pull_messages— DESTRUCTIVE, removes delivered mailemail-security/knowbe4knowbe4_execute_tool(arbitrary tool dispatch)email-security/checkpoint-avananhec_delete_exception— DESTRUCTIVE, IRREVERSIBLE; plushec_restore_emails,hec_restore_events,hec_update_exception. Plugin has no GOVERNANCE.md and names no tools anywhere.azure-mcp/azure-mcpadvisor,applens,foundry,monitor,pricing,quota,resourcehealth,searchm365/m365microsoft_graph_*toolssentinelone/sentinelonepowerqueryemail-security/checkpoint-avananis the highest-risk remaining gap: an allowlist built from its docs today would contain nothing, while the server ships an irreversible delete.Per-vendor detail
Nearest-real-name is a similarity heuristic (segment Jaccard + Levenshtein). It is a starting point, not an authority — e.g.
domotz_list_alertsis matched todomotz_alerts_profiles_listwheredomotz_alerts_device_listis more likely correct. Verify each before applying.— no equivalent existsmeans nothing scored above threshold: the documented capability is absent from the server, so the fix is to delete the claim, not rename it.Expand all 17 script-detected vendors
abnormal/abnormal-security— serverabnormal-mcp, 10 real tools (source: static+runtime)abnormal_list_casesabnormal_cases_listagents/email-threat-analyst.md:20abnormal_list_threatsabnormal_threats_listagents/email-threat-analyst.md:18abnormal_cases_actionabnormal_cases_getGOVERNANCE.md:95abnormal_manage_remediationabnormal_remediation_manageagents/email-threat-analyst.md:18abnormal_messages_headersabnormal_messages_getGOVERNANCE.md:96abnormal_threats_remediateabnormal_threats_getGOVERNANCE.md:95abnormal_ato_activityskills/account-takeover/SKILL.md:92abnormal_ato_cases_getabnormal_cases_getskills/account-takeover/SKILL.md:91abnormal_ato_cases_listabnormal_cases_listskills/account-takeover/SKILL.md:90abnormal_ato_remediateskills/account-takeover/SKILL.md:93abnormal_cases_actionsabnormal_cases_getskills/cases/SKILL.md:113abnormal_get_abuse_reportsabnormal_abuse_listagents/email-threat-analyst.md:20abnormal_get_messageabnormal_messages_getagents/email-threat-analyst.md:18abnormal_get_threatabnormal_cases_getagents/email-threat-analyst.md:18abnormal_list_messagesabnormal_messages_listagents/email-threat-analyst.md:18abnormal_threats_actionsabnormal_threats_getskills/threats/SKILL.md:120abnormal_threats_unremediateabnormal_threats_getskills/threats/SKILL.md:122abnormal_vendors_activityskills/vendors/SKILL.md:93abnormal_vendors_getabnormal_messages_getskills/vendors/SKILL.md:92abnormal_vendors_listabnormal_messages_listskills/vendors/SKILL.md:91abnormal_vendors_threatsabnormal_threats_getskills/vendors/SKILL.md:94connectwise/manage— serverconnectwise-manage-mcp, 51 real tools (source: static+runtime)cw_delete_time_entrycw_create_time_entryGOVERNANCE.md:49cw_update_time_entrycw_create_time_entryGOVERNANCE.md:50domotz/domotz— serverdomotz-mcp, 21 real tools (source: static+runtime+live-gw)domotz_list_devicesdomotz_devices_listGOVERNANCE.md:107domotz_list_agentsdomotz_agents_listcommands/alert-status.md:14domotz_get_agentdomotz_agents_getcommands/device-inventory.md:14domotz_list_alertsdomotz_alerts_profiles_listcommands/alert-status.md:14domotz_scan_networkdomotz_network_interfacesGOVERNANCE.md:108domotz_search_devicesdomotz_devices_getcommands/device-lookup.md:14domotz_get_devicedomotz_devices_getcommands/device-inventory.md:14domotz_list_eyesdomotz_agents_listcommands/site-overview.md:14domotz_get_alertdomotz_agents_getcommands/alert-status.md:14domotz_list_alert_profilesdomotz_alerts_profiles_listskills/alerts/SKILL.md:118domotz_list_eye_resultsskills/api-patterns/SKILL.md:95domotz_list_portsdomotz_agents_listskills/api-patterns/SKILL.md:86domotz_list_snmp_datadomotz_metrics_snmp_sensors_listskills/api-patterns/SKILL.md:85domotz_run_speed_testskills/api-patterns/SKILL.md:87domotz_get_agent_statusdomotz_statusskills/api-patterns/SKILL.md:61domotz_get_device_statusdomotz_statusskills/api-patterns/SKILL.md:70domotz_get_eyedomotz_agents_getskills/api-patterns/SKILL.md:94email-security/knowbe4— serverknowbe4-mcp, 34 real tools (source: static+runtime)knowbe4_training_list_campaignsknowbe4_training_campaigns_listGOVERNANCE.md:28knowbe4_training_list_enrollmentsknowbe4_training_enrollments_listGOVERNANCE.md:28knowbe4_phishing_list_campaignsknowbe4_phishing_campaigns_listGOVERNANCE.md:28knowbe4_training_get_campaignknowbe4_training_campaigns_getGOVERNANCE.md:28knowbe4_groups_list_membersknowbe4_groups_membersGOVERNANCE.md:28knowbe4_phishing_get_campaignknowbe4_phishing_campaigns_getGOVERNANCE.md:28knowbe4_phishing_get_recipientknowbe4_phishing_campaigns_getGOVERNANCE.md:28knowbe4_phishing_get_security_testknowbe4_phishing_security_test_getGOVERNANCE.md:28knowbe4_phishing_list_recipientsknowbe4_phishing_campaigns_listGOVERNANCE.md:28knowbe4_phishing_list_security_testsknowbe4_phishing_security_tests_listGOVERNANCE.md:28knowbe4_training_list_modulesknowbe4_training_campaigns_listGOVERNANCE.md:28knowbe4_training_list_usersknowbe4_users_listagents/security-awareness-analyst.md:20knowbe4_users_list_eventsknowbe4_users_listGOVERNANCE.md:28knowbe4_phishing_get_templateknowbe4_phishing_campaigns_getGOVERNANCE.md:28knowbe4_phishing_list_templatesknowbe4_phishing_campaigns_listGOVERNANCE.md:28knowbe4_reporting_account_summaryknowbe4_reporting_phishing_summaryGOVERNANCE.md:28knowbe4_reporting_department_breakdownGOVERNANCE.md:28knowbe4_reporting_ppp_trendGOVERNANCE.md:28knowbe4_training_get_enrollmentknowbe4_training_enrollments_getGOVERNANCE.md:28knowbe4_training_get_moduleknowbe4_training_campaigns_getGOVERNANCE.md:28knowbe4_training_get_store_purchaseknowbe4_training_enrollments_getGOVERNANCE.md:28knowbe4_training_list_phishing_testsknowbe4_phishing_security_tests_listagents/training-enforcer.md:22knowbe4_training_list_store_purchasesknowbe4_store_purchases_listGOVERNANCE.md:28knowbe4_training_list_training_campaignsknowbe4_training_campaigns_listagents/training-enforcer.md:20knowbe4_phisher_bulk_actionagents/security-awareness-analyst.md:18knowbe4_phisher_get_messageagents/security-awareness-analyst.md:18knowbe4_phisher_list_messagesagents/security-awareness-analyst.md:18email-security/proofpoint— serverproofpoint-mcp, 44 real tools (source: static+runtime)proofpoint_forensics_search_destroyproofpoint_forensics_search_messagesGOVERNANCE.md:31proofpoint_forensics_get_evidenceproofpoint_forensics_get_threatGOVERNANCE.md:29proofpoint_forensics_get_reportproofpoint_forensics_get_threatGOVERNANCE.md:29proofpoint_quarantine_bulk_releaseproofpoint_quarantine_releaseGOVERNANCE.md:31proofpoint_quarantine_previewproofpoint_quarantine_deleteGOVERNANCE.md:29proofpoint_tap_get_all_eventsproofpoint_tap_get_all_threatsGOVERNANCE.md:29proofpoint_threat_get_indicatorsproofpoint_threat_get_iocsGOVERNANCE.md:29proofpoint_url_get_clicksproofpoint_tap_get_clicks_blockedGOVERNANCE.md:29proofpoint_threat_search_campaignsproofpoint_threat_get_campaignGOVERNANCE.md:29proofpoint_url_batch_decodeproofpoint_url_decodeGOVERNANCE.md:29proofpoint_forensics_auto_pull_statusproofpoint_forensics_pull_messagesGOVERNANCE.md:29proofpoint_forensics_get_operationproofpoint_forensics_get_campaignGOVERNANCE.md:29proofpoint_forensics_get_sandbox_reportproofpoint_forensics_get_threatGOVERNANCE.md:29proofpoint_forensics_message_traceGOVERNANCE.md:29proofpoint_get_campaignproofpoint_threat_get_campaignagents/email-security-auditor.md:19proofpoint_get_siem_clicksproofpoint_tap_get_clicks_blockedagents/email-security-auditor.md:19proofpoint_get_siem_messagesproofpoint_tap_get_messages_blockedagents/email-security-auditor.md:19proofpoint_people_get_attack_indexproofpoint_people_get_vapGOVERNANCE.md:29proofpoint_people_list_vipproofpoint_people_get_vapGOVERNANCE.md:29proofpoint_quarantine_bulk_deleteproofpoint_quarantine_deleteGOVERNANCE.md:31proofpoint_threat_get_familyproofpoint_threat_get_campaignGOVERNANCE.md:29proofpoint_threat_get_landscapeproofpoint_threat_get_campaignGOVERNANCE.md:29proofpoint_threat_search_indicatorsGOVERNANCE.md:29proofpoint_url_get_verdictproofpoint_url_decodeGOVERNANCE.md:29proofpoint_forensics_list_operationsGOVERNANCE.md:29proofpoint_get_email_statsproofpoint_events_get_statsagents/email-security-auditor.md:21proofpoint_list_orgsproofpoint_list_categoriesagents/email-security-auditor.md:21proofpoint_people_set_vipproofpoint_people_get_vapGOVERNANCE.md:30proofpoint_quarantine_getproofpoint_quarantine_listGOVERNANCE.md:29proofpoint_tap_get_top_clickersproofpoint_people_get_top_clickersGOVERNANCE.md:29proofpoint_threat_get_actorproofpoint_threat_get_iocsGOVERNANCE.md:29freshdesk/freshdesk— serverfreshdesk-mcp, 66 real tools (source: static+runtime)freshdesk_sla_policies_listfreshdesk_sla_listREADME.md:76freshdesk_tickets_conversationsfreshdesk_tickets_list_conversationsREADME.md:59freshdesk_solutions_articles_searchfreshdesk_solutions_articles_createREADME.md:73huntress/huntress— serverhuntress-mcp, 32 real tools (source: static+runtime+prod-schema)huntress_backskills/api-patterns/SKILL.md:48inforcer/inforcer— serverinforcer-mcp, 19 real tools (source: static+runtime)inforcer_secure_scoresinforcer_secure_scores_getGOVERNANCE.md:51inforcer_audit_events_searchinforcer_audit_searchGOVERNANCE.md:51inforcer_tenant_policies_listinforcer_policies_listGOVERNANCE.md:52ironscales/ironscales— serverironscales-mcp, 9 real tools (source: static+runtime)ironscales_classify_emailironscales_email_classifyagents/phishing-responder.md:19ironscales_get_company_statsironscales_stats_companyagents/crowdsourced-intel-harvester.md:21ironscales_get_incidentironscales_incidents_getagents/phishing-responder.md:19ironscales_list_incidentsironscales_incidents_listagents/phishing-responder.md:36ironscales_remediate_incidentagents/phishing-responder.md:19ironscales_manage_allowlistironscales_allowlist_manageagents/phishing-responder.md:21kaseya/it-glue— serveritglue-mcp, 24 real tools (source: static+prod-schema+live-gw)itglue_create_documentcreate_documentGOVERNANCE.md:81mimecast/mimecast— servermimecast-mcp, 10 real tools (source: static)mimecast_get_queuemimecast_get_queue_statusGOVERNANCE.md:113quickbooks/quickbooks-online— serverqbo-mcp, 133 real tools (source: static+runtime)qbo_invoices_updateqbo_invoices_createGOVERNANCE.md:130saas-alerts/saas-alerts— serversaas-alerts-mcp, 30 real tools (source: static+runtime)saas_alerts_users_getsaas_alerts_users_get_mspREADME.md:54saas_alerts_devices_getsaas_alerts_customers_getREADME.md:57saas_alerts_billing_getsaas_alerts_billing_get_detailsREADME.md:60saas_alerts_billing_listsaas_alerts_billing_list_datesREADME.md:60saas_alerts_devices_listsaas_alerts_devices_list_orgsREADME.md:57saas_alerts_users_listsaas_alerts_users_list_partnerREADME.md:54sherweb/sherweb— serversherweb-mcp, 15 real tools (source: static+runtime)sherweb_billing_get_billing_periodscommands/billing-summary.md:14sherweb_billing_get_payable_chargessherweb_billing_payable_chargescommands/billing-summary.md:14sherweb_customers_get_accounts_receivablesherweb_customers_accounts_receivablecommands/list-customers.md:14sherweb_billing_get_invoicesskills/api-patterns/SKILL.md:177sherweb_billing_get_invoice_detailssherweb_billing_charge_detailsskills/api-patterns/SKILL.md:178sherweb_billing_get_charge_detailssherweb_billing_charge_detailsskills/api-patterns/SKILL.md:176spamtitan/spamtitan— serverspamtitan-mcp, 9 real tools (source: static+runtime)spamtitan_list_allowlistspamtitan_manage_allowlistGOVERNANCE.md:126spamtitan_list_blocklistspamtitan_manage_blocklistGOVERNANCE.md:126spamtitan_get_domain_statsspamtitan_get_statsGOVERNANCE.md:127threatlocker/threatlocker— serverthreatlocker-mcp, 17 real tools (source: static+prod-schema)threatlocker_computer_groups_getthreatlocker_computer_groups_listREADME.md:60threatlocker_organizations_getthreatlocker_organizations_get_auth_keyREADME.md:73timezest/timezest— servertimezest-mcp, 14 real tools (source: static+live-gw)timezest_resources_gettimezest_resources_listskills/resources/SKILL.md:62Recommended fix order
Ordered by agent-breakage, not by count.
rootly— 4 skills (postmortems,services,alerts,workflows) document a server that does not exist. Delete or rewrite; do not rename. Then fixapi-patterns(24 of 31 names fabricated, "25 tools" → 253) andincidents. Leaveoncallalone. Addmcp__*entries to both agents' frontmatter.email-security/proofpointthenemail-security/knowbe4— highest absolute breakage (105 and 72 uses), and their GOVERNANCE allowlists must be regenerated fromtools/list, not patched by hand. Proofpoint first: its Destructive row is wrong in both directions.abnormal/abnormal-security— 21 of 31 documented names wrong against a 10-tool server. Whole skills (vendors,account-takeover) describe capability the server does not have.domotz/domotz— 100% of skill and command names wrong, 66 uses. Governance is already correct, so this is a mechanical skills-and-commands rename.ironscales/ironscales— 51 uses against a 9-tool server; every name inagents/phishing-responder.mdis wrong.sherweb,saas-alerts,spamtitan,inforcer,mimecast— contained renames, 12–35 uses each.freshdesk,threatlocker,timezest,huntress— reference-table and README fixes; primary paths work.connectwise/manage,kaseya/it-glue,quickbooks— one-line GOVERNANCE.md corrections.email-security/checkpoint-avanan— not drift, but the largest governance gap: 13 tools, 4 write-capable, 1 irreversible, zero documented.pax8— docs unblocked only after someone generates anx-pax8-mcp-tokenand captures the realtools/list. Separately, file therelease.ymldeploy-job hazard againstpax8-mcp.Confirming / refuting the prior reports
Reported drifted (14): confirmed for
inforcer,saas-alerts,threatlocker,abnormal,ironscales,mimecast,spamtitan,domotz,freshdesk,sherweb,rootly— 11.rootlyconfirmed but inverted, see above.betterstackandpagerdutycould not be verified (hosted, no credentials).pax8is structural rather than name-drift, and its hosted surface is unverified.Newly found, not previously reported (7):
email-security/proofpoint,email-security/knowbe4,huntress,timezest,connectwise/manage,kaseya/it-glue,quickbooks/quickbooks-online.Reported clean (15): confirmed for
kaseya/autotask(98 tools, 98 names, 0 drift),datto-bcdr,datto-rmm,datto-saas-protection,kaseya-bms,kaseya-vsa,rocketcyber,spanning,unitrends,connectwise-cpq,auvik,meraki,cipp,blumira— 14 of 15. Refuted:kaseya/it-glue—GOVERNANCE.md:81saysitglue_create_document; the server registerscreate_document(unprefixed). One name, but it is a false clean.Also verified clean beyond the reported list:
alternative-payments,atera,connectwise/automate,crewhu,halopsa,hudu,kaseya-quote-manager,liongard,microsoft-graph,ncentral,ninjaone-rmm,salesbuildr,scalepad,sentinelone,superops-ai,syncro-msp,xero.Unverified — explicitly NOT called clean
Twelve plugins where ground truth could not be established. All are hosted upstreams or vendors with no local server repo. None should be treated as clean.
pax8/pax8https://mcp.pax8.com/v1Missing x-pax8-mcp-token; no token incortex-secretpagerduty/pagerdutyhttps://mcp.pagerduty.compagerduty_*namesbetterstack/betterstackhttps://mcp.betterstack.comPOST /mcp— worth a separate look, since the gateway'svalidate()uses that exact path; documents 5betterstack_*nameshubspot/hubspothttps://mcp.hubspot.com/anthropic/v1/mcpslack/slackhttps://mcp.slack.comstripe/stripehttps://mcp.stripe.compandadoc/pandadochttps://mcp.pandadoc.com/v1/mcpwarmly/warmlyhttps://opps-api.getwarmly.com/api/mcprunzero/runzerohttps://console.runzero.com/mcprunzero_*namesblackpoint/blackpointhttp://blackpoint-mcpimmybot/immybothttp://immybot-mcpclio/cliovendor-config.tsat all; documents 26clio_*namesblackpoint,immybotandclioare the cheapest to resolve (check out the repo / add the vendor entry), andimmybotdocuments 68 tool names with nothing currently verifying them.Also flagged, not drift:
mimecast,spamtitan,ironscales,sherweb,scalepadandconnectwise-cpqship plugins but have no entry inmcp-gateway/vendor-config.ts, so gateway users cannot reach them at all regardless of tool names.Method
<vendor>-mcp/dist/index.jsover stdio,initialize→tools/list. 50 of 61 repos answered. Authoritative but incomplete for progressive-disclosure servers: 12 gate their surface behind a*_navigatecall and advertise only 1–2 entrypoints at init (pax8-mcpreturns exactlypax8_navigate).src/**for MCPToolobject literals (name: "…"with an adjacentinputSchema) andserver.registerTool(…)calls. Recovers the post-navigation surface.prompts.tsis excluded — MCP prompt argument definitions have the identical{ name: '…' }shape and produced false tools (client_name,incident_id,customer_id) on the first pass.mcp-gateway/schemas/<vendor>.json, pinned to the prod image digests in.harness/vendors.json. 12 vendors.mcp.wyre.aiconnector during the audit. This is what resolvedsentinelone(22 tools, no vendor prefix —list_alerts,powerquery,purple_ai), which both other sources missed.staticMissed(runtime tools the static scan did not find).qbo-mcpandscalepad-mcpregister from generated registries the static scan cannot see — for those two, runtime is authoritative and static alone would badly under-report.snake_casetokens from each plugin'sskills/**/SKILL.md,references/*.md,agents/*.md,commands/*.md, and root-levelREADME.md/GOVERNANCE.md, filtered to tokens whose first segment matches a prefix the server actually uses.vendor-config.tscontainerUrldecides the real upstream. Where that is a vendor host, the local repo is ignored entirely; that is how the rootly and pax8 determinations were reached.Verified vs inferred. Everything in the summary table and per-vendor detail is verified against server source or a live
tools/list. Rootly's 253-tool surface was verified with a real token and confirmed per-name bytools/calldispatch. Pax8's hosted surface is inferred only — the "15 read-only tools" claim has no vendor-authored source. Everything in the Unverified section is explicitly not established.Known limits of the script. It only sees names written in backticks; prose mentions are missed. The nearest-name suggestion is a heuristic. It cannot reach OAuth-gated hosted upstreams. Servers with no
dist/and no recognizable registration pattern fall through (3cx-mcp,float-mcp,nable-mcp,pco-mcp,autotask-projects-mcp).The script
Two files.
probe-tools.mjsbuilds the runtime source;tool-drift-audit.mjsdoes the diff and exits 1 on drift, so it can gate CI. A separate PR proposes adding it toscripts/alongsidecheck-marketplace-drift.mjs.scripts/tool-drift-audit.mjsprobe-tools.mjs(runtime source)