impresso-mcp
Provides access to the impresso corpus of digitized historical newspapers, enabling article search with keyword-in-context snippets, filtering, facets, and source metadata retrieval.
README
impresso MCP
A CLI and an MCP server for impresso, the research corpus of the digitised historical press of Switzerland and Luxembourg — roughly 1738 to 2018, in German, French, Luxembourgish and Italian.
Searches resolve to an individual article, not to an issue or a page, and every result arrives with its keyword-in-context fragments already attached. Search and snippets are one request here rather than two.
impresso search "Gotthardtunnel" --from-year 1880 --to-year 1882 # 274 results
impresso facets newspaper "Landesausstellung" # NZZ 7144, FZG 3002, …
impresso sources --term Zürcher # NZZ, 1780-01-12 … 1950-12-31
impresso get NZZ-1882-03-21-b-i0001
Requirements
- Python ≥ 3.12 and uv
- A free impresso account
Credentials
impresso needs an account. The Basic tier is free and open to anyone: register at https://impresso-project.ch/datalab with a first name, a last name and an email address. No institutional affiliation is required.
impresso access tokens expire after a few hours. So this client does not ask you to hold a token. Store the account email and password once, and it logs in again by itself whenever the token it is holding is about to die:
mkdir -p ~/.config/impresso-mcp
cat > ~/.config/impresso-mcp/credentials.env <<'EOF'
IMPRESSO_EMAIL=you@example.com
IMPRESSO_PASSWORD=your_password
EOF
The minted token is cached, mode 0600, alongside the download cache, and every process sharing that cache shares the token — a fan-out of parallel searches logs in once between them, not once each.
If you would rather not store a password, IMPRESSO_API_TOKEN still works with a token copied from https://impresso-project.ch/datalab/token. It cannot be renewed, so expect to replace it by hand every few hours.
Check either arrangement with:
impresso auth
Install
uv tool install . # puts `impresso` on PATH
uv run impresso-mcp-install # registers the MCP server with Claude Code, Codex and Gemini
Add --enable-advanced-search to the installer to expose the filtered search, facet and source tools as well as the basic one.
Commands
search
impresso search "Völkerbund" --from-year 1920 --to-year 1925 --language fr --sort date_asc
# 36 results
There is no operator syntax inside a term. The server escapes the characters an operator would need, so a OR b searches for that literal text. Boolean logic is structural instead:
| Flag | Effect |
|---|---|
--or TERM |
an alternative, ORed with the main term |
--and TERM |
a term the article must also contain |
--not TERM |
a term whose presence excludes the article |
Each is repeatable, and they divide a result set exactly: Landesausstellung gives 14,014, --and Bern gives 6,982 and --not Bern gives 7,032, which sum back to it.
A multi-word term is matched as a phrase by default. --precision changes that, and the spread is large — on zweites Gesicht: exact 493, fuzzy 510 (one word of slop), partial 493, soft 886,685 (the words merely ORed). Only partial lets a trailing * act as a wildcard: Hellsehe* gives 1,428 under exact, where the * is literal, and 1,663 under partial.
Filters: --from-year, --to-year, --title, --headline, --language, --country, --type, --mention, --entity, --topic, --partner, --front-page, --with-text, --regex. All are optional and absent by default, and the active ones are echoed in the result header so a small total is traceable to what caused it.
Two of them are not what their names suggest, and both under-retrieve silently:
--mentionsearches impresso's named-entity index rather than the text, so it finds a name the OCR spelled differently but misses everyone the tagger did not recognise. Use it alongside a term search, never instead of one.--regexis a Solr regular expression matched against indexed terms. It is not analysed, and the German text is indexed on stems, so a regex written against the surface form silently under-retrieves:Bergsteigerreturns 7,475 as a term,/bergsteiger/returns 1,197, and/bergsteig/— the stem — returns 7,474. Write the regex against the stem, and check it by confirming that the bare stem reproduces the term-search total. The regex must also match a whole term, and the server strips.*and.+from the pattern before running it. A single.does widen the match, which is what makes it useful for finding OCR variants.
That stemming is worth knowing about on its own: searching one form finds the others that share its stem, so a query need not enumerate inflections — but the totals for different surface forms are not identical, so variants that matter should still be given explicitly with --or.
facets
impresso facets year "Landesausstellung"
impresso facets newspaper "Landesausstellung" --from-year 1939 --to-year 1939
Lists a filter's values with counts, largest first. Two uses: it gives a filter value verbatim — these filters match whole strings, so a near-miss returns zero with no error — and it answers a distribution question in one request. The counts always describe the current result set, never the whole corpus.
sources
impresso sources --term Luxemburg
The publications, with the years each one ran and the dates impresso actually holds. The two are frequently not the same, which matters before concluding that a paper is silent on a subject.
get
impresso get NZZ-1882-05-23-a-i0007
Downloads one article's transcript and prints the path to the cached file. This is the metered call: searches and facets are cheap, transcripts are drawn against the account's monthly quota. Most of the time it is unnecessary, because search already returns the fragments.
An article whose rights status the account cannot read is refused with an explanation rather than cached as an empty file — its search fragments remain quotable and its citation URL still opens the scan.
Rate limits
Throttling is per account, not per address, so parallel processes share one budget rather than getting one each.
The API documents a RateLimit header stating what is left of that budget, and the client reads it — reporting it on stderr after a search and in the --json output. No such header was returned in testing, so in practice the budget is not observable; the field stays null and the reporting is there for the day it is populated. Around 60 requests in a session drew no throttling and no 429.
Requests are paced by a cross-process limiter, default 1 second, overridable with IMPRESSO_MIN_REQUEST_INTERVAL.
Pagination
Deep pagination is unrestricted: totals are true match counts, and paging reaches them. Verified at offset 499,900 on a 601,658-result query, with no ceiling and no error.
Cache
Downloads and the minted token live under $XDG_CACHE_HOME/impresso-mcp/, overridable with --cache-dir or IMPRESSO_CACHE_DIR. Search results and facet listings are never cached.
Licence
Apache 2.0. impresso itself is a project of the University of Luxembourg, EPFL and the University of Zurich; its terms of use are its own.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.