Docs
MCP & agent access
The hosted JSON-RPC endpoint at /api/mcp that lets AI agents run valuations with a Pro API key. There is nothing to install.
MCP / Agent Access — Beta
Current status: operational Beta. Pro accounts can call POST /api/mcp with a Bearer key. The transport has passed an authenticated production smoke, but it remains a Beta surface and is not a headline Launch 1.0 selling point.
What that means in practice:
- Agent access is not part of what a Pro subscription is sold on today. It is a callable Beta surface we document, not a launch headline.
- Pro API keys can call the endpoint; create or revoke them at
/dashboard/api-mcp. - The tool set covers website valuations, a dedicated Domain-only appraisal (
value_domain, paused — see below), the social platforms currently live undervalue_social, and the two dedicated creator-channel toolsvalue_youtubeandvalue_twitch. There is no RESTv1API, no resumable SSE session, and no CORS. - Questions or Beta feedback: contact support.
There is nothing to download
RealSiteWorth's MCP surface is a hosted HTTPS endpoint:
https://realsiteworth.com/api/mcp
There is no npm package, no binary, and no local server to run. You point your agent client at that URL and send a Bearer token. "Installing" it means writing a few lines of client config.
The endpoint is a stateless MCP-compatible JSON-RPC 2.0 POST facade. It supports the standard lifecycle and seven valuation/account tools (value_website, value_domain — paused, see below, value_social, value_youtube, value_twitch, get_watchlist, get_history), without resumable SSE sessions. The advertised tool list is derived from which surfaces are publicly live — it can shrink or grow as src/lib/surfaces.ts changes, so call tools/list rather than hardcoding this count. Direct legacy method calls remain supported.
What you need first
API access requires a Pro plan. The check is exact: the endpoint accepts a request only when the key belongs to an account whose tier is pro. Free and Basic keys are rejected with the same error as an invalid key.
Pro is $99 per month or $999 per year.
Pro's runtime allowances, straight from the constants:
| Constant | Value |
|---|---|
TIER_QUOTAS.pro.website_standard | 250 |
TIER_QUOTAS.pro.website_deep | 25 |
TIER_QUOTAS.pro.rateLimitPerSec | 5 |
The wire values are the internal run kinds: lite is the Quick valuation, standard is the Full valuation, deep is the Full Diligence Valuation. Send the wire value, not the product name.
For contrast, TIER_QUOTAS.basic.website_standard is 100 and TIER_QUOTAS.basic.website_deep is 3. Free carries zero Standard/Deep allowance at all — its only allowance is Lite (TIER_QUOTAS.free.lite_web_domain 15/month, .lite_social 25/month), and it cannot call the API regardless. Basic can start its Deep run from the dashboard Run Valuation page; what Basic cannot do is start ANY run through this API, because MCP/agent transport is Pro-only.
Getting your key
- Sign in and open
/dashboard/api-mcp. - Scroll to the API keys section. This block only renders when your tier is
pro. If you do not see it, your account is not on Pro. These keys authenticate the hosted MCP endpoint described on this page. - In the API Keys panel, type an optional name and press Create key.
- Copy the key immediately. The full key is returned exactly once. After that only the prefix is stored for display.
- To revoke, press Revoke next to the key. Revocation is a delete, and any service using that key loses access on the next call.
Key format: rsw_ followed by 40 lowercase hex characters, 44 characters total. Only a SHA-256 hash is stored server side. The panel and the list endpoint show a 12-character prefix (rsw_ plus 8 characters).
A key that has been revoked, or whose enabled flag is false, fails authentication.
Request shape
Every call is a POST with a JSON-RPC 2.0 envelope:
{
"jsonrpc": "2.0",
"id": 1,
"method": "value_website",
"params": { "url": "example.com" }
}
Rules enforced by the parser:
jsonrpcmust be the exact string"2.0".methodmust be present and a string.idis required for requests. The standardnotifications/initializednotification intentionally has noid.paramsis optional and defaults to{}.- The body must be a JSON object and must be 16384 bytes or smaller.
The request runs for at most 90 seconds.
JSON-RPC responses normally return HTTP 200
Success and application-level failure both normally come back as HTTP 200 with content-type: application/json. The outcome lives in the body: a result key on success, an error key on failure. Protocol-level browser protections are exceptions: an untrusted Origin gets HTTP 403, and an SSE-resume GET gets HTTP 405 because this facade is stateless.
The only headers added beyond content-type are the rate-limit headers on a throttled request.
There are no CORS headers on this route, and browser requests from an untrusted Origin are rejected. Call it from a server, a CLI, or an agent runtime.
MCP lifecycle and tools
Standard clients can use the normal sequence: initialize, notifications/initialized, tools/list, then tools/call with { "name": "value_website", "arguments": { ... } }. tools/call returns MCP content, structuredContent, and isError fields. Existing integrations may keep calling any of the tool names directly (see the current list above). The legacy authenticated tools method and unauthenticated GET /api/mcp schema listing also remain available.
This is a stateless HTTP transport: it does not issue session IDs and cannot resume an SSE stream. GET /api/mcp returns legacy discovery JSON for ordinary requests and returns 405 when a client explicitly requests text/event-stream.
value_website
Runs a website or domain valuation and returns the full report.
| Param | Type | Required | Notes |
|---|---|---|---|
url | string | yes* | 1 to 2048 characters. A bare hostname works, https:// is added if missing. |
targets | string[] | yes* | Batch form. Mutually exclusive with url — pass exactly one of the two. |
kind | "basic", "lite", "standard", or "deep" | no | Defaults to standard. "basic" is accepted as a backward-compat alias of "standard". "lite" selects the fixed reduced-evidence contract on any tier. |
Batch (targets)
targets values the whole list in one call and returns { "results": [...], "summary": {...} } instead of a single report. Caps come from TIER_BATCH_SIZE and are per request, not per month:
| Tier | kind: "standard" | kind: "deep" |
|---|---|---|
| Free / Basic keys | not applicable — the endpoint is Pro only | not applicable |
| Pro | 4 targets | 2 targets |
Exceeding the cap, or being on a plan whose cap is zero, returns -32002. The batch shares one 70-second deadline: targets are valued in order, and any target still unstarted when the deadline passes comes back in results with a skipped status rather than truncating the response. Each target meters against your monthly allowance individually, exactly as a single call would.
The URL must resolve to a public host. localhost, hostnames without a dot, and private ranges (127., 10., 192.168., 169.254., 0., 172.16-31.) are rejected with an invalid-params error.
The result is the valuation report object, including range (low, mid, high), confidence (label of LOW, MEDIUM, or HIGH, plus pct), mode, category, multiple, est_revenue_monthly, est_profit_monthly, margin, traffic_monthly, authority, trust, memo, roadmap, and nameValue.
kind selects both the monthly allowance the run counts against and how much evidence is collected. The two are not independent: the deep allowance is scarcer because a deep run costs more to produce.
On Pro, kind: "deep" turns on evidence that a basic run does not collect at all:
| Evidence | basic | deep |
|---|---|---|
| Organic traffic estimate | yes | yes |
| Brand-interest trend | yes | yes |
| AI-answer visibility (4 models) | yes | yes |
| Backlink profile | summary | full depth |
| Domain rank | — | yes |
| Ranked keywords (up to 100) | — | yes |
| Referring-domain sample (bounded) | — | yes |
| New/lost backlink trend (180d) | — | yes |
| Domain-comparable sample | — | yes |
That extra evidence feeds authority, trust, and the confidence figure, so a deep run can move the range and will usually raise confidence on a domain with real backlink history. It does not change the response *shape* — fields with no evidence behind them are reported as not measured rather than omitted, on both kinds.
The same applies to value_social: kind is passed through to the collection profile, not just to billing.
Spend the allowance deliberately. Pro gets 250 Full valuations (standard) and 25 Full Diligence Valuations (deep) a month; the Full Diligence run is the one worth saving for assets you are actually considering buying or selling. The wire value for a Standard run is kind: "standard" (2026-08-26 rename); the prior "basic" literal is still accepted as a backward-compat alias, and "lite" selects the fixed reduced-evidence contract on any tier.
The (tier, kind) matrix is defined in COLLECTION_PLAN_MANIFEST and is the single source of truth for what each combination pulls.
value_domain
Paused. Domain-only appraisal is temporarily paused while the model is recalibrated against comparable sales — every value_domain call, any kind including Lite, currently returns a paused error rather than a value, and nothing is charged against your allowance. Use value_website instead for a domain whose value depends on the site running on it.
Runs a dedicated Domain-only appraisal — the domain NAME itself as a transferable asset. This is a different product from value_website: it never collects or prices traffic, backlinks, existing content, or revenue, even when the domain has a live site on it. Use value_website instead when the value depends on the operating site.
| Param | Type | Required | Notes |
|---|---|---|---|
domain | string | yes* | A bare domain, e.g. example.com. Mutually exclusive with url — pass exactly one of the two. |
url | string | yes* | A URL whose registrable hostname is resolved and appraised. |
kind | "basic", "lite", or "standard" | no | Defaults to standard. Deep does not exist for domain appraisals — requesting it returns -32602 before any quota or pipeline work. |
No batch form: pass one domain or url per call. The underlying Domain-only pipeline has no batch capability, unlike value_website.
Standard runs draw from their own domain_standard monthly allowance, separate from the website quota; Lite draws from the same shared lite_shared pool as every other Lite run on a paid plan. Both are moot while the surface is paused.
The result includes range, confidence, registration (state, age, registrar), nameQuality (length, structure, pronounceability, commercial intent), liquidity, collision (trademark-screening status — Standard only; Lite returns unavailable), includes and excludes (the evidence families this run collected and explicitly did not), risks, nextActions, memo, and evidence (per-signal measured / not_attempted status — a missing signal is never silently priced in).
value_social
Runs a social account valuation.
| Param | Type | Required | Notes |
|---|---|---|---|
platform | enum | yes | Currently tiktok, instagram, twitter. X/Twitter is a public creator surface; a dollar range still requires measured evidence. Facebook remains hidden-preview, so value_social neither advertises nor accepts it — sending it returns -32602, not a valuation. The enum is derived from src/lib/surfaces.ts's live status, so it grows the day a platform goes live, with no separate doc or schema to update. |
handle | string | yes | 1 to 128 characters |
kind | "basic", "lite", or "standard" | no | Defaults to standard. "basic" is an alias of "standard". Deep does not exist for social valuations. |
The result includes surface, handle, range, confidence, multiple, est_monthly_revenue, est_annual_sde, signals, memo, roadmap, and generatedAt.
value_youtube
Runs a YouTube channel valuation — the same surface as POST /api/value-youtube.
| Param | Type | Required | Notes |
|---|---|---|---|
handle | string | yes | Channel handle (@name), bare name, or a full youtube.com channel URL |
niche | enum | no | finance, tech, business, education, health, gaming, lifestyle, entertainment, other. Defaults to other. |
kind | "basic", "lite", or "standard" | no | Defaults to standard. "basic" is an alias of "standard". Deep does not exist for creator surfaces. |
The result shape matches value_social's. Billing note: value_youtube meters against the same social_standard (and, for kind: "lite", the shared lite_shared) monthly counter as value_social — there is no separate YouTube allowance. It has no batch form.
value_twitch
Runs a Twitch channel valuation — the same surface as POST /api/value-twitch.
| Param | Type | Required | Notes |
|---|---|---|---|
handle | string | yes | Twitch login, bare name, or a full twitch.tv channel URL |
niche | enum | no | just_chatting, gaming, esports, irl, creative, music, other. Defaults to other. |
kind | "basic", "lite", or "standard" | no | Defaults to standard. "basic" is an alias of "standard". Deep does not exist for creator surfaces. |
Same result shape and the same shared social_standard / lite_shared billing as value_youtube. It has no batch form.
get_watchlist
Returns the tracked assets on your account. No quota is charged.
| Param | Type | Required | Notes |
|---|---|---|---|
surface | string | no | Exact-match filter on the stored surface |
limit | number | no | Default 50, minimum 1, maximum 200 |
Returns { "watchlist": [...] }. Each row has id, domain, surface, targetKind, target, lastRefreshedAt, createdAt, and lastValuation with range, confidenceLabel, and mode. Rows are ordered newest first. Database failures return -32005; they are never disguised as a valid empty list.
get_history
Queries the valuation run ledger. No quota is charged.
| Param | Type | Required | Notes |
|---|---|---|---|
limit | number | no | Default 20, minimum 1, maximum 100 |
surface | string | no | Exact-match filter |
Returns { "history": [...] } with requestId, surface, domain, outcome, tier, runKind, createdAt, valueLow, valueMid, and valueHigh.
History is filtered by the authenticated portal user id, so it includes that account's MCP valuation runs without exposing another account's targets.
tools
Takes no params. Returns { "tools": [...], "name": "realsiteworth", "description": ..., "version": "1.0.0" } with the JSON Schema for each method's inputs.
End-to-end example
curl -sS https://realsiteworth.com/api/mcp \
-H "Authorization: Bearer rsw_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "value_website",
"params": { "url": "example.com", "kind": "basic" }
}'
A successful response looks like this, trimmed:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"url": "https://example.com/",
"mode": "C",
"range": { "low": 0, "mid": 0, "high": 0 },
"confidence": { "label": "LOW", "pct": 0 },
"memo": [],
"roadmap": []
}
}
List the methods without a key:
curl -sS https://realsiteworth.com/api/mcp
Appraise a domain name:
curl -sS https://realsiteworth.com/api/mcp \
-H "Authorization: Bearer rsw_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 4,
"method": "value_domain",
"params": { "domain": "example.com", "kind": "standard" }
}'
Value a TikTok handle:
curl -sS https://realsiteworth.com/api/mcp \
-H "Authorization: Bearer rsw_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "value_social",
"params": { "platform": "tiktok", "handle": "someaccount" }
}'
Client configuration
These snippets point a client at the hosted endpoint with a Bearer header. The config file format is owned by each client, so check your client's own documentation if a field name has changed.
Claude Desktop, in claude_desktop_config.json:
{
"mcpServers": {
"realsiteworth": {
"url": "https://realsiteworth.com/api/mcp",
"headers": { "Authorization": "Bearer rsw_your_key_here" }
}
}
}
Claude Code, in .mcp.json at your project root:
{
"mcpServers": {
"realsiteworth": {
"type": "http",
"url": "https://realsiteworth.com/api/mcp",
"headers": { "Authorization": "Bearer rsw_your_key_here" }
}
}
}
Cursor, in ~/.cursor/mcp.json or .cursor/mcp.json:
{
"mcpServers": {
"realsiteworth": {
"url": "https://realsiteworth.com/api/mcp",
"headers": { "Authorization": "Bearer rsw_your_key_here" }
}
}
}
The endpoint implements the MCP lifecycle handshake over a stateless JSON-RPC facade and keeps direct JSON-RPC tool calls for backward compatibility. Use GET /api/mcp or the legacy tools method only when a client cannot perform tools/list.
Never commit a key to a repository. Read it from an environment variable or your client's secret store.
Rate limits
The limiter is a per-user durable Redis token bucket: 5 requests per second with a burst of 10. Atomic checks work across application processes; if the shared limiter is unavailable, API requests fail closed.
When you exceed it, you get error code -32003 and these headers:
| Header | Meaning |
|---|---|
x-ratelimit-limit | 5 |
x-ratelimit-remaining | 0 |
retry-after | Seconds to wait, rounded up |
x-ratelimit-reset | Same value as retry-after |
These headers are only set on a throttled response.
Error codes
| Code | Name | When |
|---|---|---|
-32700 | Parse error | The body is not valid JSON |
-32600 | Invalid request | Body is not an object, jsonrpc is not "2.0", method is missing or not a string, id is missing, or the body exceeds 16384 bytes |
-32601 | Method not found | Unknown method name. The message lists the valid ones |
-32602 | Invalid params | Params failed validation, or the URL is not a valid public host |
-32603 | Internal error | An unhandled error in the handler |
-32001 | Unauthorized | Missing, malformed, invalid, or revoked key, or a valid key on a non-Pro account |
-32002 | Tier forbidden | A targets batch is larger than your plan's per-request cap, or your plan allows zero batch targets for that kind |
-32003 | Rate limited | Over 5 requests per second |
-32004 | Quota exceeded | Your monthly allowance for that run kind is used up |
-32005 | Upstream error | A valuation or account-data query failed upstream |
-32002 is emitted only for the batch cases above. A non-Pro key produces -32001, not -32002, because the authentication check and the tier check are one condition.
How API runs meter against your plan
The gate is evaluate, then run, then commit.
- Before the pipeline starts, the request is checked against your monthly allowance for the requested
kind. If it fails, you get-32004, the run is written to the ledger with outcomedenied, and nothing is charged. - The valuation runs.
- On success, consumption is committed against your monthly counter, the run is written to the ledger with outcome
success, and a daily API call is recorded against themcpendpoint for your account. - On failure, the run is written to the ledger with outcome
errorand no consumption is committed.
There is one refund case worth knowing. If a social valuation comes back fully degraded, meaning every provider missed and the report holds no real signals, the commit is skipped entirely. A report with nothing in it costs you nothing. Because the gate never reserved anything up front, skipping the commit is the refund, and repeating it cannot mint usage.
get_watchlist and get_history never touch the quota gate and are not recorded as API calls. They still consume rate-limit tokens.
Discovery files
These are public, unauthenticated, and cached for an hour. Point a crawler or an agent at them to learn the surface without a key.
| Path | Content |
|---|---|
GET /api/mcp | Server metadata plus the tool list and a one-line auth instruction |
/.well-known/mcp/server-card.json | MCP server card: transport http-json-rpc, endpoint, bearer auth, tool schemas |
/.well-known/mcp.json | Same server card |
/.well-known/agent-card.json | Agent card: capabilities, supported interfaces, safety disclaimer, skills |
/.well-known/agent-skills/index.json | Skills index with a SHA-256 digest per skill |
/.well-known/skills/index.json | Same skills index |
/.well-known/api-catalog | RFC 9264 linkset with service doc, status, and the MCP server card |
/agent-skills/value-website | Markdown skill doc for website valuation |
/agent-skills/value-social | Markdown skill doc for social valuation |
/agent-skills/account-workspace | Markdown skill doc for watchlist and history |
/llms.txt | Short AI-facing reference |
/llms-full.txt | Full AI-facing reference |
/llm-info | The same full reference rendered as a web page |
The server card reports capabilities.tools: true with resources and prompts both false, which is accurate. This server exposes callable methods only.
Safety and scope
Every number the endpoint returns comes from the deterministic RealSiteWorth valuation engine, not from a language model. Output is an automated estimate. It is not a formal appraisal, and it is not investment or financial advice.
If you are wiring this into an agent, hold it to the same rule the published skill docs state: the agent may explain and summarize what the endpoint returned, and must not invent valuation inputs, metrics, or dollar figures that RealSiteWorth did not return.
get_watchlist and get_history are private account surfaces scoped to the key holder. Treat what they return as user-owned workspace data.
