Skip to content
verify mcp Beta VerifyMCP is currently in beta. If you notice any issues, get in touch and we’ll put it right.

FragDenStaat

PYPI · FDS-MCP · SCANNED SEP 22

Freedom-of-information requests for Germany via FragDenStaat.de, the froide FOI portal.

Available components

+4 this week 58 Trust /100
Trust breakdown (7 categories)

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. How we score → Why this is hard to score →

Supply Chain Security50
  • Malware scan not yet available for this package.Unverified
  • No known CVEs affecting this package version or its production dependencies.Pass
  • Runs hatchling.build at install time, a recognised native-build step with no shell scripting around it. View diagnostics → Pass
  • 1 of 33 dependencies flagged as unhealthy. View diagnostics → Partial
Provenance & Transparency32
Schema Quality & AI Usability72
  • AI-judged instruction clarity (excellent).Pass
  • Context-footprint check failed: tool/resource definitions use about 2445 tokens (~163/item across 15 items; 15 tools + 0 resources), over budget; trim descriptions and params. See how to fix → Fail
  • Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management57
  • Stability observed for 17 of 30 days with no destabilising changes; credit accrues until the full window elapses.Partial
Tool Coverage67
  • 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
  • 0% of tool parameters carry a description.Fail
Tool Safety100
  • No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
  • We read all 15 captured tool definition(s), and no name or description among them implies an irreversible operation.Pass
  • An AI judge read all 16 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
  • Implements a current MCP spec version (2026-07-28).Pass
Install

How do I install the FragDenStaat MCP server?

FragDenStaat runs locally as a PyPI package, launched with uvx fds-mcp. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

pypi · fds-mcp

# add to Claude Code
claude mcp add notdirk-fds-mcp -- uvx fds-mcp
// .cursor/mcp.json
{
  "mcpServers": {
    "notdirk-fds-mcp": {
      "command": "uvx",
      "args": [
        "fds-mcp"
      ]
    }
  }
}
// .vscode/mcp.json
{
  "servers": {
    "notdirk-fds-mcp": {
      "command": "uvx",
      "args": [
        "fds-mcp"
      ]
    }
  }
}
# add to Codex CLI
codex mcp add notdirk-fds-mcp -- uvx fds-mcp
// opencode.json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "notdirk-fds-mcp": {
      "type": "local",
      "command": [
        "uvx",
        "fds-mcp"
      ],
      "enabled": true
    }
  }
}
# add to OpenClaw
openclaw mcp add notdirk-fds-mcp --command uvx --arg fds-mcp
# ~/.hermes/config.yaml
mcp_servers:
  notdirk-fds-mcp:
    command: "uvx"
    args: ["fds-mcp"]
// ~/.netclaw/config/netclaw.json
{
  "McpServers": {
    "notdirk-fds-mcp": {
      "Transport": "stdio",
      "Command": "uvx",
      "Arguments": [
        "fds-mcp"
      ]
    }
  }
}
# add to Vellum
assistant mcp add notdirk-fds-mcp -t stdio -c uvx -a fds-mcp
// mcp.json
{
  "mcpServers": {
    "notdirk-fds-mcp": {
      "command": "uvx",
      "args": [
        "fds-mcp"
      ]
    }
  }
}
Changelog

Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.

  • 22 Sept 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 53 to 57. That category is still filling its 30-day observation window: 16 days of observed history at the previous scan, 17 at this one. The score rises as the window fills, whether or not the server changes.

  • 20 Sept 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 47 to 50. That category is still filling its 30-day observation window: 14 days of observed history at the previous scan, 15 at this one. The score rises as the window fills, whether or not the server changes.

  • 18 Sept 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 40 to 43. That category is still filling its 30-day observation window: 12 days of observed history at the previous scan, 13 at this one. The score rises as the window fills, whether or not the server changes.

  • 16 Sept 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 33 to 37. That category is still filling its 30-day observation window: 10 days of observed history at the previous scan, 11 at this one. The score rises as the window fills, whether or not the server changes.

  • 13 Sept 26 +4
    • Stability: unverified → 0.27 functional
  • 5 Sept 26 50

    First indexed and scored.

Diagnostics

Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.

Captured 22 Sept 2026 · Analysed pypi/fds-mcp@0.1.0

Provenance No attestation

The registry publishes no build provenance for this version, so there is nothing to verify.

Result No attestation
Ecosystem pypi

Background: How many MCP packages publish verified provenance →

Install scripts 1 script
Hook Tier Command
build_backend allowlisted hatchling.build

Background: Why install scripts are a supply-chain risk →

Dependencies 33 packages
Packages resolved 33
No linked repository 1
Tree resolution Complete

Background: SBOMs and build attestations, explained →

MCP tools · 15 exposed · ~2,255 tokens

The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →

Tool Tokens
build_reply_draft ~415

Prepare a follow-up message to an authority. YELLOW: reads the API, sends nothing. The counterpart of ``build_submit_url`` for a request that already exists. It looks the request up, validates the text against the rules that apply to a follow-up, and hands back the finished text plus the URL of the form. **Pressing send stays with you**, and there is no tool argument that changes that: replying is not possible through the API at all. Measured 2026-09-05 (tests/test_api_contract.py): ``POST /api/v1/message/`` refuses ``kind: "email"``, and the web view at ``/anfrage/<slug>/send/message/`` answers 302 to the login page whether or not a bearer token is attached. A follow-up is validated differently from a request. froide does **not** frame it: the textarea arrives prefilled with a salutation, the placeholder U+2026 and a closing formula, and exactly what stands in it is what the authority receives. So R19 requires a salutation and a closing formula — the inverse of R10 — R04 rejects the placeholder that is sitting in the form right now, R06 keeps e-mail addresses and IBANs out of a public thread, and the subject is capped at 230 characters. Args: request_id: numeric id of your existing request. text: the complete message, salutation and closing formula included. subject: reply subject. Defaults to "AW: <title> [#<id>]". path: optional path to a ``.yaml`` file to write the draft to. Needed only if you intend to use ``send_reply_via_browser`` later; the file is written with ``status: draft`` and a placeholder confirmation token.

NameTypeReqDescription
path
request_idintegeryes
subject
textstringyes

No output schema declared.

No examples provided.

build_submit_url ~174

Build the prefilled web form URL — the recommended way out. RED tier. This is the only route on which the legal basis can actually be chosen (``?law_type=...``); the REST API's MakeRequestSerializer has no such field. Sending stays with the human. fragdenstaat.de answers GET URLs above roughly 4096 bytes with HTTP 400 (measured 2026-09-05). Longer drafts therefore get a two-step answer: a short URL that prefills subject and law_type, plus the body in a sidecar text file. Args: path: path to the draft YAML file. dry_run: True (default) does not write the sidecar .body.txt file.

NameTypeReqDescription
dry_runboolean
pathstringyes

No output schema declared.

No examples provided.

check_deadlines ~51

Your open requests whose statutory deadline has passed. YELLOW. froide exposes no "deadline expired" flag; it is computed from ``due_date`` against the current time, exactly as the frontend does.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

check_jurisdiction ~219

Which authority covers a given place? GREEN — returns the evidence trail. Resolves ``/georegion/?name=<place>``, walks its ``part_of`` chain upwards, and asks ``/publicbody/?regions=<id>`` level by level, from the most specific outwards. It stops at the **first level that yields any authority**, because that is the body actually responsible; the remaining, wider levels are reported by id only. This matters in states such as Rhineland-Palatinate, where an *Ortsgemeinde* is often not listed on fragdenstaat.de at all while the *Verbandsgemeindeverwaltung* that runs its administration is. Args: place_name: name of the municipality, district or state. include_wider: also list the authorities of the wider levels. Off by default — at country level that is thousands of bodies and tells you nothing.

NameTypeReqDescription
include_widerboolean
place_namestringyes

No output schema declared.

No examples provided.

create_request_draft ~413

Write a local YAML draft. RED tier, but performs NO network traffic at all. The file starts in status ``draft`` with a placeholder confirmation token. A human has to read the text, set ``status: approved`` and replace ``confirmation_token`` before anything can be submitted. Args: path: where to write the YAML file. subject: request subject, 8-230 characters. body: the request text, at most 5000 characters. publicbody_id: recipient authority id. law_wunsch_id: the law you want to file under. law_api_default_id: the law the REST API would apply — see get_authority(). law_wunsch_law_type: law_type of the desired law, e.g. "IFG" or "UIG". publicbody_name: authority name, for the L01 cross-check. publicbody_email: authority e-mail, for the L01 cross-check. ermittelt_ueber: how responsibility was established (a URL or a sentence). public: whether the request will be public. Public means CC0 and visible to all. full_text: True sends your text verbatim, False lets froide frame it. submit_via: "web_form" (human presses send) or "api" (immediate dispatch). dry_run: True (default) returns the draft without writing the file.

NameTypeReqDescription
bodystringyes
dry_runboolean
ermittelt_ueber
full_textboolean
law_api_default_id
law_wunsch_idintegeryes
law_wunsch_law_type
pathstringyes
publicboolean
publicbody_email
publicbody_idintegeryes
publicbody_name
subjectstringyes
submit_viastring

No output schema declared.

No examples provided.

download_attachment ~137

Download one attachment into a local directory. YELLOW: reading only. The directory has to exist already: this tool will not create a path, because ``target_dir`` is a model-chosen argument and the file name comes from the API, and together they were enough to drop a file into e.g. ~/.config/autostart/. Set ``FDS_MCP_DOWNLOAD_DIR`` to confine downloads to one directory. Args: attachment_id: numeric attachment id (from list_attachments). target_dir: an existing local directory.

NameTypeReqDescription
attachment_idintegeryes
target_dirstringyes

No output schema declared.

No examples provided.

get_authority ~116

Full record for one public body, including its laws. GREEN. The API does not expose ``default_law``, so the law the REST API would apply is recomputed here the way froide's ``get_applicable_law()`` does it (``order_by('-meta', '-priority')``). That default is almost always the *meta* law, which is why the API cannot be used to file under a specific act. Args: id: numeric public body id.

NameTypeReqDescription
idintegeryes

No output schema declared.

No examples provided.

get_law ~50

One freedom-of-information act with its deadline rules. GREEN. Args: id: numeric law id, e.g. from ``get_authority(...)["laws"]``.

NameTypeReqDescription
idintegeryes

No output schema declared.

No examples provided.

get_messages ~38

All messages of a request, oldest first. YELLOW. Args: request_id: numeric request id.

NameTypeReqDescription
request_idintegeryes

No output schema declared.

No examples provided.

get_request ~41

One FOI request in detail. YELLOW (public requests work without a token). Args: id: numeric request id.

NameTypeReqDescription
idintegeryes

No output schema declared.

No examples provided.

list_attachments ~41

Attachments belonging to one message. YELLOW. Args: message_id: numeric message id (from get_messages).

NameTypeReqDescription
message_idintegeryes

No output schema declared.

No examples provided.

list_my_requests ~72

Your own FOI requests. YELLOW: needs a token (scope read:request), read only. Args: status: optional filter, e.g. "awaiting_response" or "resolved". limit: maximum number of requests to return.

NameTypeReqDescription
limitinteger
status

No output schema declared.

No examples provided.

search_authorities ~115

Search public bodies on fragdenstaat.de. GREEN: no auth, no side effects. Args: query: free-text search, e.g. a town or an authority name. jurisdiction: optional filter — numeric id, slug ("rheinland-pfalz") or name ("Rheinland-Pfalz"). The API itself only accepts the id. limit: maximum number of results (server page size is 50).

NameTypeReqDescription
jurisdiction
limitinteger
querystringyes

No output schema declared.

No examples provided.

submit_request ~260

Actually POST the request to fragdenstaat.de. RED tier — IRREVERSIBLE. ``POST /api/v1/request/`` sends the e-mail to the authority immediately. There is no draft, no preview and no undo. Five gates therefore have to agree, in this order: 1. the draft's status is ``approved`` (a human set it), 2. no ERROR finding is open, 3. ``law.wunsch_id == law.api_default_id`` — the API cannot set law_type, so a mismatch would file the request under the wrong act, 4. ``confirmation_token`` matches the value a human wrote into the draft file, 5. the local throttle ledger says another submission stays inside 5/5min, 6/6h, 10/24h, 20/7d. Args: path: path to the approved draft YAML file. confirmation_token: must equal the ``confirmation_token`` inside the draft file. dry_run: True (default) runs every gate and reports, but sends nothing.

NameTypeReqDescription
confirmation_tokenstringyes
dry_runboolean
pathstringyes

No output schema declared.

No examples provided.

validate_draft ~113

Run the rule set against a draft. RED tier. Offline rules R01-R16 always run. The live rules L01-L04 (authority exists, law is offered, API default law, duplicate check) need the network and therefore only run with ``dry_run=False``. Args: path: path to the draft YAML file. dry_run: True (default) runs offline rules only and does not touch the file.

NameTypeReqDescription
dry_runboolean
pathstringyes

No output schema declared.

No examples provided.

Common questions

What is the FragDenStaat MCP server?

FragDenStaat is an MCP server listed in the public MCP registry as io.github.notDIRK/fds-mcp. Freedom-of-information requests for Germany via FragDenStaat.de, the froide FOI portal. This page covers its PyPI package (fds-mcp).

Is the FragDenStaat MCP server safe to use?

FragDenStaat scores 58 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 22 September 2026. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

What tools does the FragDenStaat MCP server expose?

FragDenStaat exposes 15 tools: search_authorities, get_authority, get_law, check_jurisdiction, list_my_requests, and 10 more. Their descriptions and schemas cost roughly 2,255 tokens of context every time the server is loaded.

Is the FragDenStaat MCP server still maintained?

FragDenStaat is still listed as active in the MCP registry. We last reached this channel on 22 September 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.