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.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。