FragDenStaat について
FragDenStaat は、ドイツの情報公開請求を扱う AI アシスタント向け MCP サーバーです。担当機関や適用法の確認、請求の追跡、草稿の作成ができ、取り消せない送信は事前入力済みのウェブフォームで利用者が行います。
主な機能
- 01機関の検索と詳細取得
- 02適用法と期限の確認
- 03管轄の確認と根拠の提示
- 04請求、返信、添付ファイルの確認
- 05ローカル草稿と事前入力リンクの作成
活用シーン
- 01特定地域の請求先機関の特定
- 02既存請求の状況、返信、添付ファイルの確認
- 03送信前に確認できる請求草稿の作成
MCP 対応
MCP サーバーとして、FragDenStaat.de の検索、請求管理、草稿作成ツールを MCP クライアントに提供します。送信は取り消せないため、既定ではドライランとし、利用者が確認して送信する事前入力済みフォームも用意します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
uvx fds-mcpFDS_MCP_BASE_URLWhich froide instance to use. Defaults to https://fragdenstaat.deFDS_TOKENシークレットOAuth bearer token. Only needed for the tools that read your own requests or submit one; the four search tools work without it.ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
15掲載時のツール一覧 · 3 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| limit | integer | いいえ | |
| query | string | はい | |
| jurisdiction | any | いいえ |
詳細
fds-mcp — AI アシスタント向け FragDenStaat.de
froide を基盤に構築されたドイツの情報公開プラットフォーム、 FragDenStaat.de 用の MCP サーバーです。
平易な言葉で依頼するだけで、ドイツの情報公開請求を準備できます。 アシスタントは、回答義務のある機関を見つけ、その機関が適切な窓口である理由を示し、適用される法律と期限を確認します。すでに送信した請求を追跡し、回答と添付ファイルを収集します。また、新しい請求をローカルファイルに作成するため、あなたはマシンの外に何かが送信される前に内容を確認できます。
MCP とは何ですか?ここでは何をするのですか?
MCP、つまり Model Context Protocol は、AI アシスタントが外部のツールを使えるようにする標準です。おおまかに言えば、ブラウザーで拡張機能が果たす役割に相当します。
fds-mcp はそのようなツールの一つです。一度インストールすれば、Claude やその他の MCP クライアントから、froide を基盤に構築されたドイツの情報公開プラットフォーム、FragDenStaat.de と連携する 15 個のツールを利用できます。
そのうち 4 個はアカウントもトークンも不要です。機関の検索、法律の確認、特定の場所の担当機関の特定は、すぐに利用できます。
その他の froide インスタンス
froide は FragDenStaat.de の基盤となっている Django ソフトウェアで、その README には、2 つ目の本番ポータルとして fragdenstaat.at も記載されています。次のように、このサーバーの接続先を設定できます。
export FDS_MCP_BASE_URL=https://fragdenstaat.at
パスや認証情報を含まない https のオリジンのみが受け付けられます。また、ベアラートークンが見知らぬ相手へのリンクをたどらないようにするホスト許可リストは、この値から導出されます。そのため、.at を設定すると、fragdenstaat.de は外部ホストと見なされ、拒否されます。
2026-09-05 に fragdenstaat.at を基準に測定し、継続的なテストとして維持している内容は次のとおりです。
search_authorities、get_authority、get_law | アカウントなしで動作します |
check_jurisdiction | そこで動作しません — /api/v1/georegion/ のレコード数は .at では 0 件、.de では 24,216 件です。このクライアントで修正できることはありません |
| トークンに紐づくツール | そのインスタンスに登録された OAuth アプリケーションが必要です |
| 送信前のルールセット | ドイツの情報公開法を前提としており、他国には適用できません。他のインスタンスを通じた送信は未検証として扱ってください |
使用例
あなた: ボン市に関する情報公開請求には、どの機関が回答する必要がありますか?また、どの法律が適用されますか?
アシスタントは
check_jurisdiction("Bonn")を呼び出し、地域の階層とKommunalverwaltung Bonn(機関 3495)を取得します。続いてget_authority(3495)を呼び出して、適用される法律と期限を確認します。さらに使用した API の URL も示すため、回答をうのみにせず、自分で確認できます。
送信も可能ですが、このサーバーが行う処理の中で、意図的に最も慎重な扱いが必要なものです。
⚠️ POST /api/v1/request/ は即時かつ取り消し不能に送信します
FragDenStaat の REST API には、下書きモードも、プレビューも、取り消し機能もありません。POST /api/v1/request/ が成功した瞬間に、機関宛てのメールが送信され、請求は(デフォルトで)CC0 のもと公開され、取り消すことはできません。
さらに、MakeRequestSerializer には**law_type フィールドがありません**。そのため、API は必ず publicbody.default_law に基づいて請求を登録します。froide は ("-meta", "-priority") の順に並べるため、ほとんどの場合、意図した特定の法律ではなく、複合的な包括法が選ばれます。たとえば、ラインラント=プファルツ州の自治体に LTranspG(法律 16)に基づいて請求しても、API を通すと気づかないうちに「LTranspG, VIG」(法律 18)に基づいて登録されます。
**このため、このサーバーでは build_submit_url の利用を推奨します。**正しい law_type を設定した入力済みのウェブフォームが用意されるので、送信ボタンは自分で押せます。submit_request もありますが、デフォルトは dry_run=True で、5 つの独立した安全確認がすべて一致しない限り処理を拒否します。詳しくは安全モデルをご覧ください。
ドキュメント
- APIでできることとできないこと — 直面したすべての制限、その測定方法、試した行き止まり、途中で犯した間違い
- スクリーンショット付きのOAuth設定 — アプリケーションの登録、スコープ、リダイレクトURIのルール、ローカルのHTTPSリスナーがブロックされた場合の対処方法
- README.de.md と docs/oauth-setup.de.md — 同じドキュメントのドイツ語版です。原文は米国英語で、ドイツ語版はそれに準じています。
インストール
pip install fds-mcp
または、何もインストールせずにPyPIから直接実行できます。
uvx fds-mcp serve
チェックアウトから開発する場合:
git clone https://github.com/notDIRK/fds-mcp.git
cd fds-mcp
pip install -e ".[dev]"
Python 3.10以降が必要です。
MCPクライアントに登録する
このサーバーはstdioを使用します。Claude Codeの場合:
claude mcp add fds -- fds-mcp serve
JSON設定を読み込むクライアントの場合:
{
"mcpServers": {
"fds": {
"command": "fds-mcp",
"args": ["serve"]
}
}
}
または、何もインストールせずに実行する場合:
{
"mcpServers": {
"fds": {
"command": "uvx",
"args": ["fds-mcp", "serve"]
}
}
}
4つの緑色のツールは、アカウントもトークンも不要で、すぐに使えます。
OAuthの設定
黄色と赤色のツールにはOAuth 2.0ベアラートークンが必要です。FragDenStaatのAPIがサポートする認証方式は、OAuth2とセッションCookieの2種類だけです。個人用APIキーもBasic Authもありません(froide自身のdocs/api.rstには別の記載がありますが、情報が古くなっています)。
1. アプリケーションを登録する
ログインして、https://fragdenstaat.de/account/applications/register/を開きます。アカウントの各ページはrecent_auth_requiredで保護されているため、パスワードの再入力を求められる場合があります。
| フィールド | 値 |
|---|---|
| 名前 | 任意。例:fds-mcp |
| クライアントの種類 | public(PKCEが必須になります) |
| 認可グラントタイプ | authorization-code |
| リダイレクトURI | https://localhost:8765/callback |
受け付けられるスキームはhttpsとfragdenstaatだけです。 http://localhost/...は登録時に拒否されます。これはサーバー上のOAUTH2_PROVIDER.ALLOWED_REDIRECT_URI_SCHEMESによるものです。そのため、デフォルトのリダイレクト先は、fds-mcpがopenssl経由で生成する自己署名証明書を使ったHTTPSループバックリスナーです。また、代替手段はfragdenstaat://callbackを使い、手動で貼り付ける方法です。
2. 設定してログインする
fds-mcp configure --client-id <your-client-id>
fds-mcp login
loginはAuthorization Code + PKCE(S256)を実行し、ブラウザーを開いて、https://localhost:8765/callbackへのリダイレクトを受け取ります。ブラウザーに自己署名証明書の警告が表示されますが、これはローカルリスナーのものです。許可してください。
ブラウザーまたはopensslを使わない場合:
fds-mcp login --manual # uses fragdenstaat://callback, you paste the URL back
トークンはモード0600で~/.config/fds-mcp/tokens.jsonに保存されます。トークンは自動的に更新されます。リフレッシュトークンの有効期間は180日です。
fds-mcp status # config, token and throttle state
fds-mcp whoami # the authenticated account
fds-mcp logout --revoke
スコープ
fds-mcpはデフォルトでread:user read:request make:requestを要求します。リクエストを送信するつもりがない場合は、fds-mcp configure --scopes "read:user read:request"で変更できます。
| スコープ | 必要な機能 |
|---|---|
read:user | 自分のアカウントの識別(/api/v1/user/) |
read:request | 非公開のものを含む、自分のリクエスト |
make:request | POST /api/v1/request/ — リクエストの送信 |
write:message、write:attachment | 郵送物の記録(未実装) |
削除を許可するスコープはありません。make:requestを外すと、submit_requestは動作しなくなりますが、それ以外の機能は引き続き動作します。
ツール
| ツール | ティア | 認証 | 副作用 |
|---|---|---|---|
search_authorities(query, jurisdiction=None, limit=20) | 🟢 green | なし | なし |
get_authority(id) | 🟢 green | なし | なし |
get_law(id) | 🟢 green | なし | なし |
check_jurisdiction(place_name) | 🟢 green | なし | なし |
list_my_requests(status=None, limit=50) | 🟡 yellow | トークン、読み取り専用 | なし |
get_request(id) | 🟡 yellow | トークン、読み取り専用 | なし |
get_messages(request_id) | 🟡 yellow | トークン、読み取り専用 | なし |
list_attachments(message_id) | 🟡 yellow | トークン、読み取り専用 | なし |
download_attachment(attachment_id, target_dir) | 🟡 yellow | トークン、読み取り専用 | ローカルファイルを書き込みます |
check_deadlines() | 🟡 yellow | トークン、読み取り専用 | なし |
build_reply_draft(request_id, text, subject=None, path=None) | 🟡 yellow | トークン、読み取り専用 | path が指定されている場合、ローカル YAML ファイルを書き込みます |
create_request_draft(...) | 🔴 red | なし | ローカル YAML ファイルを書き込みます。ネットワーク通信は一切行いません |
validate_draft(path) | 🔴 red | なし | L01~L05 の API を読み取ります |
build_submit_url(path) | 🔴 red | なし | ローカルの .body.txt サイドカーファイルを書き込みます |
submit_request(path, confirmation_token) | 🔴 red | トークン + make:request | リクエストを送信します。取り消せません |
send_reply_via_browser(draft_path, confirmation_token) | 🔴 red、オプトイン | ログイン済みのブラウザープロファイル | 返信を送信します。取り消せません |
4 つの赤いツールはすべて dry_run: bool = True を受け取ります。
send_reply_via_browser は 16 番目のツールであり、FDS_MCP_BROWSER_SEND=1 が設定されていない限り登録されません。この変数が設定されていない場合、ツール一覧には表示されません。有効にする前に返信の送信をお読みください。
check_jurisdiction は根拠情報を返します
/georegion/?name=<place> をたどり、part_of チェーンを上へ進みながら、各レベルで /publicbody/?regions=<id> を照会します。その後、地域のチェーン、一致した行政機関、使用した API URL の一覧を返します。ラインラント=プファルツ州では、Ortsgemeinde が FragDenStaat に掲載されていないことがよくある一方、これを管轄する Verbandsgemeindeverwaltung は掲載されているため、これは重要です。
build_submit_url は長いリクエストを 2 段階で処理します
2026-09-05 に測定:fragdenstaat.de は、およそ 4096 バイトを超える GET URL に対して HTTP 400 を返します(4086 バイト → 200、4106 バイト → 400)。一般的な 4000 文字のリクエストは、URL エンコード後にこの上限を超えます。上限を超えた場合、このツールは件名と law_type を事前入力する短い URL に加えて、下書きの隣に .body.txt ファイルとして本文を返します。本文をフォームに貼り付けてください。
FragDenStaat の API ではできないこと
以下はフロントエンド専用で、REST による同等の機能はありません。サーバーはその事実を取り繕いません。
- 行政機関への返信 —
POST /api/v1/message/は 郵送 メッセージのみを作成します(OnlyPostalMessagesWritable)。また、subject/contentは読み取り専用のシリアライザーフィールドです。メールでの返信は/anfrage/<slug>/send/message/を通じて行います。この Django ビューは CSRF によって保護されており、ベアラートークンを無視します。返信の送信を参照してください。 - 法的根拠の選択 — シリアライザーに
law_typeはありません。 - 下書き —
RequestDraftは API ルーターに登録されていません。 - ステータス、解決状況、タグ、法律を後から設定すること、リクエストを公開すること、異議を申し立てること、州の情報コミッショナーにエスカレーションすること。
返信の送信
当局へのメール返信は、FragDenStaat API 経由では送信できません。 ペイロードを変えても、スコープを追加しても、より良いトークンを使っても送信できません。2026-09-05 に実施し、tests/test_api_contract.py で確実性を保った 3 つの測定結果を示します。
POST /api/v1/message/にkind: "email"を指定すると、HTTP 400 が返され、kindキーの下に "Nachrichten dieser Art können nicht über die API erstellt werden." と報告されます。これは froide のOnlyPostalMessagesWritableです。- 同じリクエストで
kind: "post"を指定しても 400 が返されます。プローブには意図的に解決できないリクエスト URI が含まれているため、どちらの場合も作成できません。ただし、kindエラーは含まれません。これが比較対象です。これがなければ、最初の測定では何も証明できません。400 の原因は、無効な URI、エンドポイントがすべての POST を拒否していること、またはスコープ不足かもしれないからです。 POST https://fragdenstaat.de/anfrage/<slug>/send/message/は HTTP 302 を返し、/account/login/にリダイレクトされます。ベアラートークンの有無にかかわらず、ステータスとLocationは同じです。ウェブビューで必要なのはセッションと CSRF のみです。OAuth は 1 の制限を回避する方法ではありません。
ですから、正直な答えは、人が返信を送信するということです。build_reply_draft を使えば、その作業を短時間で済ませられます。
build_reply_draft
リクエストを検索し、入力したテキストを検証して、完成したメッセージ、froide 独自の形式の件名(AW: <title> [#<id>])、フォームの URL を返します。ネットワークには何も書き込みません。送信させる引数はありません。
フォローアップはリクエストとは異なる方法で検証されます。この違いは簡単に見落としがちです。froide は新しいリクエストを法令の letter_start/letter_end で囲みますが、フォローアップはまったく囲みません。テキストエリアには、あらかじめ次の内容が入力されています。
Guten Tag,
…
Mit freundlichen Grüßen
<your name>
当局に送信されるのは、そこに入力された内容そのものです。そのため、次の点に注意してください。
R19では、あいさつと結びの定型句をそれぞれちょうど 1 回含める必要があります。これは、枠が適用されている間はその両方を禁止するR10とは逆です。R04は、現在そのフォームに入力されているプレースホルダー…(U+2026)を拒否します。この経路で最も起こりやすいミスです。R06は、公開され CC0 のスレッドにメールアドレスや IBAN が含まれないようにします。- 件名は 230 文字までです。
どの結果にも、例外なく警告が 1 つ付いています。フォームには、郵便住所があらかじめ入力されています。その住所は "Adresse mitsenden" というラベルのチェックボックスの背後にあります。公開リクエストでチェックを入れると、居住地が CC0 のもとで永久に公開されます。当局から郵便住所を明示的に求められていない限り、チェックを外したままにしてください。
send_reply_via_browser — オプション、デフォルトでは無効
最後の手順を自動化する方法もあります。ログイン済みのセッションを保持するブラウザーでフォームを操作します。このサーバーはそれを実行できますが、有効にはなっていません。FDS_MCP_BROWSER_SEND=1 が設定されている場合にのみ登録され、追加で次のものが必要です。
pip install 'fds-mcp[browser]'
python -m playwright install chromium
export FDS_MCP_BROWSER_SEND=1
テキストを作成することはありません。build_reply_draft が作成し、人間が承認した返信下書きファイルの subject と body を送信するだけです。それ以外の入力は受け付けません。次の5つのゲートがあります。
- ファイルが
status: approvedの返信下書きであり、send_addressが false であること。 - フォローアップルールに基づく未解決の
ERROR検出項目がないこと。 confirmation_tokenが、人間がファイルに書き込んだトークンとバイト単位で一致すること。- ローカルの台帳で、次のメッセージが
2/5min、6/6h、8/24hの制限内に収まっていること。この経路では、確実に依存できる形で froide がmessage_throttleを適用しないため、この制限は任意の歯止めです。 - フォーム上で、「住所を一緒に送信」がオフになっており、受信者を読み取って報告でき、入力後に件名とメッセージをバイト単位で読み返せること。U+2026 がなく、あいさつ文と結びの文句がそれぞれちょうど1つであること。検出できないものがあれば失敗として扱います。フォームの形が変わっていたら、ボタンを押してはならないフォームです。
その後、API に問い合わせて、リクエストに新しいメッセージが実際に存在するかを確認します。存在しない場合、結果は unconfirmed と報告され、下書きは送信済みとしてマークされません。不明であることは失敗でも成功でもありません。
警告
この機能を有効にすることで受け入れること
ブラウザーの自動化は、人間が最後の操作を行うという原則を覆します。 このサーバーのほかのすべての送信経路は、人が送信ボタンをクリックして終わります。この経路はそうではありません。
汎用のファイル書き込みツールと併用すると、ゲート1と3はゲートとして機能しません。 これらはディスク上の YAML ファイルにある2つの値にすぎません。このサーバーのツールでいずれかを設定することはできません。
build_reply_draftは常にstatus: draftとプレースホルダートークンを書き込みます。しかし、ほとんどの MCP ホストはモデルにwrite_fileツールも提供します。ファイルを書き込めるモデルなら、status: approvedと任意のトークンを書き込めます。これに権限機関からの返信に含まれるプロンプトインジェクションを組み合わせると、そのテキストはこのサーバーが読み取って信頼できないものとしてラベル付けしますが、モデルの目の前に表示されるため、公開機関への投稿が人間を介さずに送信される可能性があります。送信後に取り消すことはできません。ブラウザーには、あなたのログイン済みセッションが保持されています。 不具合が起きると、fragdenstaat.de 上であなたのリクエスト、アカウントページ、住所に対して、あなたの完全な権限で動作します。
対策。効果の高い順です。
- この機能をオフのままにします。
FDS_MCP_BROWSER_SENDを設定解除すれば、このツールは存在しません。FDS_MCP_BROWSER_PROFILEを使って、ほかのログイン情報がない専用のブラウザープロファイルを使用します。そのプロファイルのセッションが、被害の及ぶ範囲になります。FDS_MCP_DRAFT_DIRを使い、下書きディレクトリをほかのツールからアクセスできない場所に置きます。ゲート1と3に意味があるのは、ほかのものがそのファイルに書き込めない間だけです。- 通常の使用では
dry_run=Trueのままにします。フォームに入力した後、クリックする前に停止します。
安全モデル
7つのルールは、文書に記載するだけでなく、コードで適用されています。それぞれについて、実際に機能することを証明するテストが
tests/test_security_gates.py にあります。
submit_requestは、下書きのstatusがapprovedでない限り中止します。これを設定するのは人間です。ERRORの指摘事項が1つでも未解決の間は中止します。law.wunsch_id != law.api_default_idの場合、中止します。API はlaw_typeを設定できず、誤った法律に基づいて申請してしまうためです。confirmation_tokenが、人間が下書きファイルに記入したトークンと1バイトも違わず一致しない限り中止します。ツールがこのトークンを作り出してはいけません。- すべての書き込みツールでは、
dry_run: bool = Trueがデフォルトです。 - ローカルの台帳が、POST の前に
5/5min、6/6h、10/24h、20/7dを確認し、再試行せず明確なメッセージを表示して中止します。FragDenStaat の利用規約 B.1.4 では、制限の回避を試みた場合、アカウントが1か月間ロックされます。 - HTTP クライアントは、
allow_write=Trueが明示的に設定されていない限り、GET 以外のすべてのメソッドを拒否します。パッケージ内でこれを設定する関数は1つだけです。
send_reply_via_browser には、返信の送信に記載された独自の5段階のチェックがあり、tests/test_browser_send.py にテストがあります。また、ほかのツールには不要なゲートもあります。ルール0として、FDS_MCP_BROWSER_SEND=1 が設定されていない限り、ツール自体が登録されません。
ルールセット
オフラインルール R01~R19 は、fr ओide のウェブフォームが適用する検証を再現します。これは REST API が検証する内容よりもかなり多くなっています。ライブール L01~L06 は API と照合し、機関が実在し、現在もその名称であること、希望する法律が実際に提供されていること、再計算された API のデフォルトが下書きの記載内容と一致すること、申請が重複していないこと、本文の文が法律独自の書簡テンプレートにすでに含まれていないこと、完成した書簡に必要な要素がすべて含まれていることを確認します。
特筆すべきルール:
R06は、本文にメールアドレスや IBAN が含まれていると拒否します。公開申請は CC0 で、誰でも閲覧できます。他人に関する情報を記載しないでください。R10は、full_text=falseの場合、冒頭の挨拶または結びの定型句をエラーとして扱います。fr ode は法律のletter_start/letter_endで本文を囲むため、どちらかを自分で記入すると挨拶が重複して送信されます。R12はsubmit_via: apiの場合はエラーですが、submit_via: web_formの場合はヒントにとどまります。ウェブフォームでは法律を選択できますが、API では選択できません。R18とL06が確認するのは、記入した本文ではなく、機関が受け取る書簡です。full_text=falseの場合、法律のletter_start/letter_endが本文の一部を補うため、要素はどちら側からでも補えます。L06は書簡の枠を取得し、どちらにも含まれていない要素を報告します。要素は6つです。法的根拠(唯一のERROR)、費用の事前通知、費用の上限、期限、本文に責任がない場合の転送、電子的な返信です。
費用の上限が、この仕組みを設けた理由です。実際に、費用の上限を記載しないまま申請が送信されました。LTranspG の letter_end では予想費用の通知を求めていますが、上限も、現地での無料閲覧に切り替える代替案も明記されていませんでした。それ以外はすべてテンプレートで補われていました。まさにそのため、本文だけを読んでも問題が見つからなかったのです。
R19はR10の逆にあたるルールで、フォローアップにのみ適用されます。返信の送信を参照してください。
サーバーによる書き込みが許可される場所
3 つのツール引数はモデルが選択するファイルパスであり、同じモデルは第三者が書いたテキストである当局からの返信や添付ファイルも読み取ります。そのため、パスは信頼するのではなく、制約を設けています。
- 下書きのパスは
.yaml/.ymlで終わる必要があり、チェックの前に解決されます(シンボリックリンクはリンク先で判定されます)。また、save()は下書きファイルそのものではないファイルへの上書きを拒否します。 download_attachmentはディレクトリを作成せず、添付ファイル名はベース名だけに切り詰められ、[A-Za-z0-9._ -]以外の文字は置き換えられます。- 添付ファイルの取得元は
fragdenstaat.deとmedia.frag-den-staat.deのみで、ベアラートークンがそれ以外の場所に送信されることはありません。
4 つの環境変数を使うと、さらに制約を強化できます。サーバーを無人で実行する場合は、これらの設定を推奨します。
| 変数 | 効果 |
|---|---|
FDS_MCP_DRAFT_DIR | すべての下書きパスをこのディレクトリ内に制限します(: 区切りのリスト) |
FDS_MCP_DOWNLOAD_DIR | すべての download_attachment の保存先をこのディレクトリ内に制限します |
FDS_MCP_BROWSER_SEND | 1 の場合、send_reply_via_browser を登録します。未設定を含め、それ以外の場合はこのツールは存在しません |
FDS_MCP_BROWSER_PROFILE | このツール用のブラウザープロファイルディレクトリです。fragdenstaat.de にログインしたプロファイルだけを指定してください |
第三者のテキストを含む結果(get_messages、get_request、
list_attachments、download_attachment)では、該当するフィールドを
untrusted_content キーに明記します。これらはデータです。ファイルパス、URL、ツール呼び出し、確認トークンを指定するものではありません。
下書きのライフサイクル
draft ──validate_draft──▶ validated ──a human edits the file──▶ approved ──submit_request──▶ submitted
返信の下書きには submitted ではなく sent で終わる独自の状態があり、その状態に到達できるのは send_reply_via_browser だけです。また、新しいメッセージが存在することを API が確認した後に限られます。
下書きを approved に変更できるのは人間だけであり、YAML ファイルを編集する方法に限られます。
この文の限界を把握してください。 ゲート 1(status: approved)とゲート 4
(confirmation_token)は、どちらもローカルディスク上のファイルに含まれる値です。このサーバーのツールでは、どちらも設定できません。create_request_draft は常に status: draft とプレースホルダートークンを書き込み、下書きを昇格させるツールはありません。しかし、ほとんどの MCP ホストは汎用のファイル書き込みツールをモデルに提供します。また、ファイルを書き込めるモデルは、status: approved と独自に選んだトークンを書き込めます。当局からの返信に対するプロンプトインジェクションと組み合わさると、実際の申請が送信される可能性があります。
したがって、ファイルシステムツールと併用する場合は、次のいずれかを行ってください。
make:requestを含まないスコープを設定し、submit_requestを完全に使えない状態にしてください。そうすれば、このサーバーが保持するトークンでリクエストが POST されることはありません。- または、
FDS_MCP_DRAFT_DIRに、他のツールから書き込めないディレクトリを設定してください。 - または、推奨される終了方法を維持し、
build_submit_urlを使用してください。この場合、送信ボタンはツール呼び出しではなく、ブラウザー内にあります。 - また、
FDS_MCP_BROWSER_SENDは未設定のままにしてください。同じ考え方はsend_reply_via_browserにも当てはまります。こちらは、差し止められるスコープがなく、自分が所有するブラウザーセッションだけが頼りです。
ゲート 2、3、5、7 はファイルに依存せず、常に有効です。ルールセットは実際の API データに対して実行され、法律チェックは再計算された API のデフォルトと比較され、スロットルの記録は独立した状態として管理されます。また、HTTP クライアントは submit_request 以外では、あらゆる場所で GET 以外のリクエストを拒否します。
開発
pip install -e ".[dev]"
python -m pytest -m "not live" # offline suite
python -m pytest -m live # hits fragdenstaat.de
pytest-socket により、デフォルトでネットワークアクセスがブロックされます。live とマークされたテストだけが fragdenstaat.de にアクセスできます。
ライブテストは読み取り専用の GET で構成され、例外は 2 つだけです。どちらも tests/test_api_contract.py にあり、いずれも何も作成できません。メッセージの POST には解決できないリクエスト URI が指定され、ウェブフォームの POST は空の本文を送信します。ブラウザーを開くテストも、メッセージを送信するテストもありません。 トークンを必要とするテストは、~/.config/fds-mcp/tokens.json が存在しない場合、失敗ではなくスキップされます。
CLI は MCP クライアントなしでも動作します。
fds-mcp validate examples/request-draft.yaml
fds-mcp validate examples/request-draft.yaml --live
事実とその出典
このサーバーが API について主張する内容はすべて、2026-09-05 に fragdenstaat.de で、
okfde/froide@bc6c2fa および okfde/fragdenstaat_de@88bfbba を参照して確認しました。
出典は docstring にファイル名と行番号まで記載しています。誤りがある、または古くなった記述を見つけた場合は、バグです。issue を作成してください。
API のドキュメントは https://fragdenstaat.de/api/ にあり、OpenAPI 3.0.3 スキーマは
https://fragdenstaat.de/api/v1/schema/、Swagger UI は
https://fragdenstaat.de/api/v1/schema/swagger-ui/ にあります。(froide のドキュメントで案内されている
/api/v1/docs/ は 404 を返します。)
責任を持ってご利用ください
FragDenStaat は非営利団体が運営しており、寄付によって資金を賄っています。送信するリクエストはすべて、公的機関の職員の実際の作業時間を消費します。レート制限が 5 分間に 5 リクエスト、週に 20 リクエストとなっているのには理由があります。このサーバーは、リクエストの数を増やすのではなく、より良いリクエストを送信できるよう支援するために作られています。
public: true(デフォルト)を指定して送信したリクエストでは、メールのやり取り全体、承認済みの添付ファイル、およびアップロードされたすべての文書が、CC0 ライセンスのもとで全世界に公開されます。
免責事項
このプロジェクトは、Open Knowledge Foundation Deutschland e.V.、FragDenStaat、または froide プロジェクトと提携、承認、関係していません。 公開 API と通信する、独立したサードパーティ製クライアントです。商標はすべて各所有者に帰属します。
これは法律上の助言ではありません。
ライセンス
MIT — LICENSE を参照してください。Copyright 2026 Dirk Wolbeck。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。