elster-mcp-server
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| ELSTER_HEADLESS | No | Overrides the headless setting from config.json (whether the browser runs without a visible window). | |
| ELSTER_PASSWORD | No | Password of your ELSTER certificate file (.pfx). Overrides auth.password from config.json. | |
| ELSTER_PFX_PATH | No | Path to your ELSTER certificate file (.pfx). Overrides auth.pfxPath from config.json. | |
| ELSTER_CONFIG_PATH | No | Path to config.json, which holds the certificate path, password, headless/download/screenshot settings and the taxpayer and §13b supplier settings used by the UStVA helpers. | ./config.json |
| ELSTER_DOWNLOAD_DIR | No | Overrides the download directory from config.json (where transmission protocols and PDFs are saved). | |
| ELSTER_SCREENSHOT_DIR | No | Overrides the screenshot directory from config.json. |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| elster_login_testA | Verifies that the configured certificate + password can log into the ELSTER portal. Returns success and final URL or an error. Use this once before submitting anything. |
| elster_config_showA | Shows the currently loaded ELSTER configuration (with secrets redacted) so you can verify env vars / config.json were picked up. |
| elster_kennziffern_listA | Returns the list of supported UStVA Kennziffern (codes 81, 86, 66 etc.) with descriptions and whether they are NET (base amount) or TAX (tax amount). |
| elster_ustva_generate_xmlA | Generates an ELSTER UStVA XML snapshot for archiving. Does NOT submit (submission goes via elster_ustva_start). Useful for audit trails. |
| elster_ustva_detect_reverse_chargeC | Tests whether a voucher would be detected as Reverse-Charge (§13b UStG) based on the configured supplier patterns. Returns matched supplier and region (EU / NON_EU), or null. |
| elster_datenuebernahme_listA | Lists the earlier submissions ELSTER offers to carry over ("Datenübernahme") for a given form and tax year, without starting a filling session. Read-only. Feed an aufgabeId or year from the result into the "takeover" argument of elster_ustva_start / elster_eur_start / elster_est_start. |
| elster_edaten_fetchA | Retrieves the pre-filled tax data ("vorausgefüllte Steuererklärung" / eDaten) the tax authority already holds for a year: Lohnsteuerbescheinigung, Vorsorgeaufwendungen, Lohnersatzleistungen, Riester/Rürup. ELSTER only exposes these from inside the ESt form, so this walks the form up to the import step and reads the values back. The form is left without saving, so no draft is kept (ELSTER may offer it for recovery at the next login). Nothing is ever transmitted. |
| elster_submissions_listA | Lists everything under "Meine Formulare" → "Übermittelte Formulare": what was filed, when, its Ordnungskriterium, plus the aufgabeId to reuse it as a Datenübernahme source and the nachrichtId needed by elster_submission_protocol. Read-only. |
| elster_submission_protocolA | Reads the "Übertragungsprotokoll" of already-submitted returns — every field that was actually filed, with its Zeile number, label, value and ELSTER field id — so earlier years can be used as context. Select either by nachrichtId (from elster_submissions_list) or by formFilter/years. Read-only; returns real personal tax data. |
| elster_sync_historyC | Reads "Übermittelte Formulare" (transmission history) from ELSTER. Optionally downloads PDFs. |
| elster_sync_inboxC | Reads ELSTER inbox messages ("Posteingang"). Optionally downloads each message as PDF. |
| elster_drafts_listA | Lists saved drafts ("Meine Formulare → Entwürfe") with their aufgabeId, newest first. Uses the persistent engine session (logs in on first use, then stays logged in). |
| elster_form_openA | Opens a saved draft in the engine session and returns its Startseite (fields, repeat groups, navigation RIDs). Without aufgabeId the newest draft is opened. If ELSTER still holds the form open from an earlier call, it is re-entered instead of failing. Only one form can be open at a time. |
| elster_form_newA | Starts a NEW form: picks the year, handles Datenübernahme (none by default), Anlagenauswahl and the eDaten import, and stops on the form's Startseite. Returns the page like elster_form_page. Follow with elster_form_save to persist it as a draft. |
| elster_form_pageA | Reads a page of the open form. With rid, jumps there first (RIDs look like "FormData://est-2025-v1/Startseite[0]/MAVSAnlageN[0]/VAnlageN[0]/HomeofficePauschale[0]" and come from the nav list of any page). Returns plain fields (name, kennzahl, label, value, options), repeat groups (committed rows, the template fields for a new row, sub-page RIDs), non-navigation commands, validation errors and the nav RIDs visible from this page. Read-only. |
| elster_form_setA | Sets plain fields on a page and saves them to the server-side form. Keys are a Kennzahl ("E0204507") or the field name ("eruNWkHomeofficeE0204507"); a key must match exactly one field on the page. Checkboxes take true/false, radios and selects take the option value. Money: fields labelled "(Euro)" accept whole euros only (no decimal separator — round expenses up, income down); "(Euro, Cent)" fields take "3,36". Validation errors come back in |
| elster_form_add_rowA | Adds one row to an inline repeat group ("Mzb", e.g. Arbeitsmittel "AufwendungenArbeitsmittel") by filling its new-row template and committing it ("Eintrag übernehmen"). Group names and template keys come from elster_form_page → groups. Same key and money rules as elster_form_set. |
| elster_form_attachA | Attaches local files to a form's upload group, e.g. the Einspruch page "5 - Anhänge" (group "anhang_mzb"). PDF or XML, max 10 MB each, up to 20 files. Uploads each file the way the portal page does and creates one row per file. Submits nothing. |
| elster_form_delete_rowC | Deletes row |
| elster_form_pressB | Escape hatch: presses a button by id or posts a raw reqCmd JSON from elster_form_page → commands (e.g. EditDetachedMzbSemIndex to add an Anlage for a person, FillInProfile, AddMzbItem). Sending, deleting drafts and logging out are refused. |
| elster_form_crawlA | Walks every page below a RID (breadth-first, read-only) and returns each page's fields and repeat groups. Use it once per form/Anlage to learn which Kennzahl lives on which page. |
| elster_form_checkA | Runs ELSTER's "Prüfen" on the open form. Returns ok, the headline (for ESt it includes the provisional "Erstattung/Nachzahlung"), and the error panel with the causing pages. Never sends. |
| elster_form_reviewA | Final check before the user submits: runs "Prüfen" and, only if it is clean, reads ELSTER's "Formular absenden" overview — exactly the data that would be transmitted, including eDaten fields — as sections of rows (Zeile, label, value, Kennzahl, source). Returns to edit mode in the same call. Never transmits: "Absenden" stays refused, and no command but EINGABE/PRUEFEN is accepted while on the overview. |
| elster_form_handoffA | Hands a finished form to the USER for sending. Saves the open form (or takes the given draft), opens it in a separate, visible browser window with its own login, runs "Prüfen" and, if clean, moves on to the "Formular absenden" page. Then the MCP detaches from that window: it cannot click anything there. The user checks the overview, clicks "Absenden" themselves and closes the window. Until the window is closed the other elster_form_* tools refuse to run. Follow up with elster_form_handoff_wait, which returns when the window is closed and shows what was sent. |
| elster_form_handoff_waitA | Call right after elster_form_handoff: blocks until the user closes the handoff window (or the timeout passes). If a new submission appeared, saves its Übertragungsprotokoll as HTML + PDF and returns the Transferticket and file paths. Read-only. If it returns closed:false, call it again. |
| elster_submission_archiveA | Saves the Übertragungsprotokoll of submitted forms as HTML and PDF, as proof of what was sent (Transferticket, receipt time on the server, full content incl. attachment names). Select by nachrichtId (from elster_submissions_list) or by formFilter/years (newest first, limit default 1). Default folder: /nachweise. Read-only. |
| elster_belege_listA | Lists receipts in "Meine Belege" (id, label, year, Belegart, recognised values, status). Read-only. |
| elster_beleg_uploadA | Uploads one receipt file (PDF, PNG or JPG, max 10 MB) to "Meine Belege" and tags it with a Belegart and its values, so it is linked to the matching form line. Belegart is a path like "N/Arbeitsmittel" (fields Art_der_Arbeitsmittel, Betrag), "N/Weitere_Wk/Sonst" (Bezeichnung, Betrag), "N/Fortb" (Bezeichnung, Betrag), "N/Dienstreise". Betrag as number or "12,99". Stores a document in the account; submits nothing. Receipts are optional for the ESt (Belegvorhaltepflicht) but can avoid queries. |
| elster_form_saveA | Saves the open form as a draft ("Speichern und Formular verlassen") and closes it. Reopen with elster_form_open. The server session times out after ~30 min idle and unsaved work is then only in ELSTER's auto-recovery — save before long pauses. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 29 tools
Most tools target distinct resources/actions (form editing vs. drafts vs. submissions vs. Belege vs. session handoff), and descriptions explicitly steer usage order. A few pairs overlap meaningfully: elster_submissions_list vs elster_sync_history (both read 'Übermittelte Formulare'), elster_submission_protocol vs elster_submission_archive (same protocol, one archives as PDF/HTML), and elster_form_check vs elster_form_review (review just adds the absenden overview). These are disambiguated in the text but still require careful reading.
All names are snake_case with an 'elster_' prefix, which is good, but the verb placement varies: noun_verb (elster_form_open, elster_drafts_list), verb-in-middle (elster_ustva_generate_xml, elster_form_handoff_wait), and bare noun_verb forms. Singular/plural is also inconsistent (elster_submissions_list vs elster_submission_protocol/archive; elster_belege_list vs elster_beleg_upload). Still readable, but not a predictable pattern throughout.
29 tools is heavy and above the comfortable 3–15 band. The domain is genuinely complex (login, config, UStVA, ESt form engine, drafts, submissions, Belege, handoff), so most tools earn their place, but the surface is large enough that an agent must navigate many near-sibling tools. Borderline: justified by scope but on the high side.
The ESt/form lifecycle is well covered end to end: open/new/page/set/add_row/delete_row/attach/crawl/check/review/handoff/wait/save, plus drafts, submissions, protocol, archive and Belege. However, several descriptions reference tools that do not exist in this set (elster_ustva_start, elster_eur_start, elster_est_start), leaving the UStVA submission path apparently incomplete and creating dead-end references. The document-upload and handoff flows round out coverage reasonably well.