Server data from the Official MCP Registry
Drive the German tax portal ELSTER via Puppeteer: submit UStVA, prepare EUER/ESt, sync inbox.
Drive the German tax portal ELSTER via Puppeteer: submit UStVA, prepare EUER/ESt, sync inbox.
This MCP server automates the German ELSTER tax portal using Puppeteer and user-provided credentials. While the code demonstrates careful design with explicit confirmation flows before submission and no obvious malicious patterns, there are several security and code quality concerns: sensitive configuration data (certificate paths, passwords, tax numbers) is read from env vars and config files without comprehensive validation; the server performs complex DOM manipulation and field detection with broad CSS selectors and XPath queries that could be fragile or exploited; error handling logs error messages that may contain sensitive details; and permissions (file I/O, network, browser automation) are broad relative to typical developer tools. The explicit confirmation requirement before UStVA submission is a good safeguard, but the overall architecture and handling of credentials warrant caution. Supply chain analysis found 2 known vulnerabilities in dependencies (0 critical, 2 high severity). Package verification found 1 issue.
4 files analyzed · 11 issues found
Security scores are indicators to help you make informed decisions, not guarantees. Always review permissions before connecting any MCP server.
This plugin requests these system permissions. Most are normal for its category.
Set these up before or after installing:
Environment variable: ELSTER_CONFIG_PATH
Environment variable: ELSTER_PFX_PATH
Environment variable: ELSTER_PASSWORD
Environment variable: ELSTER_TAX_NUMBER
Environment variable: ELSTER_STATE_CODE
Environment variable: ELSTER_NAME
Environment variable: ELSTER_FIRST_NAME
Environment variable: ELSTER_STREET
Environment variable: ELSTER_HOUSE_NUMBER
Environment variable: ELSTER_ZIP
Environment variable: ELSTER_CITY
Environment variable: ELSTER_COUNTRY
Environment variable: ELSTER_HEADLESS
Environment variable: ELSTER_EST_SKIP_EUR
Add this to your MCP configuration file:
{
"mcpServers": {
"io-github-lukasschwarz-elster-mcp-server": {
"env": {
"ELSTER_ZIP": "your-elster-zip-here",
"ELSTER_CITY": "your-elster-city-here",
"ELSTER_NAME": "your-elster-name-here",
"ELSTER_STREET": "your-elster-street-here",
"ELSTER_COUNTRY": "your-elster-country-here",
"ELSTER_HEADLESS": "your-elster-headless-here",
"ELSTER_PASSWORD": "your-elster-password-here",
"ELSTER_PFX_PATH": "your-elster-pfx-path-here",
"ELSTER_FIRST_NAME": "your-elster-first-name-here",
"ELSTER_STATE_CODE": "your-elster-state-code-here",
"ELSTER_TAX_NUMBER": "your-elster-tax-number-here",
"ELSTER_CONFIG_PATH": "your-elster-config-path-here",
"ELSTER_EST_SKIP_EUR": "your-elster-est-skip-eur-here",
"ELSTER_HOUSE_NUMBER": "your-elster-house-number-here"
},
"args": [
"-y",
"elster-mcp-server"
],
"command": "npx"
}
}
}From the project's GitHub README.
A Model Context Protocol (MCP) server that lets Claude (or any MCP-capable client) drive the German tax portal ELSTER via Puppeteer.
English
Deutsch
Practical safeguards built into the tool
elster_ustva_confirm — it requires an explicit second call after elster_ustva_start has paused at AWAITING_CONFIRM. Nothing is sent without that second confirmation.| Tool | What it does | Submits? |
|---|---|---|
elster_login_test | Verifies your certificate + password can log in | No |
elster_config_show | Shows the loaded config (secrets redacted) | No |
elster_kennziffern_list | Returns the supported UStVA Kennziffern with descriptions | No |
elster_ustva_generate_xml | Generates a UStVA XML snapshot (archive only) | No |
elster_ustva_detect_reverse_charge | Detects §13b reverse-charge suppliers | No |
elster_ustva_start | Logs in, fills, runs Prüfung, then pauses for confirmation | Pauses |
elster_ustva_confirm | Clicks "Absenden" after you reviewed | Yes |
elster_eur_start | Fills Anlage EÜR up to Prüfung, then "Speichern und Verlassen" | No |
elster_est_start | Opens ESt 1 A, fills basics, runs Prüfung, keeps browser open 30 min | No |
elster_sync_history | Reads "Übermittelte Formulare" (optionally with PDFs) | No |
elster_sync_inbox | Reads ELSTER inbox (optionally with PDFs) | No |
elster_session_status / _list / _cancel | Session management | No |
.pfx) — get it from https://www.elster.de → "Mein ELSTER" → "Mein Benutzerkonto" → "Zertifikat verlängern"git clone https://github.com/YOUR_USERNAME/elster-mcp-server.git
cd elster-mcp-server
npm install
npm run build
Puppeteer will install a bundled Chromium on first install (~150 MB).
cp config.example.json config.json
$EDITOR config.json
All keys in config.json can be overridden by environment variables
(ELSTER_PFX_PATH, ELSTER_PASSWORD, ELSTER_TAX_NUMBER,
ELSTER_STATE_CODE, ELSTER_NAME, ELSTER_FIRST_NAME, ELSTER_STREET,
ELSTER_HOUSE_NUMBER, ELSTER_ZIP, ELSTER_CITY, ELSTER_COUNTRY,
ELSTER_DOWNLOAD_DIR, ELSTER_SCREENSHOT_DIR, ELSTER_HEADLESS,
ELSTER_EST_SKIP_EUR). Env vars win over the file.
You can also point the loader at a different config file via
ELSTER_CONFIG_PATH=/path/to/your/config.json.
The two-digit stateCode for your Finanzamt is published by ELSTER —
look up the current value in the official ELSTER documentation.
Add your §13b UStG suppliers under ustva.reverseChargeSuppliers in
config.json. Patterns are case-insensitive regexes matched against the
voucher's contactName or description. Example entry:
{ "pattern": "your-supplier\\s+ireland", "region": "EU", "name": "Your Supplier Ireland" }
Add to ~/Library/Application Support/Claude/claude_desktop_config.json
(macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"elster": {
"command": "node",
"args": ["/absolute/path/to/elster-mcp-server/dist/index.js"],
"env": {
"ELSTER_CONFIG_PATH": "/absolute/path/to/elster-mcp-server/config.json"
}
}
}
}
See examples/claude_desktop_config.json for the template.
Run the server in stdio mode:
node dist/index.js
Then connect via your client's MCP transport.
1. elster_login_test → { ok: true }
2. elster_kennziffern_list → reference for valid codes
3. elster_ustva_start({ → { sessionId: "ustva-..." }
year: 2026,
period: "Q1",
report: { "81": 12000, "86": 300, "66": 1845.30 }
})
4. elster_session_status({ sessionId }) → poll until status == AWAITING_CONFIRM
(open the screenshot at screenshotPath to verify)
5. elster_ustva_confirm({ sessionId }) → { success: true, ticket: "..." }
1. elster_login_test
2. elster_eur_start({
year: 2025,
data: {
betriebseinnahmen: 50000,
fahrzeugkosten: 1200,
afa: 800,
homeOffice: 1260
}
})
3. elster_session_status (poll until SAVED or AWAITING_REVIEW)
4. open the ELSTER portal in your browser → "Meine Formulare" → review the draft → submit manually
.env, config.json, or .pfx. They are gitignored by default.ELSTER_HEADLESS=false once to watch the first run and confirm everything is wired correctly.ELSTER_HEADLESS=false
and check the screenshots written to ./screenshots/.PRs welcome. The most useful additions are:
report schema validator for elster_ustva_*When opening an issue, please run with ELSTER_HEADLESS=false and attach the
screenshot under ./screenshots/ that shows the failure.
Be the first to review this server!
by Modelcontextprotocol · Developer Tools
Read, search, and manipulate Git repositories programmatically
by Modelcontextprotocol · Developer Tools
Web content fetching and conversion for efficient LLM usage
by Toleno · Developer Tools
Toleno Network MCP Server — Manage your Toleno mining account with Claude AI using natural language.
by mcp-marketplace · Developer Tools
Create, build, and publish Python MCP servers to PyPI — conversationally.
by Microsoft · Content & Media
Convert files (PDF, Word, Excel, images, audio) to Markdown for LLM consumption
by mcp-marketplace · Finance
Free stock data and market news for any MCP-compatible AI assistant.