MCP Server Governance & Change Monitor avatar

MCP Server Governance & Change Monitor

Pricing

from $1.20 / 1,000 mcp server observeds

Go to Apify Store
MCP Server Governance & Change Monitor

MCP Server Governance & Change Monitor

Monitor approved MCP servers in the official MCP Registry. Detect version, package, endpoint, transport, auth and lifecycle changes.

Pricing

from $1.20 / 1,000 mcp server observeds

Rating

0.0

(0)

Developer

Vadim Bezrukov

Vadim Bezrukov

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Share

Know when an MCP server you have approved, or are evaluating, materially changes in the official MCP Registry, before your agents, IDE policies or internal marketplace keep trusting it.

Give the Actor the exact Registry names on your allowlist. Every run looks each one up in the official Registry API, compares it with the last successful observation of the same monitorKey, and writes one row per server with typed events: NEW_VERSION, PACKAGE_VERSION_CHANGED, REMOTE_URL_CHANGED, AUTH_REQUIREMENT_CHANGED, SERVER_DEPRECATED, SERVER_DELETED and more, each with the previous and current values. Nothing changed? You get a run summary and no noise. A lookup failed? The previous state is kept and the row says FAILED, so an outage never looks like a deletion.

A second mode follows the whole Registry: every server the Registry marks as updated since your last successful run, latest version only, with the same typed comparison. That turns the Registry into an incremental change feed for ecosystem tracking, internal registries and subregistries.

This data comes from the Official MCP Registry (registry.modelcontextprotocol.io). The Actor reads only published Registry metadata over the public API. It never connects to an MCP server, never runs a tool, never downloads a package and never claims a server is safe.

MCP: https://mcp.apify.com?tools=automa-flow/mcp-server-governance-monitor

Try your first allowlist check

Keep the four prefilled Registry names and click Start. A fresh monitorKey returns four BASELINE observations plus a run summary when all names resolve. With the current Free/Bronze event rate, this costs $0.020 at 256 MB. Set the maximum charge to $0.05; this is a ceiling, not an upfront charge. Replace the examples with your own approved names, then save a Task. Run the same Task again with the same monitorKey: unchanged servers are still checked and billed. If nothing changed, only the summary is written with changesOnly on. Use Servers for inventory exports and Changes for reviewing differences.

What does MCP Server Governance & Change Monitor do?

  1. Validates your input before any request: exact Registry names only, 1-500, duplicates collapsed, no fuzzy matching.
  2. Fetches the latest version of each server from the official Registry API (GET /v0.1/servers/{name}/versions/latest?include_deleted=true), or pages through GET /v0.1/servers?updated_since=...&version=latest in registryChanges mode.
  3. Normalizes each record into a deterministic snapshot (packages, remotes, transports, declared auth headers, repository, website, lifecycle status) and fingerprints it, so reordered arrays never produce a false change.
  4. Compares with the last successful snapshot stored under your monitorKey in an Apify Key-Value Store and emits typed change events with previous and current values.
  5. Saves state only for servers that were successfully observed, and advances the registryChanges checkpoint only after a complete window.

Monitor approved MCP servers

Typical setup: one Task per allowlist, scheduled daily or hourly, with changesOnly on.

{
"mode": "watchlist",
"monitorKey": "production-approved",
"servers": [
"io.github.github/github-mcp-server",
"io.github.microsoft/playwright-mcp",
"com.stripe/mcp"
],
"changesOnly": true,
"baselineMode": "emitSnapshot",
"includeDeleted": true
}

The first run writes a BASELINE row per server (the full normalized snapshot) so the run is useful immediately. From the second run on, only servers with a typed change, NOT_FOUND names and FAILED lookups are written; the run summary always reports how many servers were observed and unchanged.

What changes can it detect?

Every event is backed by a before/after difference in Registry metadata:

EventEvidence
NEW_VERSIONlatest version string changed and the new record was published later
VERSION_CHANGEDlatest version string changed without a later publication (rollback, removed newer version)
PACKAGE_ADDED, PACKAGE_REMOVED, PACKAGE_IDENTIFIER_CHANGEDpackage set keyed by registry type and identifier changed
PACKAGE_VERSION_CHANGED, PACKAGE_CHECKSUM_CHANGEDsame package, different version or fileSha256
REMOTE_ADDED, REMOTE_REMOVED, REMOTE_URL_CHANGEDremote endpoint set changed (one URL replaced by one URL of the same transport is a URL change)
TRANSPORT_CHANGEDthe set of transports (stdio, streamable-http, sse) across packages and remotes changed
AUTH_REQUIREMENT_CHANGEDa remote's secret/required header names or a package's secret/required environment variables and secret argument variables changed
REPOSITORY_CHANGED, WEBSITE_CHANGED, TITLE_CHANGED, DESCRIPTION_CHANGEDthe corresponding field changed
STATUS_CHANGED plus SERVER_DEPRECATED, SERVER_DELETED, SERVER_REAPPEAREDofficial lifecycle status moved; statusMessage is included
STATUS_MESSAGE_CHANGEDsame status, new official message
SERVER_NOT_FOUND, NEW_SERVER, SERVER_REAPPEAREDthe Registry stopped or started answering an exact name
METADATA_CHANGEDthe fingerprint moved but no typed rule matched; changed_fields says where

UNCHANGED and BASELINE are the two non-change outcomes.

MCP allowlist governance

Feed the changes Dataset view into the review step that already exists in your organization: a webhook to a ticketing queue, a Slack notification, a policy pipeline that re-pins package versions, or a manual approval board. event_id is deterministic per observation, so a replayed webhook can be deduplicated downstream. server.packages[] and server.remotes[] carry the exact identifiers, versions and endpoints to re-approve.

The Actor does not decide whether a change is acceptable. It reports what the official Registry says, with provenance (source_url, Registry timestamps), and leaves the policy to you.

Monitor new, deprecated and deleted MCP servers

registryChanges mode asks the Registry for servers updated since the previous successful checkpoint of your monitorKey:

{
"mode": "registryChanges",
"monitorKey": "ecosystem",
"includeDeleted": true,
"maxResults": 1000,
"lookbackDays": 1
}

The first run covers lookbackDays (default 1; about 600 updated servers on 2026-09-13, seven days held about 5,900). Later runs continue from the saved checkpoint with a five minute overlap; records re-delivered inside the overlap are recognized and neither emitted nor charged. Servers seen before in the same monitorKey get typed diffs; servers seen for the first time get BASELINE rows with their official status, published_at and status_changed_at.

If a window exceeds maxResults or the page budget, the run returns PARTIAL and saves its pagination position. Start another run with the same monitorKey to continue, including windows larger than 5,000 servers. Already delivered observations are not billed again when a partially consumed page is revisited. The checkpoint advances only when the scan completes, to the original scan's start minus the overlap. A following scan therefore also catches changes made behind the cursor while the preceding scan was in progress. Keep the same includeDeleted setting while continuing; changing it restarts pagination from the unchanged checkpoint so newly included records are not skipped.

The Registry lists deleted servers in this feed automatically. With includeDeleted off they are dropped before observation. The docs say a deleted status "typically indicates" a moderation-policy violation; the Actor reports the official status and message only.

Input

FieldTypeDefaultNotes
modewatchlist or registryChangeswatchlist
monitorKeystring, 1-80 [A-Za-z0-9_-]defaultindependent state namespace
serversarray of exact Registry names, 1-500required in watchlist mode; ignored in registryChanges mode and counted as watchlistIgnored
changesOnlybooleantruedrop UNCHANGED rows
baselineModeemitSnapshot or storeOnlyemitSnapshotwhether first observations are written
includeDeletedbooleantrueask the Registry to include deleted servers
maxResults1-50001000registryChanges: unique servers per run
lookbackDays1-301registryChanges: first-run window only

Output

One server_observation row per delivered server and one run_summary row. Dataset views: Changes, Servers, Run summary. Views select columns; they do not filter row types. Filter record_type == "server_observation" in your integration before sending change alerts. Read RUN_SUMMARY from the Key-Value Store when you need just the summary. A shortened example:

{
"record_type": "server_observation",
"source": "official-mcp-registry",
"source_id": "mcp-registry:io.github.github/github-mcp-server",
"source_url": "https://registry.modelcontextprotocol.io/v0.1/servers/io.github.github%2Fgithub-mcp-server/versions/latest?include_deleted=true",
"scraped_at": "2026-09-13T12:00:00+00:00",
"schema_version": 1,
"fingerprint": "9494f068d7df2c9dbab661f9990f1cbcdf2c33f0a15b4de8b413a1e3eafa9cae",
"monitor_key": "production-approved",
"mode": "watchlist",
"server_name": "io.github.github/github-mcp-server",
"status": "SUCCESS",
"registry_status": "active",
"version": "1.12.1",
"previous_version": "1.12.0",
"change_types": ["NEW_VERSION", "PACKAGE_VERSION_CHANGED"],
"changed_fields": ["version", "packages"],
"changes": {
"version": {"previous": "1.12.0", "current": "1.12.1"},
"packages": {"previous": [{"registry_type": "oci", "identifier": "ghcr.io/github/github-mcp-server", "version": "1.12.0", "transport_type": "stdio"}], "current": [{"registry_type": "oci", "identifier": "ghcr.io/github/github-mcp-server", "version": "1.12.1", "transport_type": "stdio"}]}
},
"server": {
"title": "GitHub",
"repository_url": "https://github.com/github/github-mcp-server",
"remotes": [{"transport_type": "streamable-http", "url": "https://api.githubcopilot.com/mcp/", "header_names": ["Authorization"], "secret_header_names": ["Authorization"], "required_header_names": []}],
"transport_types": ["stdio", "streamable-http"],
"auth_header_names": ["Authorization"],
"published_at": "2026-09-08T19:04:11.03351Z"
},
"error": null,
"event_id": "..."
}

The full example, produced from sanitized fixtures, is in examples/sample_output.json. Header values and argument values are never stored; only header names and their secret/required flags.

The RUN_SUMMARY record in the run's Key-Value Store carries serversObserved, serversNotFound, sourceFailures, changeRecords, newVersions, deprecatedServers, deletedServers, checkpointPrevious, checkpointCurrent, sourceRequests, sourceRetries, bytesDownloaded, eligibleServerObservationCount, chargedServerObservationCount, outputLimitReached, spendLimitReached and durationMs.

Scheduling and webhooks

Create a Task with your allowlist, then a Schedule such as 0 6 * * * (daily) or 15 * * * * (hourly; the Registry asks aggregators for "regular but infrequent" access). Add a webhook on ACTOR.RUN.SUCCEEDED and ACTOR.RUN.FAILED pointing at your queue; read the Dataset with the changes view:

https://api.apify.com/v2/datasets/{{resource.defaultDatasetId}}/items?view=changes

Read the summary's status and failure.code as well as the platform run status. PARTIAL can mean a failed target or a window bounded by maxResults or the page budget; successful observations are retained and an incomplete window can be continued. FAILED can also report invalid state, a spend limit or uncertain delivery, not just an unreachable source. Consult the error before retrying.

API and MCP usage

Run it from the Apify API:

curl -X POST "https://api.apify.com/v2/acts/automa-flow~mcp-server-governance-monitor/runs?maxTotalChargeUsd=0.05" \
-H "Authorization: Bearer $APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"mode":"watchlist","monitorKey":"production-approved","servers":["io.github.github/github-mcp-server"]}'

Or from an agent through Apify MCP: https://mcp.apify.com?tools=automa-flow/mcp-server-governance-monitor. The input is bounded (at most 500 names or maxResults servers), the output is typed, and the public Registry needs no login, browser or proxy. Running through Apify API or MCP requires Apify authentication (OAuth or an API token). The worst-case bill is servers x server-observed plus the Actor start. Set maxTotalChargeUsd on the run; when it cannot cover the requested servers the Actor refuses before any source traffic and reports SPEND_LIMIT. In registryChanges mode the count is only known after the window was read, so size the limit for maxResults servers; an unaffordable window is reported as SPEND_LIMIT with no server observations delivered, charged or saved. The fixed Actor start fee still applies.

Pricing

Pay per event. The Actor's Pricing tab is authoritative; the numbers here describe the model:

  • server-observed: charged once per unique MCP server successfully evaluated against the current Registry state in a run, changed or not. Several changes on one server are one event.
  • Never charged: NOT_FOUND names, FAILED lookups, retries, pagination, duplicated input, state writes, the run summary, and records re-delivered inside the checkpoint overlap.
  • apify-actor-start: $0.012 once per run, including quiet, invalid-input or failed runs. This fixed fee covers run startup and reporting; it is separate from successful server checks. Source failures never create server-observed events.

A daily check of a 100-server allowlist is 100 events per run; a quiet registryChanges window is the start event only.

Current rates (USD; checked 2026-09-13):

Apify planPer successful server check100 servers per run100 servers daily, 30 runs
Free / Bronze$0.002$0.212$6.36
Silver$0.0016$0.172$5.16
Gold / Platinum / Diamond$0.0012$0.132$3.96

These examples include one $0.012 platform start event at the fixed 256 MB memory allocation. An inventory Task with three found servers costs $0.018 at the Free/Bronze rate. A Registry feed with 1,000 observed servers costs $2.012; use a $2.50 run ceiling for that Task. A quiet feed costs $0.012. This Actor requires a maximum-charge setting of at least $0.02, even for cheaper runs. Prices can change; check the Pricing tab before scheduling. Only published Registry metadata is checked: this fee does not buy a live endpoint or security test.

Failure semantics

  • Requests, redirects and retry waits share a 45-second source time budget. After it expires, unverified watchlist targets are FAILED with SOURCE_TIME_BUDGET; successful observations remain usable. An incomplete Registry scan retains its boundary and can continue next run.
  • Runs use 256 MB; prepared Tasks have a 120-second platform timeout.
  • Incorrect PPE event configuration fails before source requests or Dataset writes with PRICING_CONFIGURATION; diagnostic details remain in RUN_SUMMARY.
  • NOT_FOUND is the Registry's own 404 problem body with detail Server not found for an exact name. Any other 404 (for example an unknown API route) is FAILED, never a missing server. It is an authoritative answer, is stored, and later becomes NEW_SERVER or SERVER_REAPPEARED if the name starts resolving.
  • FAILED covers timeouts, network errors, HTTP 429/5xx after three attempts, HTML or malformed JSON bodies and a response that names a different server. The previous state of that server is untouched and no deletion is inferred.
  • SERVER_DELETED is emitted only when the Registry reports status: deleted for a server that was previously observed with another status.
  • In registryChanges mode the checkpoint advances only after every page of the window was read and its observations were verified. When maxResults bounds a run, it is PARTIAL, observed servers and the continuation position are saved together, and the checkpoint stays until the window is completed.
  • A run interrupted after output started is never replayed on restart (DELIVERY_UNCERTAIN); start a new run for a fresh observation.
  • Incompatible stored state (a different schema version) fails the run and is never silently reset.
  • Server snapshots carry snapshot_version. Existing unversioned snapshots are recognized as the older formats. The first comparison after an upgrade uses only fields the old format actually observed; newly supported fields are established without claiming a source change. Subsequent observations compare the complete current format. Unknown future formats fail explicitly.
  • Entries the Actor cannot read on a registryChanges page make the run PARTIAL (or FAILED when no observation was verified) and keep the checkpoint. Pages containing unreadable entries are retried; successful observations are retained. This includes normalization failures inside an otherwise valid page.
  • checkpointCurrent reports the durable boundary. If a charge limit prevents saving the state, it remains the previous checkpoint, and the saved continuation position is also unchanged.
  • Do not run two instances with the same monitorKey at the same time; state is last-writer-wins. Use one Schedule per key.
  • A registryChanges first run that could not complete its window (failure, maxResults) anchors the window start as the checkpoint, so the next run resumes from the same boundary and nothing between is lost.
  • State per monitorKey is one Key-Value Store record. Only when it would exceed 6 MB (roughly 5,500 servers) are the least-recently-observed servers outside the current input pruned; the run summary lists the count and those servers reappear as BASELINE on their next observation.

Data source and limitations

  • Source: the Official MCP Registry read API only, version=latest, no authentication, no proxy, no browser. Aggregators are explicitly supported by the Registry; requests are sequential per page and at most four in parallel for watchlists.
  • Registry Data is intended to be public and dedicated under CC0 1.0 per the Registry Terms of Service (checked 2026-09-13). That dedication does not cover the packages the metadata points to; the Actor redistributes identifiers, not package content.
  • The Registry is in preview and states it provides no uptime or durability guarantees and that data resets may occur. A reset would surface as SERVER_NOT_FOUND rows, never as SERVER_DELETED.
  • Only the latest version of each server is compared. A status change on an older version is not observed.
  • registryChanges mode does not detect brand-new servers as such: without a prior observation a record is a BASELINE, with its published_at.
  • Authentication is reported as declared header names only. The Registry has no field that proves whether an endpoint enforces authentication.
  • Deletion means the official status deleted. It is not a malware finding.
  • No GitHub, npm, OSV, vulnerability, trust-score or tool-execution enrichment.

FAQ

Which names do I use? The exact name shown in the Registry (namespace/name, for example io.github.github/github-mcp-server). The Registry's search is a substring match and is not used for identity.

Why did my first run write BASELINE rows with changesOnly on? The first observation is what later runs compare against; it is written so the run is useful on day one. Use baselineMode: storeOnly to record it silently.

Can two watchlists share state? Only if they share a monitorKey. Use one key per allowlist so a server removed from one list does not affect another.

What happens if the Registry is down? Every target is FAILED, the run is FAILED, nothing is charged for those targets and the previous state is kept.

Does it tell me whether a server is safe? No. It tells you what changed in the official metadata so your own review can run.