runeberg-mcp
This MCP server lets you research historical Nordic people, families, and places by searching and reading digitized literature from Project Runeberg.
Global full-text search across all digitized works via
runeberg_search, with automatic historical spelling expansion and optional user-provided spelling variants.Read page text from any work via
runeberg_read_page, using either a full URL or work slug plus page number, with cleaned OCR/proofread content and links to facsimile images.Inspect work metadata via
runeberg_get_work_info, including publication details and table of contents/chapter/lemma indexes.Targeted in-work search (as described in the README) for fuzzy/lemma matching within alphabetical encyclopedias and biographical works.
CLI usage for the same workflows:
search,in-work,read, andinfocommands for terminal-based research.
Provides full-text search of Projekt Runeberg content using DuckDuckGo as the default privacy-respecting search backend, requiring no API keys.
Supports Google Custom Search JSON API for site-restricted searches of runeberg.org, enabling higher-volume or specialized search setups.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@runeberg-mcpwhat is the table of contents for Strindberg's Dödsdansen?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Runeberg MCP 📖
A Model Context Protocol (MCP) server and CLI tool for researching historical people, noble families, and places across digitized Nordic literature, encyclopedias, and archives on Projekt Runeberg.
Project Runeberg has been publishing free electronic editions of classic Nordic literature out of copyright since 1992. It is a treasure trove for genealogy and local history, containing monumental works like:
karlxiioff: Karl XII:s officerare. Biografiska anteckningar (Adam Lewenhaupt)sbh: Svenskt biografiskt handlexikon (Hofberg et al.)anrep/elgenst: Svenska adelns ättar-taflor (Gabriel Anrep / Gustaf Elgenstierna)rosenberg: Geografiskt-statistiskt handlexikon öfver Sverige (C.M. Rosenberg – all Swedish villages, farms, and parishes)hgsl: Historiskt-geografiskt och statistiskt lexikon öfver Sverigenf: Nordisk familjebok (all editions)
✨ Features
🔎 Smart Global Search (
runeberg_search): Full-text search across all digitized works with automatic historical spelling expansion and support for caller/LLM-provided spelling variants (variants).🎯 In-Work Lemma Bisection & Fuzzy Search (
runeberg_search_in_work): Instantly locates candidate pages in alphabetical encyclopedias (e.g. searching for Hilpershausen finds Hilperhaussen on page 297 of Karl XII:s officerare with 92% similarity).📄 Page Reader with Context Window (
runeberg_read_page): Extracts clean OCR/proofread text with links to original facsimile images. Supportscontext_pagesto read across page breaks seamlessly.📚 Work & Chapter Inspector (
runeberg_get_work_info): Retrieves metadata, publication details, and full chapter/lemma index.⚡ Zero-Config by Default: Built-in multi-engine search (
ddgs) requiring no API keys or setup.🚀 Optional Google Custom Search API: Set
GOOGLE_API_KEYandGOOGLE_CSE_IDto use Google's official API.
Related MCP server: DHLAB MCP Server
🛠️ Installation
Managed with modern Python packaging via uv:
git clone https://github.com/tobbaz/runeberg-mcp.git
cd runeberg-mcp
uv sync🤖 MCP Server Configuration
Add to your MCP client configuration (claude_desktop_config.json, Cursor, Antigravity, etc.):
{
"mcpServers": {
"runeberg": {
"command": "uv",
"args": [
"--directory",
"/path/to/runeberg-mcp",
"run",
"runeberg-mcp",
"serve"
]
}
}
}💻 CLI Usage
Test and research directly in your terminal:
1. Global Search (with automatic historical variants):
# Finds hits across all of Runeberg, automatically testing historical spelling shifts
uv run runeberg-mcp search "Hilpershausen"
# Or provide your own historical variants:
uv run runeberg-mcp search "Hilpershausen" -v "Hilperhaussen" -v "Hilpershusen"2. Targeted In-Work Fuzzy Search:
# Search within Karl XII:s officerare:
uv run runeberg-mcp in-work karlxiioff "Hilpershausen"
# Search within Svenskt biografiskt handlexikon:
uv run runeberg-mcp in-work sbh "Bellman"
# Search for a farm or village in Rosenberg:
uv run runeberg-mcp in-work rosenberg "Långtora"3. Read Page (with optional context window):
# Read a single page:
uv run runeberg-mcp read dasakungen 5
# Read a page and the subsequent page across page breaks:
uv run runeberg-mcp read https://runeberg.org/karlxiioff/0311.html -c 14. Inspect Work:
uv run runeberg-mcp info karlxiioff🧪 Running Tests
Run the test suite:
uv run python test_server.py📜 License
Distributed under the MIT License. Digital works hosted on Projekt Runeberg are public domain cultural heritage.
Available Tools
3 toolsruneberg_get_work_infoA
Get metadata, publication details, and table of contents/chapter list for a work in Project Runeberg.
Args:
work_slug: The work identifier (e.g. 'dasakungen', 'sbh', 'nfda', 'salmonsen').
| Name | Required | Description | Default |
|---|---|---|---|
| work_slug | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the behavioral burden. It clearly communicates a read-only 'get' operation and what the result will contain. It does not disclose potential error behavior or rate limits, but for a simple retrieval tool this is not a major gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences plus a parameter block with no filler. The purpose is front-loaded and the parameter explanation is immediately actionable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With only one required parameter and an output schema present, the description is nearly complete. The only missing context is a brief nod to the sibling tools or how to obtain a valid work_slug, but that is a minor omission for this low-complexity tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, but the description fully compensates by explaining work_slug as 'The work identifier' and giving four concrete examples. This tells the agent exactly what value to supply and what form it takes.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific verb ('Get'), a concrete resource ('a work in Project Runeberg'), and the exact information returned (metadata, publication details, table of contents/chapter list). This makes it easy to distinguish from the sibling tools runeberg_search and runeberg_read_page.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The use case is implied: after you already have a work_slug, this tool fetches overview information. However, the description does not explicitly contrast this with searching for works or reading pages, so the agent must infer when to select this tool over its siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
runeberg_read_pageA
Read the cleaned, transcribed/OCR text of a specific book page from Project Runeberg.
Args:
url_or_slug: Full page URL (e.g. 'https://runeberg.org/pvmhall/0105.html') or work slug (e.g. 'pvmhall').
page: Optional page number if slug was provided (e.g. '0105' or 105).
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | ||
| url_or_slug | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. It discloses that this is a read operation returning cleaned/OCR text and that the page parameter only applies when a slug is used. However, it does not state what happens when a slug is provided without a page, how invalid inputs are handled, or whether any normalization occurs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded: the purpose appears in the first sentence, followed by a clean Args section. Every sentence adds necessary information and there is no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return-value details do not need to be in the description. The two parameters are thoroughly documented and the read behavior is clear. The main gaps are the lack of explicit sibling differentiation and the unspecified default behavior when page is omitted, but overall this is nearly complete for a simple read tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description is the only documentation for the parameters. It fully explains url_or_slug with a concrete URL and slug example, and page with both string and numeric examples, while also clarifying the conditional relationship between the two parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Read') and the resource ('cleaned, transcribed/OCR text of a specific book page from Project Runeberg'). This distinguishes it from the sibling tools runeberg_search and runeberg_get_work_info, which serve clearly different purposes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description makes the use case clear: retrieve page text when you have a full page URL or a work slug plus optional page number. It does not explicitly mention alternatives or exclusions, but the context is strong enough for an agent to infer when this tool applies.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
runeberg_searchA
Full-text search across digitized books, encyclopedias, and literature in Project Runeberg (runeberg.org).
Args:
query: Search keywords or phrases (e.g. "Abraham Brodersson", "Dödsdansen", or "Falun gruva").
max_results: Maximum number of search results to return (default: 10).
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | ||
| max_results | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
There are no annotations, so the description carries the behavioral burden. It clearly states this is a full-text search operation, which implies a read-only, non-destructive action. However, it does not disclose details such as result behavior, pagination, authentication needs, or any search limitations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded: the first sentence states the core purpose, followed by a clean Args section. There is no redundant or filler content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple, has only two parameters, and an output schema exists, so the return format does not need to be explained. The description covers purpose and all parameters well, though it could be slightly stronger by noting when to prefer this over sibling tools.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It fully does: query is explained with concrete examples ('Abraham Brodersson', 'Dödsdansen') and max_results is described with its default value, adding practical meaning beyond the bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Full-text search across digitized books, encyclopedias, and literature in Project Runeberg.' It clearly distinguishes this tool from siblings like runeberg_read_page and runeberg_get_work_info, which are about reading pages or fetching work metadata rather than searching.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given about when to use this tool versus the sibling tools. The description explains what the search does, but it does not mention exclusions, preferred use cases, or when a different tool would be more appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
3 tool updates
v0.1.0- First observed
runeberg_get_work_info - First observed
runeberg_read_page - First observed
runeberg_search
TDQS
Scored across 3 tools
Each tool serves a distinct purpose: search for discovery, read_page for content access, and get_work_info for metadata. No overlap in functionality or ambiguous boundaries.
All tool names follow the same pattern: 'runeberg_' prefix with verb_noun structure (search, read_page, get_work_info). Consistent use of snake_case and clear verbs.
With only 3 tools, the set is minimal but appropriate for a focused read-only library access server. It covers search, retrieval, and metadata without excess.
The tools cover the core lifecycle: discover (search), access (read_page), and understand context (get_work_info). Minor gaps exist, such as lack of a browse/list tool, but search effectively covers discovery.
Maintenance
Related MCP Connectors
Search books and authors, fetch editions, browse subjects, and resolve cover images.
Search Wikipedia, read summaries and full text, target sections, find nearby pages, list languages.
Federated search of books and papers, BibTeX/RIS citations, open-access retrieval and reading.
Academic literature search, retrieval, and private library management on top of OpenAlex.
Related MCP Servers
- AlicenseAqualityAmaintenanceEnables users to search and access digital collections from the Swedish National Archives (Riksarkivet) through multiple APIs. Supports searching records by keywords, exploring collections, and downloading historical images and documents.224Apache 2.0
- AlicenseBqualityDmaintenanceProvides access to the National Library of Norway's Digital Humanities Lab, enabling text and image search, NGram analysis, word lookup, concordance finding, and corpus statistics from Norwegian digital collections.9MIT
- AlicenseAqualityAmaintenanceEnables AI agents to search and retrieve consolidated Swedish statutes (SFS) from the Riksdagen open data API, with verifiable citations and persistent identifiers.459 PyPIApache 2.0
- AlicenseNot gradedqualityCmaintenanceEnables search and reading of Project Gutenberg books with tools for searching by title/author/subject and fetching word-range slices of book text.MIT