A side-by-side look at the Agentfetch MCP and Opentk MCP MCP servers: transport, auth, tools, quality signals, and the config to install either one in Claude, Cursor, Windsurf or VS Code.
Verdict: choose Agentfetch MCP for search & data extraction work as a local process; choose Opentk MCP for search & data extraction as a local process. You can also run both side by side in one mcpServers block.
JINA_API_KEY, FIRECRAWL_API_KEY, REDIS_URL, CACHE_TTL_SECONDS.fetch_url, estimate_tokens, fetch_multiple.get_overview, birthdays_today, list_persons.Rows where the two servers differ are marked.
| Spec | ||
|---|---|---|
| Category | Search & Data Extraction | Search & Data Extraction |
| Quality signal | 57/100 · Good | 60/100 · Good |
| Install command | Confirmed | Confirmed |
| Transport | Local subprocess (stdio) | Local subprocess (stdio) |
| Auth | API key required | No auth required |
| Pricing | Free | Free |
| Required env vars | JINA_API_KEYFIRECRAWL_API_KEYREDIS_URLCACHE_TTL_SECONDS | None listed |
| Verified owner | Community listing | Community listing |
| GitHub stars | 3 | 23 |
| Directory activity | 4 views 0 installs 0 upvotes | 1 views 0 installs 0 upvotes |
| Tools | 4 | 17 |
| Full listing | View Agentfetch MCP | View Opentk MCP |
fetch_urlFetch any URL and return clean, LLM-ready Markdown with token count, metadata, and 6h caching.
WHEN TO USE:
- You have a specific URL whose content you need.
- You want to cap response size to stay inside your context window.
- You want repeat fetches to be cheap (cache hits ≈ $0.0001).
- The URL might be JS-rendered, a PDF, or behind a paywall — this tool
auto-routes to the right fetcher (Trafilatura → Jina → FireCrawl → PDF).
WHEN NOT TO USE:
- You don't know which URL to fetch — use search_and_fetch instead.
- You have many URLs to fetch — use fetch_multiple instead.
Args:
url: The URL to fetch.
max_tokens: Hard cap on response size. Default unlimited. Pass this
if you're tight on context budget — cheaper than over-fetching.
format: "markdown" (default — recommended), "text", or "json".
use_cache: True returns a cached copy if one exists (≤6h old).
Pass False only when freshness matters (live news, prices).
Returns:
{
"url": str, "success": bool, "markdown": str,
"metadata": {title, author, published_date, domain, word_count,
token_count, reading_time_seconds, content_type, language},
"cache": {hit, cached_at, expires_at},
"fetch_info": {fetcher_used, fetch_time_ms, cost_credits},
"error": str | None
}
estimate_tokensEstimate token count of a URL's content WITHOUT fetching the body.
WHEN TO USE:
- You're considering fetching a URL but unsure if it fits your remaining
context window. This call is ~10x cheaper than a full fetch.
- You want to triage a list of candidate URLs before deciding which to
actually retrieve.
IMPORTANT: Many servers omit Content-Length on dynamic / chunked
responses. When that happens, this tool returns confident=false and
estimated_tokens=null. In that case, call fetch_url with a max_tokens
cap instead of trusting the estimate.
Args:
url: The URL to estimate.
Returns:
{
"url": str, "success": bool,
"estimated_tokens": int | null,
"byte_size": int | null,
"content_type": str,
"confident": bool,
"note": str
}
fetch_multipleFetch up to 20 URLs concurrently. Each result is the same shape as fetch_url.
WHEN TO USE:
- You have a list of URLs (search results, links from a doc, sitemap)
and want them retrieved in parallel rather than one at a time.
Args:
urls: 1–20 URLs. Larger batches: split into multiple calls.
max_tokens_each: Per-result cap. Apply this to keep total response
inside your context budget — total ≈ len(urls) * max_tokens_each.
use_cache: True for cache-aware fetching (default).
Returns:
{"count": int, "results": [<fetch_url shape>, ...]}
search_and_fetchWeb search + fetch top results in one call.
WHEN TO USE:
- You have a research question, not specific URLs. E.g. "what's the
latest on X", "find docs for Y library", "recent news about Z".
- You'd otherwise have to call a search tool, parse results, then call
fetch — this collapses that into one round-trip.
Args:
query: Search query (2–500 chars).
num_results: Top N to fetch (1–10, default 3).
max_tokens_each: Per-result cap (default 2000).
Returns:
{"query": str, "count": int, "results": [<fetch_url shape>, ...]}
get_overviewProvides a comprehensive overview of recent parliamentary activities, including the most recent documents and MPs celebrating birthdays today. The response contains structured data with two main sections: 'recentDocuments' (listing the latest parliamentary documents with their IDs, titles, types, dates, and URLs) and 'birthdays' (listing MPs celebrating birthdays today). The results are paginated with 10 documents per page. The tool supports iterative pagination - check the pagination.hasMoreDocuments field in the response to determine if additional pages are available. The response includes pagination information showing the current page, whether more documents are available, and the total number of documents retrieved. Applicable when general information about recent parliamentary activities is needed.birthdays_todayLists all Members of Parliament celebrating their birthday today, including their names, political parties, and birth dates. The response is a JSON array where each entry contains the MP's ID, name, party affiliation, and other details. This tool takes no parameters as it always returns today's birthdays. Applicable when information about MPs' birthdays is needed.list_personsProvides a complete directory of current Members of Parliament with their IDs, names, titles, party affiliations, and faction memberships. The response is a JSON array where each entry contains an MP's full details including unique MP IDs that can be referenced by other tools. This tool takes no parameters as it returns all current MPs. Applicable when comprehensive information about all MPs is needed or when analyzing the composition of parliament by party.search_tkPerforms a comprehensive search across all parliamentary data including documents, activities, and cases. Returns results matching the provided keyword or phrase. Use this for general searches when you need information on any topic discussed in parliament, regardless of document type or context. Search syntax: Searching for 'Joe Biden' finds documents containing both 'Joe' and 'Biden' anywhere in the text. Searching for "Joe Biden" (with quotes) finds only documents where these words appear next to each other. Searching for 'Hubert NOT Bruls' finds documents containing 'Hubert' but not 'Bruls'. The capital letters in 'NOT' are important. You can also use 'OR' and 'NEAR()' operators.search_tk_filteredPerforms a search within a specific category of parliamentary data, allowing results to be limited to only documents, activities, or cases. Returns paginated results sorted by date (most recent first). Search syntax supports: keyword searches ('Joe Biden' finds both terms), exact phrase searches ("Joe Biden" with quotes finds the exact phrase), exclusion ('Hubert NOT Bruls' excludes documents with 'Bruls'), and boolean operators ('OR', 'NEAR()'). Results can be returned in 'full' or 'summary' format.Paste either block (or both) into your client config, e.g. claude_desktop_config.json or ~/.cursor/mcp.json. We only show a config when the install command is confirmed.
{
"mcpServers": {
"bch1212-agentfetch-mcp": {
"command": "uvx",
"args": [
"agentfetch-mcp"
],
"env": {
"JINA_API_KEY": "YOUR_JINA_API_KEY_HERE",
"FIRECRAWL_API_KEY": "YOUR_FIRECRAWL_API_KEY_HERE",
"REDIS_URL": "YOUR_REDIS_URL_HERE",
"CACHE_TTL_SECONDS": "YOUR_CACHE_TTL_SECONDS_HERE"
}
}
}
}
{
"mcpServers": {
"r-huijts-opentk-mcp": {
"command": "npx",
"args": [
"-y",
"@r-huijts/opentk-mcp"
]
}
}
}
get_photoRetrieves the official portrait photograph of a Member of Parliament. Returns the image as a binary resource that can be displayed or saved. Use this when you need to include a visual representation of an MP in reports, presentations, or profiles.get_document_detailsRetrieves metadata about a parliamentary document in a structured JSON format, without downloading the actual document content. Returns information including title, type, document number, dates, version number, and links to both the PDF version and the official Tweede Kamer webpage.get_document_linksConverts document URLs into clickable markdown-formatted links. This tool takes either a direct PDF link or a Tweede Kamer webpage link and returns them as properly formatted clickable links.get_committeesRetrieves a list of all parliamentary committees with their IDs, names, and URLs. The response is a JSON array where each entry represents a committee with its unique identifier and name. Committees are specialized groups of MPs that focus on specific domains like defense, healthcare, or finance. This tool takes no parameters as it returns all active committees.get_committee_detailsRetrieves detailed information about a specific parliamentary committee, including its members, recent activities, and description. This provides deeper insight into the committee's composition, leadership roles, and recent work. Use this when you need comprehensive information about a particular committee's structure and activities.get_upcoming_activitiesRetrieves a list of upcoming parliamentary activities including debates, committee meetings, and other events. The response contains a structured JSON object with both a chronological list of activities and activities grouped by date. Each activity includes details like date, time, location, committee, type, and a URL for more information. The results are sorted by date with the most imminent activities first. The optional 'limit' parameter controls the number of results returned (default: 20, max: 100).get_voting_resultsRetrieves recent voting results on parliamentary motions and bills. The response contains a structured JSON object with voting results sorted by date (newest first). Each result includes detailed information such as the title of the motion/bill, the date of the vote, the submitter, whether it was accepted or rejected, the vote counts (for/against), and which political parties voted for or against. The 'limit' parameter controls the number of results (default: 20, max: 100) and 'format' parameter allows choosing between 'full' or 'summary' format. The 'summary' format provides a more structured representation with renamed fields, while both formats include complete party voting information.