# Tool Listing Auditor: Apify Actor & MCP Server SEO Audit (`ventura_workalong/tool-listing-auditor`) Actor

Audit an Apify Actor or MCP server listing for agent and Store search: metadata lint, simulated search rank for 10 task phrasings (BM25 + local embeddings), concrete rewrite suggestions, and a live MCP health check (initialize, tools/list, auth type). $0.50 per audit.

- **URL**: https://apify.com/ventura_workalong/tool-listing-auditor.md
- **Developed by:** [Ventura WorkAlong](https://apify.com/ventura_workalong) (community)
- **Categories:** Developer tools, SEO tools, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $500.00 / 1,000 listing audits

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Tool Listing Auditor: Apify Actor & MCP Server SEO Audit

Tool Listing Auditor checks how findable your **Apify Actor** or **MCP server** is, for people searching the Apify Store and for AI agents choosing tools. Give it an Actor (`username/actor-name`), an official MCP Registry name or a remote MCP URL. It returns:

- **Metadata lint:** title, description, SEO fields, categories, input-schema descriptions/prefills/secrets, dataset and output schemas, README sections, and pricing clarity. For MCP servers it lints the registry entry and every tool from `tools/list`: names, descriptions, `inputSchema` quality, annotations and context size.
- **Simulated search rank:** for 10 task phrasings generated from your listing (plus your own), where your tool ranks among its real competitors. The ranker combines BM25 with a small local embedding model.
- **Concrete rewrite suggestions:** deterministic templates, built from your own listing's words.
- **Live MCP health check:** `initialize` and `tools/list` latency, protocol version, transport and auth type. No credentials are ever sent.

$0.50 per audit. Targets that can't be audited are free.

### What does Tool Listing Auditor do?

Agents and Store users find tools by searching. Apify's Store search leans on the title and description. MCP clients and registries match task phrasings against tool and server descriptions. This Actor measures that:

1. **Builds a reference corpus.** For an Actor, it takes the most popular Store Actors in each of its categories, plus the real Store search results for each phrasing (usually 600–1,300 listings). For an MCP server, it takes every active server in the official MCP Registry (40,000+).
2. **Generates task phrasings** from your listing: half in your own words, half paraphrased with synonyms, because searchers rarely use your exact wording. You can add your own phrasings.
3. **Ranks your listing** for each phrasing with BM25 (title boosted) and the local embedding model [potion-base-8M](https://huggingface.co/minishlab/potion-base-8M), fused with reciprocal rank fusion. It reports the rank, the listings that beat you, and for Actors your **real Apify Store search position**.
4. **Lints the metadata** and turns every finding into a concrete suggestion.

### How to use Tool Listing Auditor

1. Enter one or more targets: `username/actor-name`, `https://apify.com/username/actor-name`, an MCP Registry name like `io.github.owner/server`, or a remote MCP URL like `https://example.com/mcp`.
2. Optional: add the searches you expect your users to make under **Your own task phrasings**. They are applied to every target, so audit unrelated tools in separate runs.
3. Click **Start**. An audit takes about 10–40 seconds per target.
4. Read the **Audits** table, open the **Readable report (Markdown)**, or download JSON, CSV or Excel. You can also call it from the Apify API or MCP.

### Input example

```json
{
  "targets": ["ventura_workalong/sitemap-url-extractor", "app.workalong/data-tools"],
  "taskQueries": ["extract all urls from a sitemap"],
  "numGeneratedQueries": 10,
  "checkStoreSearch": true,
  "healthCheck": true
}
```

### Output example

One item per target (trimmed; real run on our own MCP Registry entry):

```json
{
  "type": "audit",
  "target": "app.workalong/data-tools",
  "targetType": "mcp-registry",
  "title": "WorkAlong Data Tools (via Apify)",
  "score": 96,
  "grade": "A",
  "healthScore": 100,
  "healthGrade": "A",
  "health": {
    "transport": "streamable-http",
    "initializeMs": 321,
    "auth": { "type": "oauth", "discovery": "protected-resource-metadata", "httpStatus": 401 }
  },
  "retrieval": {
    "queries": 14, "medianRank": 118.0, "top10": 3, "corpusSize": 40102, "model": "minishlab/potion-base-8M",
    "results": [
      { "query": "convert pdf to markdown", "source": "user", "rank": 419, "bm25Rank": 1029, "embeddingRank": 295,
        "outrankedBy": [{ "title": "pdf to markdown", "registryName": "..." }] }
    ]
  },
  "suggestions": [
    { "field": "server.json description", "priority": "medium",
      "why": "The description lists 9 different jobs in 100 characters and the median simulated rank is 127 ...",
      "suggested": "Lead with the one job most users search for and its key nouns, or publish focused entries ..." }
  ]
}
```

After we applied that suggestion, "convert pdf to markdown" moved from rank 419 to 81 and the median rank from 118 to 61.5 (same phrasings, same corpus).

Each item also has `issues` (id, severity, area, message), `keyphrases`, `scores` per area, `phraseDemand` (how many demand-weighted competitor titles carry each of your phrases), `onlyIfAccurate` (search terms your listing never mentions) and, for MCP, a per-tool summary.

### How is the score calculated?

- **Listing score (0–100):** each area starts at 100 and loses 25 / 10 / 4 points per high / medium / low issue.
  - Actor areas: listing, input schema, README, output, pricing.
  - MCP areas: registry entry, tools, schemas.
  - Grades: A ≥ 85, B ≥ 70, C ≥ 55, D ≥ 40, F below.
- **MCP health (0–100):**
  - Points for being reachable, a valid `initialize`, a working `tools/list`, and fast responses.
  - A server that requires auth is not penalized. If it answers 401 with discoverable OAuth metadata (RFC 9728), it can still get an A.
- **Search metrics:** rank per phrasing (1 = best), mean reciprocal rank, median rank, and top-1/3/10 counts.

### Pricing

- **$0.50 per audit** (pay per event `audit-completed`).
- Targets that can't be audited are not charged: not found, private, an unreachable MCP URL, invalid input, or an internal error.
- Set a maximum charge per run in the run options: allow **$0.50 per target plus $0.01** (Apify's tiny Actor-start fee counts too). The run never computes an audit it can't charge; remaining targets are listed as free "not audited" rows.

### FAQ

#### Does it use an LLM?

No. Phrasings, lint and suggestions are deterministic. The only model is a 30 MB static embedding model (potion-base-8M, MIT license) that runs inside the Actor. No paid API is called and your listing is not sent anywhere.

#### Is the simulated rank my real Apify Store rank?

No. It is a lexical plus semantic retrieval simulation, close to how many MCP clients and tool-search layers match descriptions. Apify's own ranking also uses a quality score: reliability, users, reviews and more. That's why we report the **real Store search position** next to it for Actors. Use the simulated rank to compare versions of your listing, not as a prediction of traffic.

#### Will it send my API keys or tokens to MCP servers?

Never. The health check sends only `initialize`, `notifications/initialized` and `tools/list` without credentials or cookies. For servers that need auth, it reports the auth method (OAuth discovery, bearer or API key) and lints the registry entry only.

#### Can I audit someone else's Actor or MCP server?

Yes, the audit only reads public data: the public Apify API, the official MCP Registry API, and the public MCP endpoint. Use it for competitor research and for your own listings.

#### Why are the generated phrasings biased toward my listing?

Half of them reuse your own words, so they show whether people who describe your tool the way you do can find it. The paraphrased half and your own phrasings test everything else. For a fair test, add 3–5 real searches.

### Limitations

- Actors must be public. Private Actors and Console URLs can't be audited.
- MCP live checks support Streamable HTTP and the legacy HTTP+SSE transport. stdio-only (package) servers get registry and retrieval checks without a live check.
- Remote URLs with template variables (they need user configuration) are not called.
- Internal or private network addresses are refused.
- The MCP Registry corpus is a bundled snapshot plus live updates since the snapshot. Very new servers may be missing for a few minutes.
- Suggestions only reuse words from your own listing or phrasings. Terms that only competitors use are listed under `onlyIfAccurate`: add them only if your tool really does that.

### Related tools

- [Sitemap URL Extractor](https://apify.com/ventura_workalong/sitemap-url-extractor): every URL from a site's sitemaps.
- [Tech Stack Detector](https://apify.com/ventura_workalong/tech-stack-detector): what software a website runs.
- [Bulk WHOIS Domain Lookup](https://apify.com/ventura_workalong/domain-lookup-bundle): RDAP, DNS, SSL and security headers.
- [PageSpeed Insights Bulk Checker](https://apify.com/ventura_workalong/pagespeed-insights-bulk): Lighthouse and Core Web Vitals.
- [PDF to Markdown & Text Extractor](https://apify.com/ventura_workalong/doc-to-markdown-tables): documents to LLM-ready Markdown.
- Free [MCP Registry Health Index](https://workalong.app/mcp-registry-health): live checks of remote MCP servers.

Questions or a wrong result? Open an issue on this Actor or use [workalong.app/support](https://workalong.app/support).

# Actor input Schema

## `targets` (type: `array`):

One target per line. An Apify Actor (`username/actor-name` or its `https://apify.com/...` URL), an official MCP Registry server name (`io.github.owner/server`), or a remote MCP server URL (`https://example.com/mcp`). Each audited target is one charge; targets that can't be audited are free.

## `taskQueries` (type: `array`):

Searches you expect users or AI agents to make when they need your tool, e.g. `extract all urls from a sitemap`. They are ranked in addition to the 10 phrasings generated from the listing. Up to 20.

## `numGeneratedQueries` (type: `integer`):

How many task phrasings to generate from the listing itself (title, description, README headings or tool names). Half reuse the listing's wording, half are paraphrases with synonyms.

## `corpusSize` (type: `integer`):

For Actors: the reference corpus is the N most popular Store Actors in each of the target's categories (deduplicated). For MCP servers the corpus is the official MCP Registry (all active servers).

## `checkStoreSearch` (type: `boolean`):

For Actors: look up the target's actual position (top 100) in Apify Store search for each task phrasing, next to the simulated rank. Uses the public Store API, one request per phrasing.

## `healthCheck` (type: `boolean`):

For MCP servers with a remote URL: call `initialize` and `tools/list` and report latency, protocol version and auth type. No credentials are ever sent, so servers that require auth report their auth method only.

## `requestTimeoutSecs` (type: `integer`):

Timeout for each live MCP request.

## Actor input object example

```json
{
  "targets": [
    "ventura_workalong/sitemap-url-extractor"
  ],
  "taskQueries": [],
  "numGeneratedQueries": 10,
  "corpusSize": 300,
  "checkStoreSearch": true,
  "healthCheck": true,
  "requestTimeoutSecs": 15
}
```

# Actor output Schema

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

One item per target: scores, lint issues, simulated search ranks per task phrasing, rewrite suggestions and (for MCP servers) the live health check. Targets that could not be audited get a free error row.

## `report` (type: `string`):

The same audits as a Markdown report, one section per target.

## `summary` (type: `string`):

Targets audited and failed, corpus sizes and sources, embedding model, and timings.

# 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 = {
    "targets": [
        "ventura_workalong/sitemap-url-extractor"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("ventura_workalong/tool-listing-auditor").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 = { "targets": ["ventura_workalong/sitemap-url-extractor"] }

# Run the Actor and wait for it to finish
run = client.actor("ventura_workalong/tool-listing-auditor").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 '{
  "targets": [
    "ventura_workalong/sitemap-url-extractor"
  ]
}' |
apify call ventura_workalong/tool-listing-auditor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ventura_workalong/tool-listing-auditor"
        }
    }
}
```

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/lUV1zWsYX8LcxJ8V7/builds/MnFlgxCD37Vz9J86j/openapi.json
