# MCP Server Governance & Change Monitor (`automa-flow/mcp-server-governance-monitor`) Actor

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

- **URL**: https://apify.com/automa-flow/mcp-server-governance-monitor.md
- **Developed by:** [Vadim Bezrukov](https://apify.com/automa-flow) (community)
- **Categories:** Developer tools, Agents, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.20 / 1,000 mcp server observeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## MCP Server Governance & Change Monitor

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.

```json
{
  "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:

| Event | Evidence |
| --- | --- |
| `NEW_VERSION` | latest version string changed and the new record was published later |
| `VERSION_CHANGED` | latest version string changed without a later publication (rollback, removed newer version) |
| `PACKAGE_ADDED`, `PACKAGE_REMOVED`, `PACKAGE_IDENTIFIER_CHANGED` | package set keyed by registry type and identifier changed |
| `PACKAGE_VERSION_CHANGED`, `PACKAGE_CHECKSUM_CHANGED` | same package, different version or `fileSha256` |
| `REMOTE_ADDED`, `REMOTE_REMOVED`, `REMOTE_URL_CHANGED` | remote endpoint set changed (one URL replaced by one URL of the same transport is a URL change) |
| `TRANSPORT_CHANGED` | the set of transports (`stdio`, `streamable-http`, `sse`) across packages and remotes changed |
| `AUTH_REQUIREMENT_CHANGED` | a 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_CHANGED` | the corresponding field changed |
| `STATUS_CHANGED` plus `SERVER_DEPRECATED`, `SERVER_DELETED`, `SERVER_REAPPEARED` | official lifecycle status moved; `statusMessage` is included |
| `STATUS_MESSAGE_CHANGED` | same status, new official message |
| `SERVER_NOT_FOUND`, `NEW_SERVER`, `SERVER_REAPPEARED` | the Registry stopped or started answering an exact name |
| `METADATA_CHANGED` | the 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`:

```json
{
  "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

| Field | Type | Default | Notes |
| --- | --- | --- | --- |
| `mode` | `watchlist` or `registryChanges` | `watchlist` | |
| `monitorKey` | string, 1-80 `[A-Za-z0-9_-]` | `default` | independent state namespace |
| `servers` | array of exact Registry names, 1-500 | | required in watchlist mode; ignored in registryChanges mode and counted as `watchlistIgnored` |
| `changesOnly` | boolean | `true` | drop `UNCHANGED` rows |
| `baselineMode` | `emitSnapshot` or `storeOnly` | `emitSnapshot` | whether first observations are written |
| `includeDeleted` | boolean | `true` | ask the Registry to include `deleted` servers |
| `maxResults` | 1-5000 | `1000` | registryChanges: unique servers per run |
| `lookbackDays` | 1-30 | `1` | registryChanges: 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:

```json
{
  "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`](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:

```text
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:

```bash
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 plan | Per successful server check | 100 servers per run | 100 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](https://github.com/modelcontextprotocol/registry/blob/main/docs/modelcontextprotocol-io/terms-of-service.mdx)
  (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.

# Actor input Schema

## `mode` (type: `string`):

Watchlist looks up each exact server name (one Registry request per server). Registry changes pages through servers the official Registry marks as updated since the previous successful checkpoint of this monitorKey, latest version only.

## `monitorKey` (type: `string`):

Independent state namespace. Use a stable name per watch, for example production-approved. Letters, numbers, '\_' and '-', 1-80 characters.

## `servers` (type: `array`):

Exact official Registry names such as io.github.github/github-mcp-server, 1-500, required in watchlist mode. No fuzzy matching: a name the Registry does not know is NOT\_FOUND. Duplicates keep the first entry. Ignored in registryChanges mode (reported as watchlistIgnored in the run summary).

## `changesOnly` (type: `boolean`):

Omit UNCHANGED observations from the Dataset; successful unchanged checks are still billed. BASELINE rows follow the First observation setting. NOT\_FOUND, FAILED and typed changes are delivered.

## `baselineMode` (type: `string`):

Emit snapshot writes a BASELINE row the first time a server is seen in this monitorKey. Store only records the baseline silently and starts emitting from the second run.

## `includeDeleted` (type: `boolean`):

Ask the Registry to include servers with official status deleted, so a deletion is reported as SERVER\_DELETED with the Registry's own status. When off, a deleted server is invisible to the lookup and reported as NOT\_FOUND.

## `maxResults` (type: `integer`):

Upper bound on unique server observations in one registryChanges run (1-5000). Larger windows return PARTIAL and save a continuation position. Run again with the same monitorKey to continue; the checkpoint advances after the complete window is verified.

## `lookbackDays` (type: `integer`):

registryChanges only: how far back the very first run of a monitorKey looks (1-30). Later runs continue from the last successful checkpoint. One day held about 600 updated servers on 2026-09-13; seven days about 5,900.

## Actor input object example

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

# Actor output Schema

## `results` (type: `string`):

No description

## `runSummary` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "mode": "watchlist",
    "monitorKey": "production-approved",
    "servers": [
        "io.github.github/github-mcp-server",
        "io.github.microsoft/playwright-mcp",
        "com.stripe/mcp",
        "com.apify/apify-mcp-server"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("automa-flow/mcp-server-governance-monitor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "mode": "watchlist",
    "monitorKey": "production-approved",
    "servers": [
        "io.github.github/github-mcp-server",
        "io.github.microsoft/playwright-mcp",
        "com.stripe/mcp",
        "com.apify/apify-mcp-server",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("automa-flow/mcp-server-governance-monitor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "mode": "watchlist",
  "monitorKey": "production-approved",
  "servers": [
    "io.github.github/github-mcp-server",
    "io.github.microsoft/playwright-mcp",
    "com.stripe/mcp",
    "com.apify/apify-mcp-server"
  ]
}' |
apify call automa-flow/mcp-server-governance-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automa-flow/mcp-server-governance-monitor"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/zYbACer8JgOfLUhBN/builds/dKGRzRJjWA37QNLST/openapi.json
