# VerifiedDR (remote · verifieddr.com)

Website authority and AI visibility tools for DR, TrueDR, keywords, backlinks, and partnerships.

- Trust score: 67/100 (medium)
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-08-03

## Components

- remote · `verifieddr.com`: 67/100 (this document), [markdown](https://verifymcp.io/servers/verifieddr-verifieddr/api-mcp.md), [page](https://verifymcp.io/servers/verifieddr-verifieddr/api-mcp)

## Channel facts

- Endpoint: `https://verifieddr.com/api/mcp`
- Transports: `streamable-http`
- Auth: `required`
- Version: `1.0.0`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-08-03.

- **Endpoint Security**: 63/100
  - The endpoint's TLS certificate is valid, in date, and uses a strong key.
  - Authorisation check failed: no authorisation is required to call this server, and it exposes a tool marked destructive (remove_tracked_keyword).
  - HTTPS is enforced; there's no plaintext access path.
  - The HSTS (Strict-Transport-Security) header is present.
  - DNSSEC check failed: this domain isn't protected by DNSSEC.
- **Transport & Reachability**: 100/100
  - Verified streamable-http transport via a live MCP handshake.
- **Schema Quality & AI Usability**: 85/100
  - 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).
  - AI-judged instruction clarity (excellent).
  - Tool/resource definitions use about 4454 tokens (~70/item across 63 items; 63 tools + 0 resources), lean.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 13/100
  - Stability observed for 4 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 98/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 95% of tool parameters carry a description.
- **Capabilities**: 60/100
  - Spec-recency check failed: implements MCP spec 2025-06-18; the latest is 2026-07-28.

## Install

### Claude

```bash
claude mcp add --transport http verifieddr-verifieddr https://verifieddr.com/api/mcp
```

### Codex

```toml
[mcp_servers.verifieddr-verifieddr]
url = "https://verifieddr.com/api/mcp"
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "verifieddr-verifieddr": {
      "type": "remote",
      "url": "https://verifieddr.com/api/mcp",
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add verifieddr-verifieddr --url https://verifieddr.com/api/mcp --transport streamable-http
```

### Hermes

```yaml
mcp_servers:
  verifieddr-verifieddr:
    url: "https://verifieddr.com/api/mcp"
```

### Other

```json
{
  "mcpServers": {
    "verifieddr-verifieddr": {
      "type": "http",
      "url": "https://verifieddr.com/api/mcp"
    }
  }
}
```

The mcpServers block is a cross-client convention. Remote transports vary, so check your client's docs.

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-08-03 (score 67, +1)

- [security] Tool “get_domain_rating” rewrote its description, which is the text the model reads
- [functional] Schema quality: good → excellent
- [functional] New tool “check_site”
- [cosmetic] “submit_site” added an optional parameter “siteCheck”

### 2026-08-02 (score 66, +2)

- [functional] The server now declares the “prompts” capability
- [functional] First check of Schema quality: 100
- [functional] Schema quality: excellent → good
- [functional] New prompt “ai-visibility”
- [functional] New prompt “buy-backlinks”
- [functional] New prompt “competitor-teardown”
- [functional] New prompt “earn-placements”
- [functional] New prompt “find-prospects”
- [functional] New prompt “growth-loop”
- [functional] New prompt “inbox-triage”
- [functional] New prompt “review-my-authority”
- [functional] New prompt “run-ai-visibility”
- [functional] New prompt “tune-ai-questions”
- [functional] New prompt “write-article”
- [functional] New prompt “gsc-audit”
- [functional] New prompt “launch-a-site”
- [functional] New prompt “partner-outreach”
- [functional] New tool “get_domain_rating”

### 2026-07-31 (score 64, −1)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-30 (score 65)

First indexed and scored.

## MCP tools (63)

### `account_usage` (~47 tokens)

Account usage & quota

Your plan, the account-wide AI prompt budget, remaining API quota, and plan entitlements. Call this first: it is how you budget before acting instead of discovering caps as a 402.

### `list_categories` (~29 tokens)

List site categories

The category values accepted when submitting a site or filtering discovery (32 values, max 3 per site).

### `list_sites` (~35 tokens)

List your sites

All websites on your account with current metrics: DR, TrueDR, weekly/monthly changes, traffic, referring domains, verification state.

### `submit_site` (~163 tokens)

Submit a site

List a new website on VerifiedDR, owned by your account. Use the primary domain (example.com, not blog.example.com). Owned submits count against the free-tier unverified-site cap.

Input parameters:

- `categories` (array): Up to 3 values from list_categories.
- `description` (string): Short description, max 240 chars.
- `siteCheck` (boolean): Also run the site reality check (shell/PBN/spam heuristics) at submit time; fetch the stored report later with check_site.
- `title` (string): Display title, 1-40 chars.
- `url` (string, required): The site's primary domain or URL, e.g. example.com.
- `xHandle` (string): X/Twitter handle, e.g. @acme.

### `get_site` (~68 tokens)

Get one site

One site with DR and traffic history plus latest backlink totals. Resolves your own sites first, then falls back to any approved public site (`owned` says which).

Input parameters:

- `site` (string, required): Any approved VerifiedDR site: a domain, URL, or slug (does not have to be yours).

### `get_truedr` (~93 tokens)

Get TrueDR

TrueDR (DR weighted by trust and real traffic) for one of YOUR sites, from the stored score. With detailed=true also returns the per-signal trust breakdown and recommended actions — the only place that breakdown is exposed.

Input parameters:

- `detailed` (boolean): Include the per-signal breakdown and recommendations.
- `site` (string, required): One of your websites, as a slug or hostname (e.g. example.com).

### `export_site` (~56 tokens)

Export site data

Machine-readable export for one of your sites: current metrics, the full public authority payload, and badge snippets in one response.

Input parameters:

- `site` (string, required): One of your websites, as a slug or hostname (e.g. example.com).

### `lookup_site` (~66 tokens)

Look up any site

Public authority lookup for ANY approved site: DR, TrueDR, trust score, confidence, traffic validation, and latest backlink evidence. Never returns owner data.

Input parameters:

- `site` (string, required): Any approved VerifiedDR site: a domain, URL, or slug (does not have to be yours).

### `get_domain_rating` (~101 tokens)

Get Domain Rating for any domain

Domain Rating for ANY domain: the site does not have to be on VerifiedDR. Use it to score a prospect, competitor, or link target before anyone submits it. DR only: TrueDR, trust and traffic need a tracked site, so call `lookup_site` when `listed` is true.

Input parameters:

- `domain` (string, required): Any domain or URL at all: it does not have to be on VerifiedDR, and nobody has to have submitted it.

### `check_site` (~137 tokens)

Check whether a site is real

Stored fraud check for a submitted site: homepage shell detection, domain age, organic-keyword footprint versus backlink profile, and spam score, combined into a real/suspicious/shell/unreachable verdict with plain-language reasons. Read-only and listed-sites-only: reports are created by `submit_site` with `siteCheck: true`, and this returns 404 for unsubmitted domains or until a report exists. Use it to vet link partners, exchange candidates, and outreach prospects before trading anything.

Input parameters:

- `domain` (string, required): Any domain or URL at all: it does not have to be on VerifiedDR, and nobody has to have submitted it.

### `get_trust_map` (~76 tokens)

Get Trust Map

The public Trust Map (backlink map) for any approved site, from cache: per-domain DR, link type, importance, spam score. Answers 503 if no cached map exists yet.

Input parameters:

- `site` (string, required): Any approved VerifiedDR site: a domain, URL, or slug (does not have to be yours).

### `get_badge_snippets` (~71 tokens)

Get badge snippets

Ready-to-paste badge and embed snippets (HTML, markdown, share text) plus public links (badge, OG image, sparkline) for any approved site.

Input parameters:

- `site` (string, required): Any approved VerifiedDR site: a domain, URL, or slug (does not have to be yours).

### `monitor_sites` (~76 tokens)

Monitor your sites

Authority watch across your sites: weekly (or daily) change digest with traffic validation and spam/trust alerts. Optionally restrict to one site.

Input parameters:

- `daily` (boolean): Use the daily cadence instead of weekly.
- `site` (string): One of your websites, as a slug or hostname (e.g. example.com). Optional.

### `verify_site` (~60 tokens)

Verify badge

Fetch one of your sites and check the VerifiedDR badge is embedded. Side effect: marks the site verified or unverified based on the result.

Input parameters:

- `site` (string, required): One of your websites, as a slug or hostname (e.g. example.com).

### `find_sites` (~112 tokens)

Find trusted sites

Discover approved sites by authority for partner/sponsor/integration prospecting, ranked by TrueDR then DR. Verified-only by default.

Input parameters:

- `category` (string): A category value from list_categories.
- `includeUnverified` (boolean): Include unverified sites too.
- `limit` (number): 1-50, default 25.
- `minDr` (number): Minimum classic DR.
- `minTrueDr` (number): Minimum TrueDR.
- `trafficValidated` (boolean): Only sites with validated traffic.

### `find_partner_opportunities` (~122 tokens)

Find partner opportunities

Partner candidates for one of your sites: verified sites worth contacting, excluding anyone you already contacted or dismissed. Use contact_partner to reach out.

Input parameters:

- `category` (string): Filter by category.
- `limit` (number): 1-25, default 25.
- `minDr` (number): Minimum classic DR.
- `minTrueDr` (number): Minimum TrueDR.
- `site` (string, required): One of your websites, as a slug or hostname (e.g. example.com).
- `trafficValidated` (boolean): Only sites with validated traffic.

### `contact_partner` (~135 tokens)

Contact a partner

Send a partnership request to one discovered candidate, as the account owner. SENDS REAL EMAIL — always preview with dryRun=true and get the user's approval before sending. Subject and message must be human-quality; there is no template fallback. Monthly contact limits apply per plan.

Input parameters:

- `dryRun` (boolean): Preview without sending. Default false.
- `message` (string, required): Email body.
- `site` (string, required): One of your websites, as a slug or hostname (e.g. example.com).
- `subject` (string, required): Email subject.
- `target` (string, required): The candidate's slug or domain from find_partner_opportunities.

### `keyword_difficulty` (~84 tokens)

Keyword difficulty

The DR profile of the live Google top 10 for a keyword: median DR needed, the weakest ranking domain (entry point), and — with your domain — your gap and a verdict. Paid plans only (402 otherwise).

Input parameters:

- `domain` (string): Your domain, to add gap + verdict.
- `keyword` (string, required): The keyword, 2-80 chars.

### `keyword_suggestions` (~60 tokens)

Winnable keywords

Winnable keywords a domain already ranks 4-30 for, ordered by traffic value, brand queries filtered out. Works for any domain (competitor research). Paid plans only.

Input parameters:

- `domain` (string, required): Any domain, e.g. competitor.com.

### `list_tracked_keywords` (~73 tokens)

List tracked keywords

Tracked keyword targets for one of your sites with stored difficulty snapshots (median DR, gap, tier, volume, positions) and 28-day GSC impressions when connected. Free on every plan.

Input parameters:

- `site` (string, required): One of your websites, as a slug or hostname (e.g. example.com).

### `add_tracked_keyword` (~64 tokens)

Track a keyword

Add a keyword target to one of your sites and snapshot its difficulty. Per-site keyword cap applies.

Input parameters:

- `keyword` (string, required): The keyword to track.
- `site` (string, required): One of your websites, as a slug or hostname (e.g. example.com).

### `refresh_tracked_keyword` (~57 tokens)

Refresh a keyword

Re-snapshot a saved keyword target's difficulty.

Input parameters:

- `id` (string, required): Target id from list_tracked_keywords.
- `site` (string, required): One of your websites, as a slug or hostname (e.g. example.com).

### `remove_tracked_keyword` (~53 tokens)

Untrack a keyword

Remove a tracked keyword target.

Input parameters:

- `id` (string, required): Target id from list_tracked_keywords.
- `site` (string, required): One of your websites, as a slug or hostname (e.g. example.com).

### `get_ai_visibility` (~78 tokens)

Get AI visibility

How often ChatGPT, Perplexity, and Google AI Mode name one of your sites for its tracked questions: score, per-question answers, rival brands, cited pages worth outreach, and run history. Reading never spends budget.

Input parameters:

- `site` (string, required): One of your websites, as a slug or hostname (e.g. example.com).

### `diff_ai_visibility_runs` (~95 tokens)

Diff two visibility runs

Compare two stored AI visibility runs: score delta, gained/lost mentions, new/dropped cited sources, brands that entered or left. Run timestamps come from get_ai_visibility history.

Input parameters:

- `from` (string, required): ISO timestamp of the older run.
- `site` (string, required): One of your websites, as a slug or hostname (e.g. example.com).
- `to` (string, required): ISO timestamp of the newer run.

### `run_ai_visibility_scan` (~75 tokens)

Run a visibility scan

Ask the tracked questions across AI engines NOW. Paid plans only, one run per site per week (inside the cooldown you quietly get the stored run back). This spends real vendor budget — check account_usage first.

Input parameters:

- `site` (string, required): One of your websites, as a slug or hostname (e.g. example.com).

### `add_ai_visibility_prompt` (~127 tokens)

Add a tracked question

Add one question to a site's AI visibility tracking (8-300 chars; must not name your own brand/domain). Counts against the account-wide prompt budget. Non-global locations need a paid plan.

Input parameters:

- `location` (string): Target market for the question: "global" (default) or a 2-letter ISO country code like us, gb, de, nl, fr.
- `prompt` (string, required): The question, e.g. "best crm for agencies".
- `site` (string, required): One of your websites, as a slug or hostname (e.g. example.com).

### `import_ai_visibility_prompts` (~108 tokens)

Import tracked questions

Import several questions at once (bad lines are skipped, so a pasted numbered list works). Counts against the account-wide prompt budget.

Input parameters:

- `location` (string): Target market for the question: "global" (default) or a 2-letter ISO country code like us, gb, de, nl, fr.
- `prompts` (array, required): The questions to import.
- `site` (string, required): One of your websites, as a slug or hostname (e.g. example.com).

### `set_ai_visibility_prompt_location` (~98 tokens)

Re-target a question

Pin one tracked question to a country market. Paid plans only.

Input parameters:

- `location` (string, required): Target market for the question: "global" (default) or a 2-letter ISO country code like us, gb, de, nl, fr.
- `promptId` (string, required): Prompt id from get_ai_visibility.
- `site` (string, required): One of your websites, as a slug or hostname (e.g. example.com).

### `reorder_ai_visibility_prompts` (~65 tokens)

Reorder tracked questions

Reorder the tracked questions; pass every prompt id in the new order.

Input parameters:

- `promptIds` (array, required): All prompt ids, in the new order.
- `site` (string, required): One of your websites, as a slug or hostname (e.g. example.com).

### `reset_ai_visibility_prompts` (~61 tokens)

Reset tracked questions

Throw away the current question set and reseed from the site's keywords. Paid plans only. Destructive: the old questions are gone.

Input parameters:

- `site` (string, required): One of your websites, as a slug or hostname (e.g. example.com).

### `remove_ai_visibility_prompt` (~56 tokens)

Remove a tracked question

Delete one tracked question by its prompt id.

Input parameters:

- `promptId` (string, required): Prompt id from get_ai_visibility.
- `site` (string, required): One of your websites, as a slug or hostname (e.g. example.com).

### `get_growth_plan` (~68 tokens)

Get growth plan

The generated growth task plan for one of your sites: ranked tasks with impact, status, and execution artifacts, plus benchmark sites. Free plans get the summary and one revealed action.

Input parameters:

- `site` (string, required): One of your websites, as a slug or hostname (e.g. example.com).

### `run_growth_plan` (~59 tokens)

Generate growth plan

Generate a fresh growth plan. Paid plans only. Progress on unchanged tasks carries over, so a re-run never reopens finished work.

Input parameters:

- `site` (string, required): One of your websites, as a slug or hostname (e.g. example.com).

### `update_growth_task` (~65 tokens)

Update growth task

Move one growth task's status after executing it.

Input parameters:

- `id` (string, required): Task id from get_growth_plan.
- `site` (string, required): One of your websites, as a slug or hostname (e.g. example.com).
- `status` (string, required): The new status.

### `get_gsc_audit` (~55 tokens)

Get GSC index audit

The latest stored Google Search Console index audit for one of your sites (needs a connected GSC property).

Input parameters:

- `site` (string, required): One of your websites, as a slug or hostname (e.g. example.com).

### `run_gsc_audit` (~56 tokens)

Run GSC index audit

Run a fresh index audit. Spends real GSC URL Inspection quota; 12h cooldown between runs.

Input parameters:

- `site` (string, required): One of your websites, as a slug or hostname (e.g. example.com).

### `get_gsc_performance` (~79 tokens)

Get GSC performance

Search Console performance for one of your sites: totals vs the preceding period, daily data, and top query/page/country/device snapshots from the existing sync.

Input parameters:

- `range` (string): Date range, default 28d.
- `site` (string, required): One of your websites, as a slug or hostname (e.g. example.com).

### `marketplace_packages` (~32 tokens)

List backlink packages

Backlink Packages on offer, priced for this account (plan discount applied), with the exact websites each package places on.

### `marketplace_sites` (~54 tokens)

List single placements

Single-website listings — buy one placement on one website — ranked with your niches first. Each row's websiteId is what marketplace_cart_add_site takes.

Input parameters:

- `limit` (number): 1-100, default 50.

### `marketplace_cart` (~14 tokens)

View cart

Your current open marketplace cart.

### `marketplace_cart_add_package` (~47 tokens)

Add package to cart

Add a Backlink Package to the cart. Prices are re-derived server-side; the cart caps at 5 rows.

Input parameters:

- `packageId` (string, required): Package id from marketplace_packages.

### `marketplace_cart_add_site` (~33 tokens)

Add site to cart

Add a single-website placement to the cart.

Input parameters:

- `websiteId` (string, required): websiteId from marketplace_sites.

### `marketplace_cart_remove` (~31 tokens)

Remove cart row

Remove one row from the cart by its index.

Input parameters:

- `index` (number, required): Row index from marketplace_cart.

### `marketplace_cart_checkout` (~43 tokens)

Checkout cart

Start checkout: returns a Stripe Checkout URL and charges NOTHING. A human opens the URL and enters the card — that boundary is deliberate. Give the URL to the user.

### `marketplace_orders` (~37 tokens)

List orders

Every marketplace order with its placements, their status, and live URLs as publishers deliver. An unbriefed paid order is the thing to chase.

### `marketplace_order_brief` (~73 tokens)

Brief an order

Brief a paid order so publishers can start (the brief is collected after payment on purpose).

Input parameters:

- `anchorPrefs` (string)
- `companyDescription` (string)
- `orderNo` (string, required): Order number from marketplace_orders.
- `talkingPoints` (string)
- `targetUrls` (array)

### `marketplace_requests` (~49 tokens)

List your asks

What one of your websites is asking other websites for (the Ask side of the marketplace).

Input parameters:

- `site` (string, required): One of your websites, as a slug or hostname (e.g. example.com).

### `marketplace_request_post` (~122 tokens)

Post or edit an ask

Post what your website wants from others and what you'll pay (or pass id to edit an existing ask). Requires a verified website.

Input parameters:

- `budgetAmount` (number): Budget in USD cents; 0 = open to discuss.
- `description` (string, required): What you want, concretely.
- `id` (string): Existing request id — pass to edit instead of add.
- `site` (string, required): One of your websites, as a slug or hostname (e.g. example.com).
- `title` (string, required): Short title, e.g. Review swap.

### `marketplace_request_remove` (~50 tokens)

Remove an ask

Take a posted ask down.

Input parameters:

- `id` (string, required): Request id from marketplace_requests.
- `site` (string, required): One of your websites, as a slug or hostname (e.g. example.com).

### `earn_sites` (~29 tokens)

List publisher sites

Every owned website with what it earns per placement, whether it's in the publisher network, and its terms.

### `earn_join_network` (~138 tokens)

Join publisher network

Join the publisher network with one verified website. REFUSES to run without acceptTerms=true, because joining accepts the publisher terms on the owner's behalf — confirm with the user first. Lands in pending for human approval.

Input parameters:

- `acceptTerms` (boolean, required): Must be true; confirms the owner accepts the publisher terms.
- `linkTypes` (array): Placement types offered. Default: all three.
- `maxPlacementsPerMonth` (number): Default 4.
- `site` (string, required): One of your websites, as a slug or hostname (e.g. example.com).
- `turnaroundDays` (number): Max 7, default 7.

### `earn_update_settings` (~78 tokens)

Update publisher settings

Tune a network website's placement settings: link types, turnaround, monthly cap.

Input parameters:

- `linkTypes` (array)
- `maxPlacementsPerMonth` (number)
- `site` (string, required): One of your websites, as a slug or hostname (e.g. example.com).
- `turnaroundDays` (number): Max 7.

### `earn_set_status` (~68 tokens)

Pause/resume publishing

Set a network website's status: active, paused (stops new work without leaving), or removed (leaves the network).

Input parameters:

- `site` (string, required): One of your websites, as a slug or hostname (e.g. example.com).
- `status` (string, required): The new status.

### `earn_assignments` (~30 tokens)

List assignments

Placements assigned to your websites — target URL, anchor, the buyer's brief, payout, deadline.

### `earn_accept_assignment` (~28 tokens)

Accept assignment

Accept an assigned placement.

Input parameters:

- `placementId` (string, required): Placement id from earn_assignments.

### `earn_decline_assignment` (~52 tokens)

Decline assignment

Decline an assigned placement (declining is free and expected).

Input parameters:

- `placementId` (string, required): Placement id from earn_assignments.
- `reason` (string): Optional, e.g. "off-topic".

### `earn_submit_live_url` (~66 tokens)

Report placement live

Report a placement live — the server fetches the URL and checks the link is actually present before marking it verified. This is what gets you paid.

Input parameters:

- `liveUrl` (string, required): The published page URL.
- `placementId` (string, required): Placement id from earn_assignments.

### `earn_earnings` (~32 tokens)

Publisher earnings

What your websites have earned as publishers (USD cents): pending, due, paid, and the payout threshold.

### `inbox_list` (~58 tokens)

List inbox threads

Partnership conversations with the unread count. Time-sensitive human work: summarize and draft, don't answer on your own.

Input parameters:

- `limit` (number): 1-100, default 25.
- `offset` (number): Pagination offset, default 0.

### `inbox_thread` (~38 tokens)

Read a thread

One partnership conversation: its messages, the website on each side, and any deal attached.

Input parameters:

- `id` (string, required): Thread id from inbox_list.

### `inbox_reply` (~59 tokens)

Reply to a thread

Reply in a partnership thread. SENDS REAL EMAIL to the other side, as the account owner — draft and send only on the user's word.

Input parameters:

- `body` (string, required): The reply text.
- `id` (string, required): Thread id from inbox_list.

### `inbox_mark_read` (~28 tokens)

Mark thread read

Mark a partnership thread as read.

Input parameters:

- `id` (string, required): Thread id from inbox_list.

## Diagnostics

Captured diagnostic sections: TLS, DNSSEC, Authorisation, Transports. The full working is on the page: https://verifymcp.io/servers/verifieddr-verifieddr/api-mcp#diagnostics

## Score history

- 2026-08-03: 67
- 2026-08-02: 66
- 2026-08-01: 64
- 2026-07-31: 64
- 2026-07-30: 65

## Links

- Remote endpoint: https://verifieddr.com/api/mcp
- Authorisation metadata: https://verifieddr.com/.well-known/oauth-protected-resource/api/mcp
- Website: https://verifieddr.com/mcp
- Changelog RSS feed: https://verifymcp.io/servers/verifieddr-verifieddr/api-mcp/changelog.xml
- Changelog JSON feed: https://verifymcp.io/servers/verifieddr-verifieddr/api-mcp/changelog.json
- HTML version of this page: https://verifymcp.io/servers/verifieddr-verifieddr/api-mcp
