About wikipedia-mcp-server
wikipedia-mcp-server exposes Wikipedia search and article-reading functions to MCP clients. It supports language editions, targeted section reads, and nearby-page discovery.
Key features
- 01Search Wikipedia articles
- 02Read summaries and full articles
- 03Retrieve selected sections
- 04Find geotagged nearby pages
- 05List article language editions
Use cases
- 01Find sources and background on a topic
- 02Read only a relevant article section
- 03Explore pages near geographic coordinates
MCP support
It provides six Wikipedia tools to MCP clients, including search, article and section reads, nearby-page search, and language lookup. It supports STDIO and Streamable HTTP.
Configuration
Remote servers need no local install. Pick your client, then copy the config or install in one click.
https://wikipedia.caseyjhand.com/mcpclaude mcp add --transport http cyanheads-wikipedia https://wikipedia.caseyjhand.com/mcp{"mcpServers":{"cyanheads-wikipedia":{"type":"http","url":"https://wikipedia.caseyjhand.com/mcp"}}}Open in Cursor{"servers":{"cyanheads-wikipedia":{"type":"http","url":"https://wikipedia.caseyjhand.com/mcp"}}}Open in VS Code{"mcpServers":{"cyanheads-wikipedia":{"type":"http","url":"https://wikipedia.caseyjhand.com/mcp"}}}{"mcpServers":{"cyanheads-wikipedia":{"serverUrl":"https://wikipedia.caseyjhand.com/mcp"}}}Run commands in a terminal; paste JSON into the client’s MCP config and restart. Servers that need sign-in will prompt on first connect.
Tools
6| Parameter | Type | Required | Description |
|---|---|---|---|
| limit | integer | No | Maximum number of results to return per page (default 10, max 50). Must be a positive integer. |
| query | string | Yes | Search query (e.g. "Python programming language"). Must not be empty. |
| offset | integer | No | Result offset for pagination (default 0). Pass the nextOffset from a previous response to fetch the next page; limit still governs the per-page size. An offset past the total match count returns an empty result array, not an error. Wikipedia serves no result past 10,000, so an offset at or beyond that fails — narrow the query instead. |
| language | string | No | Wikipedia language edition code (default "en"). Examples: "fr", "de", "ja". |
Details
From the project README@cyanheads/wikipedia-mcp-server
Search Wikipedia articles, read summaries and full text, target sections, find nearby pages, and list language editions via MCP. STDIO or Streamable HTTP.
Public Hosted Server: https://wikipedia.caseyjhand.com/mcp
Overview
Wikipedia in any language edition. Search articles, read summaries or just the sections you need, find geotagged pages near a coordinate, and list an article's language editions.
Tools
| Tool | Description |
|---|---|
wikipedia_search_articles | Full-text search across Wikipedia, returning ranked results with short descriptions, Wikidata QIDs, plain-text snippets, and page IDs, plus Wikipedia's spelling suggestion. |
wikipedia_get_summary | Short summary for any article — plain text, Wikidata QID, description, thumbnail URL, page type, canonical URL, revision, and coordinates. |
wikipedia_get_article | Full article or a targeted section as clean plain text, with section markers preserved, the canonical URL, and the revision it was read from. |
wikipedia_get_sections | Table of contents with section_index values for targeted section reads. |
wikipedia_search_nearby | Geotagged Wikipedia articles within a radius of a WGS 84 coordinate, sorted by distance, with short descriptions and Wikidata QIDs. |
wikipedia_get_languages | All language editions available for an article, with titles and URLs, or just the editions you ask for. |
Capability reference
wikipedia_search_articles tool
- Free-text
query(an empty one fails withempty_query), positive integerlimit(default 10, clamped to 50), andoffsetpaging, passing back enrichmentnextOffset. Only a clamped call carriesrequestedLimit,appliedLimit, and a clamp notice. Wikipedia serves no result past the 10,000th: anoffsetat or beyond it fails withoffset_too_large, and a page ending on that window carries enrichmenttruncated - CirrusSearch operators include
incategory:"1648 treaties",morelike:Peace of Westphalia,intitle:Python,hastemplate:Infobox, andinsource:Python(support depends on the installation).sortdefaults torelevance; alternatives arelast_edit_desc,create_timestamp_desc,incoming_links_desc, andtitle_natural_asc. Enrichment echoessort; keep it andqueryunchanged when paging - Each result carries a plain-text snippet, page ID, word count, and — when the article has them — its short
descriptionand Wikidata QID (wikibase_item); enrichmentsuggestioncarries Wikipedia's spelling correction (einstien→einstein) - Invalid or over-complex
insource:/…/andintitle:/…/regexes fail once withinvalid_query, theupstreamCode, and guidance to correct or simplify the regex or remove the operator. A busy regex search remains retryable
wikipedia_get_summary tool
- Takes a
title; returns the REST summary extract — a fragment from the start of the lead (wikipedia_get_articlewithsection_index: 0reads the whole lead) — plus the short description, thumbnail URL, Wikidata QID (wikibase_item), and, for a geotagged article,latitude/longitudeto pass straight towikipedia_search_nearby page_typediscriminatesstandard/disambiguation/no-extract(ondisambiguation, re-query withwikipedia_search_articles);url,revision_id, andlast_modifiedname the revision read, and?oldid=<revision_id>is a permanent link to it- An existing page without a summary extract succeeds with metadata, an empty
extract, and guidance to open the canonical URL or trysection_index: 0. Namespace pages may contain documentation rather than article prose. An empty description is absent; a missing title still fails withnot_found
wikipedia_get_article tool
- Without
section_index: the full article with== Section ==markers, or a section outline (truncated: true) when it exceedsWIKIPEDIA_ARTICLE_OVERFLOW_BYTES(default 80,000 bytes). With asection_indexfromwikipedia_get_sections(0is the lead): that section plus its nested subsections - Outline entries include verified
section_indexvalues where available, including 0 for the lead. Ambiguous or unindexed headings retain the section-list fallback. TOC verification gets one short attempt; unavailable verification is disclosed - Redirects expose
redirected_fromand, for a section target,redirect_section. A full read remains full and includes targeted-read guidance; an explicitsection_index, including 0, takes precedence - Every read returns
urlandrevision_id(?oldid=<revision_id>is a permanent link to the text read); a full read, outline included, also returnslast_modified. WithWIKIPEDIA_BASE_URLset, a section read omitsurl - Section reads render phylogenetic clade trees as fenced, indented branches, pairing each row’s label with its leaf and preserving unnamed forks. An unparseable tree leaves
[table omitted: unparseable clade]; trees have notable_index - Section reads also carry data tables as pipe-delimited rows and infoboxes as
label: valuelines, which the full-article extract strips; a table over 40,000 rendered bytes leaves a[table omitted: N rows (table T)]marker. Passtable_index: Twith the section to read that table in complete row pages, then follownext_cursorascursorwith the same inputs. Continuations read the first page’s revision; caption and header appear once. Each page's table text fits 40,000 UTF-8 bytes on both surfaces, except an indivisible oversized row or first-page caption/header returned alone withoversized_row: true
wikipedia_get_sections tool
- Takes a
title; returns section titles, heading levels, hierarchical numbering (e.g."2.1"), and thesection_indexto pass towikipedia_get_article— the first entry is the lead (index: 0, titledIntroduction) - Heading titles use the article renderer’s script, formula, whitespace and single-pass entity normalization, so
CO₂stays identical across the section list, article reads and verified outline entries - Fails with
no_sectionson a stub or very short article — read it withwikipedia_get_articleinstead - Redirect aliases expose
redirected_fromand optionalredirect_section;redirect_section_indexappears only when a unique anchor matches a real numeric TOC index
wikipedia_search_nearby tool
latitude−90…90 /longitude−180…180 (WGS 84),radius_meters10–10,000 (default 1000), and positive integerlimit(default 10, clamped to 500), with no pagination pastlimit; enrichmenttruncatedflags more matches thanlimitallowed — at 500, Wikipedia's ceiling, sweep narrower radii instead. Only a clamped call carriesrequestedLimit,appliedLimit, and a clamp notice- Returns articles sorted by
distance_meters, with coordinates, shortdescription, and Wikidata QID (wikibase_item). Each is placed by the article's own GeoData coordinate tag, not its Wikidata item's coordinate, so a mistagged article appears where the tag puts it
wikipedia_get_languages tool
- Takes a
title; returns each edition'slanguage_code,edition_code, article title, and URL, plussource_title, the resolved title. Passedition_code— notlanguage_code— aslanguageon other tools; the two can differ (gswvsals) editionsnarrows the list to the codes asked for: codes with no article come back undermissing, andtotal_languagesstays the unfiltered count. Fails withno_other_languageswhen the article has no translations; a filter matching nothing is an empty list, not a failure
Features
Built on @cyanheads/mcp-ts-core: stdio and Streamable HTTP transports, pluggable auth (none / jwt / oauth), swappable storage (in-memory, filesystem, Supabase, Cloudflare KV/R2/D1), structured logging with optional OpenTelemetry tracing.
Wikipedia-specific:
- Dual API integration — MediaWiki REST API (
/api/rest_v1/) for summaries, Action API (/w/api.php) for search, full text, sections, geo search, and language links - Retry and backoff on every required request, including the transient refusals (search too busy, rate-limited, read-only) the Action API returns inside an HTTP 200 body, with an upstream
Retry-Afterhonored and each request's retries bounded at 30 s. The best-effort description lookup on search results gets one short attempt;User-Agentheader per Wikimedia API policy - Every read path renders HTML through one renderer to the same plain-text shape —
== Heading ==markers, one list item per line, superscripts kept, code fenced: the full article from the Action API's HTML extract, a section from the parser's own HTML for that section, the summary from the RESTextract_html. A section read additionally carries data tables, infoboxes, and the lists inside layout tables, none of which the extract carries - Per-call
languageparameter on every tool (defaulten) — all Wikipedia language editions accessible in a single session; every title read follows redirects - Language validation against a live edition registry built from the MediaWiki
action=sitematrixendpoint (cached 24h) — catches structurally valid but nonexistent editions before they cause timeouts
Agent-friendly output:
page_typeon summaries discriminatesstandard/disambiguation/no-extract— no string parsing neededwikibase_item(Wikidata QID) on summaries and on search and nearby results enables direct cross-referencing with wikidata-mcp-server- Article text, snippets, and titles are backslash-escaped on the way into the markdown
content[]render, so an article that writes about markup or markdown syntax reads as itself instead of being interpreted by the client;structuredContentcarries the same text unescaped. Fenced code blocks and table-row delimiters pass through unescaped, while table cells stay escaped section_indexon table-of-contents entries links directly to the targeted-read parameter onwikipedia_get_article, index 0 included- Titles MediaWiki cannot name a page with —
< > [ ] { }, the|multi-title separator, percent escapes, magic tildes, relative paths — are refused before any request, withinvalid_title; a trailing#fragmentis accepted and resolves normally - Recovery hints on every error type — callers get actionable next steps (e.g., "use
wikipedia_search_articlesto find the correct title")
Getting started
Public Hosted Instance
A public instance is available at https://wikipedia.caseyjhand.com/mcp — no installation required. Point any MCP client at it via Streamable HTTP:
{
"mcpServers": {
"wikipedia-mcp-server": {
"type": "streamable-http",
"url": "https://wikipedia.caseyjhand.com/mcp"
}
}
}
Self-Hosted / Local
Add the following to your MCP client configuration file.
{
"mcpServers": {
"wikipedia-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/wikipedia-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
Or with npx (no Bun required):
{
"mcpServers": {
"wikipedia-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/wikipedia-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
Or with Docker:
{
"mcpServers": {
"wikipedia-mcp-server": {
"type": "stdio",
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "MCP_TRANSPORT_TYPE=stdio",
"ghcr.io/cyanheads/wikipedia-mcp-server:latest"
]
}
}
}
For Streamable HTTP, set the transport and start the server:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcp
Prerequisites
- Bun v1.4.0 or higher (or Node.js v24+).
- No API keys required — Wikipedia's API is public.
Installation
- Clone the repository:
git clone https://github.com/cyanheads/wikipedia-mcp-server.git
- Navigate into the directory:
cd wikipedia-mcp-server
- Install dependencies:
bun install
- Configure environment (optional):
cp .env.example .env
# edit .env if you want to customize WIKIPEDIA_USER_AGENT or logging
Configuration
| Variable | Description | Default |
|---|---|---|
WIKIPEDIA_USER_AGENT | User-Agent header sent with every Wikimedia API request. Customize for your deployment. | wikipedia-mcp-server/0.2.8 (https://github.com/cyanheads/wikipedia-mcp-server) |
WIKIPEDIA_BASE_URL | Optional single-instance override. Unset (default): compose per-language hosts, language selects the edition per call. Set to a full base URL (e.g. a private MediaWiki mirror): route every call at that one fixed host — language no longer varies it. | (unset) |
WIKIPEDIA_ARTICLE_OVERFLOW_BYTES | Byte budget above which a full-article read (wikipedia_get_article without section_index) returns a section outline instead of the full text. Tuned for this domain — ordinary articles stay whole; only genuine mega-articles (World War II ~86 KB, United States ~94 KB) outline. Section-targeted reads are never affected. | 80000 |
MCP_TRANSPORT_TYPE | Transport: stdio or http. | stdio |
MCP_HTTP_PORT | Port for HTTP server. | 3010 |
MCP_SESSION_MODE | HTTP session mode: stateless, stateful, or auto (which resolves to stateful). The Docker image ships stateless. | auto |
MCP_AUTH_MODE | Auth mode: none, jwt, or oauth. | none |
MCP_LOG_LEVEL | Log level (RFC 5424). | info |
LOGS_DIR | Directory for log files (Node.js only). | <project-root>/logs |
LOG_TOOL_FAILURE_PAYLOADS | Log each failed tool call's arguments and result, redacted by key name and capped at LOG_TOOL_FAILURE_PAYLOAD_MAX_BYTES (default 16384). A secret inside a free-form value is not redacted. | false |
OTEL_ENABLED | Enable OpenTelemetry instrumentation (spans, metrics, completion logs). | false |
See .env.example for the full list of optional overrides.
Running the server
Local development
-
Build and run:
# One-time build bun run rebuild # Run the built server bun run start:stdio # or bun run start:http -
Run checks and tests:
bun run devcheck # Lint, format, typecheck, security bun run test # Vitest test suite bun run lint:mcp # Validate MCP definitions against spec
Docker
docker build -t wikipedia-mcp-server .
docker run --rm -p 3010:3010 wikipedia-mcp-server
The Dockerfile defaults to HTTP transport, stateless session mode, and logs to /var/log/wikipedia-mcp-server. OpenTelemetry peer dependencies are installed by default — build with --build-arg OTEL_ENABLED=false to omit them.
Project structure
| Directory | Purpose |
|---|---|
src/index.ts | createApp() entry point — registers tools and inits the Wikipedia service. |
src/config | Server-specific environment variable parsing and validation with Zod. |
src/mcp-server/tools | Tool definitions (*.tool.ts) — one file per tool. |
src/services/wikipedia | WikipediaService — REST API + Action API client with retry/backoff and language validation. |
tests/ | Unit and integration tests mirroring src/. |
Development guide
See CLAUDE.md for development guidelines and architectural rules. The short version:
- Handlers throw, framework catches — no
try/catchin tool logic - Use
ctx.logfor request-scoped logging,ctx.statefor tenant-scoped storage - Register new tools in
src/mcp-server/tools/definitions/index.ts - Wrap external API calls: validate raw → normalize to domain type → return output schema; never fabricate missing fields
Contributing
Issues are welcome. Run checks and tests before submitting:
bun run devcheck
bun run test
License
Apache-2.0 — see LICENSE for details.
Comments
New to MCP?
From what the protocol is to installing your first server, these answers cover most first questions.
An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.