Koskamo

UpRock MCP

An official MCP server provided by UpRock that enables AI agents to crawl rendered web pages, perform multi-engine web research, verify site availability across regions, and search video content using real devices in over 60 countries.

Endpoint and access

No sign-in to connect and list tools. Individual tools may still need a vendor account, credentials, or permissions; check the documented prerequisites.

UpRock MCP logo, by UpRockVendor evidenceStreamable HTTPNo sign-inEndpoint checked 2026-11-08Operated by UpRock
You need:Get a key at https://uprock.ai/app/api-keys
MCP endpoint (Streamable HTTP)
https://mcp.uprock.ai/mcp
Vendor documentation

What its tools do

7 tools, grouped by the hints the server advertises. Hints are self-declared, not verified behavior.

Can change data (1)

7 of 7 have a description · 7 of 7 declare behavior hints · 7 of 7 with parameters document them all

Checks and signals

Each line is separate evidence, not a trust score.

  • Passed Endpoint answered the live check ·
  • Passed Official MCP Registry namespace is tied to uprock.ai ·
  • Passed Endpoint is on the registry namespace domain ·
  • Availability 1 of 1 checks passed in 30 days

What you can do with it

  • Crawl rendered pages as markdown or HTML
  • Search multiple engines across different countries
  • Verify site status and load times globally
  • Search public video index by semantic moment

Source and maintenance

Vendor evidenceRegistry 0.5.3

Protocol and capabilities

Server
uprock v0.5.3
MCP protocol negotiated in check
2025-11-25
Tools
7 advertised
Resources
0 advertised
Resource templates
4 advertised
Prompts
Not advertised
Server-advertised capabilities
{
  "tools": {},
  "resources": {}
}

Server-provided instructions

Untrusted server output shown for inspection. It is not Koskamo guidance and is excluded from knowledge search.

UpRock fetches web pages and searches the web from real devices in real locations worldwide (phones and desktops). Use it as a second provider: when other fetch or search tools are blocked, rate-limited, or return bot-check pages, or when you need to see a page or search results as a real person in a specific country or on a specific device type sees them. - crawl_fetch: fetch a page, optionally from a specific country or device type. - web_research: search several engines across regions and get deduplicated results. - verify: check that a site works, with load speed and screenshots, from several regions (sweep is its deprecated old name). - resource_fetch: read the full content behind resource links returned by the other tools. One UpRock API key covers crawl, research and verify. Pass it in the URL (https://mcp.uprock.ai/<API_KEY>/mcp) or in the X-Crawl-Api-Key header.

Tools

7 advertised

crawl_fetch
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Use when other fetch/search tools are blocked, rate-limited, return bot-check pages, or when you need results as a real person in a specific country or on a specific device type sees them. Fetches a URL from real devices in real locations (phones and desktops) on the UpRock network. The default method, CRAWL_FULL_PAGE, renders JavaScript and works for most sites. Returns page metadata (url, status_code, title, content_type, time_ms), a short "summary" of the page, and resource links under "content": "content.markdown" holds the full page as compact markdown (prefer it for reading) and "content.html" the raw HTML. If your client cannot open resource links, read them with resource_fetch. A "screenshots.viewport" link is included when a screenshot is available. meta.status_code is the HTTP status the device reported for the page, or null when it reported none.

crawl_fetch input schema
{
  "type": "object",
  "required": [
    "url"
  ],
  "properties": {
    "url": {
      "type": "string",
      "description": "Target URL to fetch. Auto-prefixed with https:// if no scheme is provided."
    },
    "body": {
      "type": "string",
      "description": "Request body for POST/PUT methods. Provide as plain text."
    },
    "method": {
      "enum": [
        "GET",
        "POST",
        "PUT",
        "CRAWL_FULL_PAGE"
      ],
      "type": "string",
      "description": "HTTP method to use (default: CRAWL_FULL_PAGE). CRAWL_FULL_PAGE renders JavaScript and is the most reliable. GET is faster; use it only for static pages or API endpoints that need no JavaScript. POST and PUT send the body parameter."
    },
    "country": {
      "enum": [
        "NA",
        "EU",
        "APAC",
        "LATAM",
        "MEA",
        "US",
        "GB",
        "CA",
        "AU",
        "DE",
        "FR",
        "JP",
        "CN",
        "IN",
        "BR",
        "MX",
        "ES",
        "IT",
        "NL",
        "SE",
        "NO",
        "DK",
        "FI",
        "PL",
        "RU",
        "KR",
        "SG",
        "HK",
        "TW",
        "TH",
        "VN",
        "ID",
        "MY",
        "PH",
        "ZA",
        "AE",
        "SA",
        "IL",
        "TR",
        "AR",
        "CL",
        "CO",
        "NZ",
        "IE",
        "CH",
        "AT",
        "BE",
        "PT",
        "CZ",
        "RO",
        "HU",
        "GR",
        "UA",
        "EG",
        "RS",
        "AM",
        "AL",
        "BG",
        "CY",
        "DZ",
        "IQ",
        "KE",
        "NG",
        "PA",
        "SK",
        "TT",
        "LK",
        "AG"
      ],
      "type": "string",
      "description": "Where to execute the crawl FROM (device geographic placement). This controls the device's physical location, NOT the content topic — a crawl from Germany fetches the same URL but may see region-specific content (e.g., cookie banners, localized pricing). Accepts meta-regions (NA, EU, APAC, LATAM, MEA) or ISO country codes (US, DE, JP). PREFER meta-regions — they give the placement algorithm more flexibility to find available devices. Use specific country codes only when you need exact country-level placement (e.g., to see local pricing, comply with regional regulations, or access geo-restricted content)."
    },
    "retries": {
      "type": "number",
      "description": "Number of speculative retries (default: 2, max: 3). When > 0, a new attempt starts every 7s using a separate device session. First success wins. Default of 2 means up to 3 concurrent sessions per call. Set to 0 for a single attempt."
    },
    "device_type": {
      "enum": [
        "mobile",
        "desktop"
      ],
      "type": "string",
      "description": "Device type to use (default: no constraint)"
    },
    "timeout_sec": {
      "type": "number",
      "description": "Timeout in seconds (default: 60, max: 300). For CRAWL_FULL_PAGE, values below 60 are silently raised to 60."
    }
  }
}
crawl_fetch annotations
{
  "readOnlyHint": true,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": false
}
resource_fetch
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Fetch the full content of an MCP resource URI. Use this when you need to read the actual content from a prior tool result and cannot resolve resource URIs natively (most hosted AI environments do not yet support native MCP resource fetching). This tool accepts crawl:// URIs from crawl_fetch responses, sweep:// URIs from verify results, and sitemaps:// URIs from sitemaps_generate results. For crawl_fetch, responses include a summary for quick analysis, plus crawl:// resource URIs pointing to the full content in markdown and HTML formats. When the summary is sufficient, you do not need this tool. When you need the complete page text — to extract specific data, parse tables, read full articles, etc. — pass the resource URI here to get the full content. For crawl_fetch results, use the markdown resource URI unless you specifically need raw HTML structure. Markdown is significantly more compact and easier to work with. For verify results, pass a sweep:// screenshot URI to retrieve the screenshot for visual inspection. For sitemaps_generate results, pass a sitemaps:// URI to read the llms.txt content for a domain or section.

resource_fetch input schema
{
  "type": "object",
  "required": [
    "uri"
  ],
  "properties": {
    "uri": {
      "type": "string",
      "description": "A crawl://, sweep://, or sitemaps:// resource URI from a prior tool response (e.g. crawl://jobId/markdown, sweep://sweepId/region/jobIndex/screenshot, or sitemaps://domainId/llms.txt)."
    }
  }
}
resource_fetch annotations
{
  "readOnlyHint": true,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": false
}
sweep
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Deprecated: use the verify tool instead. sweep is the old name of verify, kept so existing setups keep working, and will be removed in a later release. It takes the same inputs and returns the same output. Verify a site works: load a URL on real devices in many regions and return status, load speed (Core Web Vitals) and screenshots, plus a shareable report link. Use this after deploying a website or service to verify it is up, responsive, and performing well from different parts of the world. Loads the target URL from multiple regions simultaneously, capturing performance metrics from each check. All checks (regions x tries) run concurrently, so the total operation time is approximately equal to the timeout value. Each completed check returns Core Web Vitals (TTFB, FCP, LCP, CLS), load times, transfer size, and HTTP protocol. Screenshots are captured and available as resource links in the response for visual verification if needed, but can be ignored if you only need the metrics. A run may complete with some failed checks. Inspect the failed_jobs count and per-job error fields in the response to identify issues. If the timeout passes before every region finishes, the checks that did finish are still returned with status "partial"; each region without a completed check has a status ("no_device" when no device in that region was available, otherwise "incomplete") and an "error" saying why. The response includes a "report_url" field with a link to a human-readable report page that can be shared with others for visual review of the results.

sweep input schema
{
  "type": "object",
  "required": [
    "url"
  ],
  "properties": {
    "url": {
      "type": "string",
      "description": "Target URL to test."
    },
    "tries": {
      "type": "number",
      "description": "Number of checks per region (default: 5). All checks across all regions run concurrently."
    },
    "device": {
      "enum": [
        "mobile",
        "desktop"
      ],
      "type": "string",
      "description": "Device type (default: mobile). Options: mobile, desktop."
    },
    "regions": {
      "type": "array",
      "items": {
        "enum": [
          "NA",
          "EU",
          "APAC",
          "LATAM",
          "MEA"
        ],
        "type": "string"
      },
      "description": "Geographic regions to test from: NA (North America), EU (Europe), APAC (Asia Pacific), LATAM (Latin America), MEA (Middle East & Africa). Default: [NA, EU, APAC] — these three regions have the fastest and most reliable device pools."
    },
    "timeout": {
      "type": "number",
      "description": "Global timeout in seconds for the entire run (default: 60). All checks run concurrently, so total wall-clock time is approximately this value."
    }
  }
}
sweep annotations
{
  "readOnlyHint": true,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": false
}
verify
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Verify a site works: load a URL on real devices in many regions and return status, load speed (Core Web Vitals) and screenshots, plus a shareable report link. Use this after deploying a website or service to verify it is up, responsive, and performing well from different parts of the world. Loads the target URL from multiple regions simultaneously, capturing performance metrics from each check. All checks (regions x tries) run concurrently, so the total operation time is approximately equal to the timeout value. Each completed check returns Core Web Vitals (TTFB, FCP, LCP, CLS), load times, transfer size, and HTTP protocol. Screenshots are captured and available as resource links in the response for visual verification if needed, but can be ignored if you only need the metrics. A run may complete with some failed checks. Inspect the failed_jobs count and per-job error fields in the response to identify issues. If the timeout passes before every region finishes, the checks that did finish are still returned with status "partial"; each region without a completed check has a status ("no_device" when no device in that region was available, otherwise "incomplete") and an "error" saying why. The response includes a "report_url" field with a link to a human-readable report page that can be shared with others for visual review of the results.

verify input schema
{
  "type": "object",
  "required": [
    "url"
  ],
  "properties": {
    "url": {
      "type": "string",
      "description": "Target URL to test."
    },
    "tries": {
      "type": "number",
      "description": "Number of checks per region (default: 5). All checks across all regions run concurrently."
    },
    "device": {
      "enum": [
        "mobile",
        "desktop"
      ],
      "type": "string",
      "description": "Device type (default: mobile). Options: mobile, desktop."
    },
    "regions": {
      "type": "array",
      "items": {
        "enum": [
          "NA",
          "EU",
          "APAC",
          "LATAM",
          "MEA"
        ],
        "type": "string"
      },
      "description": "Geographic regions to test from: NA (North America), EU (Europe), APAC (Asia Pacific), LATAM (Latin America), MEA (Middle East & Africa). Default: [NA, EU, APAC] — these three regions have the fastest and most reliable device pools."
    },
    "timeout": {
      "type": "number",
      "description": "Global timeout in seconds for the entire run (default: 60). All checks run concurrently, so total wall-clock time is approximately this value."
    }
  }
}
verify annotations
{
  "readOnlyHint": true,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": false
}
video_moment
Advertised by the server during the last successful anonymous check.
Open-world

Fetch transcribed, time-stamped moments for a specific video URL. This is a CURSOR over the video pre-computed sliding-window moments (~30s windows on a ~25s grid, ~5s overlap) -- NOT a summary or sample of a time range. A call returns up to max_moments consecutive windows starting at start_s, in chronological order. To cover a long span you PAGINATE: read a page, then call again with start_s = next_start_s until has_more is false. If the video is not yet indexed, indexing starts automatically and the response tells you how long to wait. Moment text is model-generated from video frames plus verbatim ASR and may contain transcription artifacts. The response includes has_more / next_start_s for pagination and a stable moment_key per moment for dedupe. When following a video_search hit, pass its url, t0, and t1 as the url, start_s, and end_s of this tool. When include_images is set (not "none"), decoded keyframe IMAGES for each moment are returned inline as base64 ImageContent blocks, downscaled to 448px and re-encoded (WebP by default; JPEG if the server is configured with VIDEO_FRAME_FORMAT=jpeg -- the actual format is reported in the frame_format field). The frames_returned / frames_truncated / frame_format fields describe what was delivered so you can narrow scope (fewer moments, or a lower tier) for full fidelity. Frames always follow their moments in order. Only request images if you can view them.

video_moment input schema
{
  "type": "object",
  "required": [
    "url"
  ],
  "properties": {
    "url": {
      "type": "string",
      "description": "Required. Video URL (https:// auto-added)."
    },
    "end_s": {
      "type": "number",
      "description": "Upper bound of the range. <=0 (default) = a single moment at start_s; >0 = consecutive windows overlapping [start_s, end_s]."
    },
    "start_s": {
      "type": "number",
      "description": "Where to start reading / the pagination cursor (default 0)."
    },
    "max_moments": {
      "type": "number",
      "description": "PAGE SIZE -- max windows returned per call (default 5; hard cap 10). Bounds how far FORWARD you read (~max_moments x 25s); it does NOT sample the whole range -- paginate for more."
    },
    "include_images": {
      "enum": [
        "none",
        "hero",
        "summary",
        "full"
      ],
      "type": "string",
      "description": "Return decoded keyframe IMAGES for each moment inline (base64, downscaled to 448px; re-encoded as WebP by default or JPEG per server config -- check frame_format in the response for the actual format). Frames follow their moments in order. Only request images if you can view them.\n- none (default): text moments only.\n- hero: 1 anchoring frame per moment (the keyframe near its start).\n- summary: ~3 evenly-sampled frames per moment.\n- full: all available frames per moment.\nFor ANY non-none tier, the total number of frames across the whole response is capped to 8 (after per-tier selection). When the cap trims frames, frames_truncated is set -- narrow scope (fewer moments or a lower tier) for true full fidelity."
    }
  }
}
video_moment annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": false
}
video_search
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Semantic search over indexed video moments. Finds the most relevant moments (time-stamped segments) across indexed videos for a natural-language query. Each result includes the source video, the moment's start/end timestamps, a relevance score, and the moment transcript when available. Results are ordered best-first and limited to the top 10 moments. Each result's url, t0, and t1 are the exact inputs to video_moment (pass them as its url, start_s, and end_s).

video_search input schema
{
  "type": "object",
  "required": [
    "query"
  ],
  "properties": {
    "tags": {
      "type": "object",
      "properties": {},
      "description": "Optional key/value facet filters."
    },
    "query": {
      "type": "string",
      "description": "Natural-language search query."
    },
    "unique_videos": {
      "type": "boolean",
      "description": "Return one (best) result per distinct video instead of per-moment hits (default: true)."
    },
    "published_after": {
      "type": "number",
      "description": "Only include moments published at or after this unix timestamp (seconds, UTC)."
    },
    "order_by_recency": {
      "type": "boolean",
      "description": "Sort results newest-first by publish date, with relevance as the tiebreak (default: false)."
    },
    "published_before": {
      "type": "number",
      "description": "Only include moments published at or before this unix timestamp (seconds, UTC)."
    }
  }
}
video_search annotations
{
  "readOnlyHint": true,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": false
}
web_research
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Use when other fetch/search tools are blocked, rate-limited, return bot-check pages, or when you need results as a real person in a specific country or on a specific device type sees them. Searches the web with several engines (Bing, DuckDuckGo, Yahoo, plus regional engines) from real devices in real locations, and returns deduplicated results with url, title and description. suggested_countries sets where the search runs FROM, not what it is ABOUT: - Geography is the topic ('Paris hotels', 'history of the Berlin Wall') → keep it in the query and omit suggested_countries. - Geography is the perspective (what Europeans see when searching for beach holidays) → query='best beach destinations', suggested_countries=['EU']. - Both ('what Germans think about Italian food') → query='Italian food', suggested_countries=['EU']. To compare regions, make one call per region; do not combine them in one call. Deduplication can return fewer results than max_results; request 2-3x your target. Results are ordered by relevance, best first: pages ranked highly by several engines or regions come first. Each result has a "score" and the engine/country "sources" that returned it.

web_research input schema
{
  "type": "object",
  "required": [
    "query"
  ],
  "properties": {
    "query": {
      "type": "string",
      "description": "Search query terms. Include geographic terms only when they describe the TOPIC you are searching for (e.g., 'Tokyo tourist spots,' 'Brazilian coffee'). Do NOT add geographic terms to target a search location — use suggested_countries for that. Query language does not imply search location."
    },
    "max_results": {
      "type": "number",
      "description": "Maximum number of results to return (default: 12, max: 50). Actual count may be lower due to cross-source deduplication."
    },
    "num_sources": {
      "type": "number",
      "description": "Maximum number of countries to query (default: 5, max: 20). Each country generates sources for all eligible providers, so the actual number of provider+country combinations may be higher. When suggested_countries expands to more countries than this value, the list is sampled down using daylight-aware selection. The server independently sizes the fan-out based on max_results; this parameter controls geographic diversity, not total source count."
    },
    "suggested_countries": {
      "type": "array",
      "items": {
        "enum": [
          "NA",
          "EU",
          "APAC",
          "LATAM",
          "MEA",
          "US",
          "GB",
          "CA",
          "AU",
          "DE",
          "FR",
          "JP",
          "CN",
          "IN",
          "BR",
          "MX",
          "ES",
          "IT",
          "NL",
          "SE",
          "NO",
          "DK",
          "FI",
          "PL",
          "RU",
          "KR",
          "SG",
          "HK",
          "TW",
          "TH",
          "VN",
          "ID",
          "MY",
          "PH",
          "ZA",
          "AE",
          "SA",
          "IL",
          "TR",
          "AR",
          "CL",
          "CO",
          "NZ",
          "IE",
          "CH",
          "AT",
          "BE",
          "PT",
          "CZ",
          "RO",
          "HU",
          "GR",
          "UA",
          "EG",
          "RS",
          "AM",
          "AL",
          "BG",
          "CY",
          "DZ",
          "IQ",
          "KE",
          "NG",
          "PA",
          "SK",
          "TT",
          "LK",
          "AG"
        ],
        "type": "string"
      },
      "description": "Where to search FROM (the searcher's geographic perspective), NOT what to search ABOUT. When omitted, the server automatically selects optimal countries for broad global coverage — this is the correct default for most queries that do not require a specific regional perspective. Only set this parameter when you need results from a particular region's point of view. Accepts meta-regions (NA, EU, APAC, LATAM, MEA) or ISO country codes. ALWAYS PREFER meta-regions for regional perspectives — they give the scheduler more flexibility and better cache hit rates. Only use specific country codes when the query demands country-level precision (e.g., country-specific law, language-specific content, or data that varies within a region). Do NOT mix meta-regions and country codes in a single call."
    }
  }
}
web_research annotations
{
  "readOnlyHint": true,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": false
}

Prompts

Not advertised

No prompt definitions available.

Resources

0 advertised

Crawl Page Content

Advertised by the server during the last successful anonymous check.

On-demand page content from a crawl job. Use the resource link returned by crawl_fetch.

Crawl Page Content URI template
crawl://{jobId}/html
Crawl Page Markdown

Advertised by the server during the last successful anonymous check.

Extracted markdown content from a crawl job. The cache key is provided in the resource link returned by crawl_fetch.

Crawl Page Markdown URI template
crawl://{cacheKey}/markdown

MIME type: text/markdown

Crawl Page Screenshot

Advertised by the server during the last successful anonymous check.

On-demand screenshot from a crawl job. Use the resource link returned by crawl_fetch when TAKE_SCREENSHOT capability is requested.

Crawl Page Screenshot URI template
crawl://{jobId}/viewport

MIME type: image/png

Sweep Screenshot

Advertised by the server during the last successful anonymous check.

On-demand screenshot from a verify check. Use the resource links returned by the verify tool.

Sweep Screenshot URI template
sweep://{sweepId}/{region}/{jobIndex}/screenshot

MIME type: image/png

30-day availability

Aggregated from read-only remote checks; this is not a tool-execution or security guarantee.

Successful checks
1 of 1 (100%)
Average latency
484 ms
95th percentile latency
484 ms

Maintenance history

Public check and source-refresh events. Editorial and ownership records remain private.

  • · probe · passed · 484 ms · metadata changed · 7 tool(s), 0 resource(s), 4 resource template(s)

Connect from your client

Each snippet registers the same endpoint; pick the client you use.

This server is operated by the named third party. Listing and endpoint checks are not an endorsement or a security audit. Review the operator's permissions, terms, and data handling before connecting. How listings are checked and corrected.

Claude Code

Run this once in a terminal. It registers the remote server. Use --scope project to write .mcp.json for the repo.
Claude Code configuration
claude mcp add --transport http uprock-mcp https://mcp.uprock.ai/mcp

Codex

Run this once. Codex stores MCP servers in ~/.codex/config.toml (or .codex/config.toml in a trusted project).
Codex configuration
codex mcp add uprock-mcp --url https://mcp.uprock.ai/mcp

Cursor

Merge this server into .cursor/mcp.json in your project, then enable uprock-mcp in your MCP settings.
Cursor configuration
{
  "mcpServers": {
    "uprock-mcp": {
      "url": "https://mcp.uprock.ai/mcp"
    }
  }
}

Cline

Merge this into cline_mcp_settings.json (Cline → MCP Servers → Configure).
Cline configuration
{
  "mcpServers": {
    "uprock-mcp": {
      "type": "streamableHttp",
      "url": "https://mcp.uprock.ai/mcp",
      "disabled": false
    }
  }
}

VS Code

Merge this server into .vscode/mcp.json. Use MCP: List Servers to start uprock-mcp and inspect its tools.
VS Code configuration
{
  "servers": {
    "uprock-mcp": {
      "type": "http",
      "url": "https://mcp.uprock.ai/mcp"
    }
  }
}

Gemini CLI

Run this once. It writes .gemini/settings.json in the current project; pass --scope user for ~/.gemini/settings.json.
Gemini CLI configuration
gemini mcp add --transport http uprock-mcp https://mcp.uprock.ai/mcp

Claude Desktop

Open Claude Settings > Connectors > Add custom connector, enter this server URL and enable it for the conversation. This is a manual remote-connector handoff, not a desktop JSON configuration.
Claude Desktop configuration
https://mcp.uprock.ai/mcp

Windsurf

Merge this into ~/.codeium/windsurf/mcp_config.json, then refresh MCP in Cascade. Windsurf remote servers use serverUrl, not url.
Windsurf configuration
{
  "mcpServers": {
    "uprock-mcp": {
      "serverUrl": "https://mcp.uprock.ai/mcp"
    }
  }
}

Let your agent find its tools

Find servers like UpRock MCP from your agent. Add Koskamo once to search the index for endpoints, access requirements, and client setup. Public discovery needs no key.

Do you run UpRock MCP?

Prove ownership with a DNS record, a well-known file, or your Official MCP Registry entry, and your edits publish immediately. Proofs are re-checked weekly; admins can still hide or remove a listing.

Claim this listing