mcpField
V
verify-atom

verify-atom

ローカル
github.com/asherengosセキュリティ05 週間前に更新

verify-atom について

verify-atomは、URLへのHTTPアクセスを観測し、検証可能な署名付き証明パケットを返すサービスです。ウェブ上の確認結果を必要とするエージェント向けに、Ed25519署名と追記専用の公開台帳を備え、MCPツールも提供します。

主な機能

  1. 01URLへのHTTP観測
  2. 02Ed25519署名付き証明パケットの生成
  3. 03検証記録の公開台帳への追記
  4. 04証明パケットのオフライン署名検証

活用シーン

  1. 01URLの到達性を確認し署名付き証拠を保存
  2. 02公開台帳で検証記録を確認

MCP 対応

stdio経由のMCPサーバーとして`verify`ツールを公開し、対応クライアントからURLのHTTP観測を依頼して、Ed25519署名付き証明パケットを取得できます。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"asherengos-verify-atom": {
"command": "uvx",
"args": [
"verify-atom-mcp"
]
}
}
}
起動コマンドuvx verify-atom-mcp

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
pypiverify-atom-mcp0.1.0

ツール

1

掲載時のツール一覧 · 2 週間前に更新

パラメーター型必須説明
urlstringはい確認して証明する公開 http(s) URL。

詳細

検証サービス(「アトム」)— v1 バックエンド

検証アトムの本番バックエンドです。**「これを1つ確認して、実行したことを証明してください。」**クライアントは1つの質問(URL の http_observation)を POST します。サービスは実際に観測を行い、コストの内訳が明確な署名付き証明パケットを返します。すべての検証は公開かつ恒久的な台帳(ボード)に追記されます。

最初に、正直にお伝えします。

  • すべてのパケットに含まれる cost_usd は、運営者が設定した推定値であり、クラウド料金の実測値ではありません("cost_basis": "estimate")。価格設定の前に再調整してください。
  • 決済は無効です。 v1 には決済プロバイダーとの連携がなく、payments.enabled が true でプロバイダーが設定されていない場合、サービスの起動を拒否します。
  • このサービスは収益を主張しません。提示価格は見積もりであり、まだ請求できないため、料金は一切請求されません。

アーキテクチャ

MCP サーバー(mcp/)

このリポジトリには、検証アトムを MCP ツールとして公開する Model Context Protocol サーバーも含まれています。これにより、MCP 対応エージェントは署名付き証明パケットを直接リクエストできます。

  • インストール: uvx verify-atom-mcp(PyPI では verify-atom-mcp として公開)
  • 公式 MCP レジストリに登録: io.github.asherengos/verify-atom
  • トランスポート: stdio · ツール: verify — URL の HTTP 観測を実行し、Ed25519 署名付き証明パケットを返します
  • ソース:mcp/mcp_server.py(依存関係なし。詳細は mcp/README.md を参照)
ファイル役割
app.pyFlask アプリ:ルート、SSRF ガード付き HTTP 観測、パケットの組み立て
signing.pyEd25519 鍵管理と署名/検証(Asher AI Studios Work Kernel から取り込んだ暗号コア、2026-09-25;純粋な Python、RFC 8032、依存関係なし)
costs.py / cost_model.yaml検証ごとの使用量測定 × 運営者設定の料金
ledger.py追記専用 JSONL 台帳(data/ledger.jsonl):ボードの信頼できる情報源であり、誠実なループの入力
mini_yaml.pyYAML の厳密なサブセットを読み込むリーダー(依存関係を flask と waitress に限定。汎用パーサーではありません)
config.yamlサービス設定:ポート、データディレクトリ、価格、ガードレール、決済スイッチ
tests/test_service.py隔離された pytest テストスイート(ローカルのスタブサーバーを使用。外部ネットワークへの接続なし)

検証の流れ:POST /verify → SSRF ガード → 実際のソケットレベルの HTTP フェッチ(DNS 解決は1回のみ。確認したアドレスに接続し、リダイレクトは追跡しません)→ 観測と証拠 → コスト計算 → 正規化 JSON への Ed25519 署名 → 台帳への追記 → 証明パケット。

クイックスタート

cd ~/workspace/verify-service
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt   # flask + waitress only; free
.venv/bin/python app.py                     # serves on 127.0.0.1:5057 via waitress

初回実行時に data/keys/ の下に Ed25519 鍵ペアが生成されます(0600)。data/ は gitignore 対象です。台帳、鍵、実行時の状態がリポジトリに含まれることはありません。

開発用(Flask 組み込みサーバー。本番環境では使用しないでください):

.venv/bin/python -m flask --app app:create_app run -p 5057

API リファレンス

POST /verify — 検証を実行
curl -s -X POST http://127.0.0.1:5057/verify \
  -H 'Content-Type: application/json' \
  -d '{"type":"http_observation","url":"https://example.com"}' | python3 -m json.tool

応答:署名付き証明パケット。

{
  "id": "VRF-20260926-3f9a2c1d",
  "type": "http_observation",
  "verdict": "CONFIRMED",
  "target": {"url": "https://example.com"},
  "observation": {
    "reachable": true,
    "http_status": 200,
    "page_title": "Example Domain",
    "body_sha256": "…",
    "tls": {"subject": "…", "issuer": "…", "not_after": "…"},
    "dns": {"host": "example.com", "addresses": ["93.184.216.34"]}
  },
  "evidence": [{"kind": "http_status", "value": 200}, …],
  "timestamp_utc": "2026-09-26T02:30:00Z",
  "usage": {"wall_time_s": 0.41, "bytes_in": 1830, "http_requests": 1},
  "cost_usd": 0.0000109,
  "cost_basis": "estimate",
  "price_quote_usd": 0.005,
  "margin_usd": 0.0049891,
  "below_cost": false,
  "signature": "<64-byte ed25519 hex>",
  "signing": {"algorithm": "Ed25519", "public_key_hex": "…",
              "signed_fields": "all fields except 'signature' and 'signing'"}
}

判定結果:CONFIRMED(フェッチ成功、HTTP 2xx)、UNCONFIRMED(フェッチ成功、その他のステータス — 実際に否定的な観測結果が得られた場合)、ERROR(拒否または失敗。理由は observation.reason で説明されます)。不明な type の場合 → 400 unknown_type。

パケットをスポットチェックする方法(信頼は不要です):

# fetch the service public key, then verify the signature offline:
curl -s http://127.0.0.1:5057/key

署名対象は、signature と signing を除くすべてのパケットフィールドを含む正規化 JSON(キーをソートし、区切り文字を詰めた形式)です。正規化 JSON を再計算し、任意の Ed25519 実装で検証してください。

GET /verify/ — 保存済みの証明パケットを取得(不明な場合は 404)
curl -s http://127.0.0.1:5057/verify/VRF-20260926-3f9a2c1d | python3 -m json.tool
GET /board/feed — 公開の追記専用フィード(古い順)
curl -s http://127.0.0.1:5057/board/feed | python3 -m json.tool

各エントリ:{id, timestamp_utc, type, verdict, url}。

GET /health
curl -s http://127.0.0.1:5057/health
# {"status":"ok","version":"0.1.0","payments_enabled":false}
GET /key — サービスの Ed25519 公開鍵
curl -s http://127.0.0.1:5057/key
# {"algorithm":"Ed25519","public_key_hex":"…"}

秘密鍵がログに記録されたり、配信されたり、signing.py の外に出たりすることはありません。

設定(config.yaml)

キーデフォルト意味
service.port5057リッスンポート
service.data_dirdata実行時状態(台帳、鍵)。Git の追跡対象外です
verify.base_price_usd0.005検証 1 回あたりの提示価格(見積もりであり、請求ではありません)
verify.timeout_s10観測ごとのネットワークタイムアウト
verify.max_body_bytes2097152本文の上限は 2 MB です。超過すると判定は ERROR になります
verify.allow_privatefalse本番環境では絶対に true にしないでください。 隔離テストで 127.0.0.1 のスタブを使用できるようにします
cost_modelcost_model.yamlオペレーターが設定した料金のパス
payments.enabledfalseマスタースイッチです。プロバイダーを設定せずに true にすると、起動を拒否します

鍵の管理

  • 初回実行時:KeyStore が Ed25519 鍵ペアを data/keys/{private.key,public.key} に生成します (ディレクトリは 0700、ファイルは 0600。既存の鍵は上書きしません)。
  • private.key はオフラインでバックアップしてください。紛失するとボードの信頼チェーンが失われます (過去のパケットは引き続き公開済みの公開鍵で検証できますが、 サービスは署名できなくなります)。
  • ローテーション(v1 では自動化されていません):新しい鍵ペアを生成し、 新しい公開鍵を key_id とともに /key で公開して、過去の検証用に 古い公開鍵も公開し続けます。サービス開始チェックリストを参照してください。

デプロイに関する注意事項

$0 のサービス開始バンドルは deploy/ にあります。

ファイル役割
deploy/verify-service.service強化された systemd ユニット(非特権の verify ユーザー、NoNewPrivileges、PrivateTmp、ProtectSystem=strict、障害時に再起動)
deploy/Caddyfile自動 TLS を備えたリバースプロキシ。実際のクライアント IP(X-Forwarded-For)を転送します。アプリがこのヘッダーを信頼するのは 127.0.0.1/::1 からの場合に限られます
deploy/DEPLOY.md専門知識のない人向けの、順を追った手順書:Oracle Cloud Always Free ARM VM、強化、初回起動時の鍵ペア生成、systemd、Caddy、DNS、サービス開始チェック

組み込みの不正利用対策:POST /verify はクライアント IP ごとにレート制限されます (スライド方式の 60 秒間ウィンドウ、verify.rate_limit_per_minute、デフォルトは 30/分)。 上限を超えると、Retry-After ヘッダー付きの 429 JSON を返します。 rate_limit_per_minute: 0 に設定すると無効になります(公開エンドポイントでは絶対に無効にしないでください)。

データディレクトリごとにワーカーを 1 つだけ実行してください(v1 では台帳に対するプロセス間ロックがありません)。 サービスは 127.0.0.1 のみでバインドし、公開トラフィックはリバースプロキシ経由で到着します。

人間とエージェント向けの機械可読ドキュメント:GET /llms.txt (text/plain)。エンドポイントの仕様、証明パケットのフィールド、 署名をオフラインで検証する方法、誠実性に関する注記を記載しています。

v1 の既知の制限事項(明記)
  • HTTP/1.1 のみ対応しています。リダイレクトは追跡せず、UNCONFIRMED として記録されます。
  • HTTP/2 と JavaScript のレンダリングには対応していません。観測対象は生の HTTP レスポンスであり、ハッシュ化と署名の対象もこれとまったく同じものです。
  • DNS は検証ごとに 1 回だけ解決されます。解決から接続までの数ミリ秒の間に応答を切り替える悪意ある DNS は、v1 の対象外です (ドキュメントには記載していますが、単一解決の設計による対策以外は講じていません)。
  • シングルワーカーです。台帳のスキャンは O(n) です。
  • 純粋な Python による Ed25519 です。正確ですが、C 実装より低速です。 v1 の処理量では問題ありません。規模を拡大する前に、十分に検証された C ライブラリを採用してください。

本番稼働チェックリスト

  • デプロイバンドル(deploy/、2026-09-26 ビルド):強化済み systemd ユニット、自動 TLS 対応の Caddyfile、DEPLOY.md ランブック(Oracle Cloud Always Free ARM VM、人手による手順を明記)、POST /verify の アプリ内 IP ごとのレート制限(デフォルト 30/min、429 + Retry-After)、 機械可読な API ドキュメント /llms.txt。すべて $0、標準ライブラリのみ、 決済コードパスなし。テスト:26/26 合格。
  • ホスティング:deploy/DEPLOY.md に従って VM をプロビジョニングし、 データディレクトリのバックアップ方法を決定します(台帳 + キーのバックアップは ランブックに記載されています)。
  • 決済プロバイダーの統合:未実装です。課金フローを実装して payments.provider に接続し、その後 enabled: true に切り替えます。
  • 本番用の新しいキーペア:ランブックに従い初回起動時に生成します (開発環境の data/ は絶対にコピーしないでください)。公開鍵を公開し、 秘密鍵をオフラインでバックアップします。
  • 実コストの調整:cost_model.yaml の推定値を実測値に置き換え、 調整用バッチを実行し、実価格を提示する前に margin_usd > 0 を確認します。
  • 利用規約と不正利用ポリシー:利用規定、検証失敗(ERROR)時の返金ポリシーを 作成して公開します(レート制限自体は組み込み済みです。残るのはエッジ側の ポリシーです)。
  • TLS + リバースプロキシ:deploy/Caddyfile で対応済みです。プレースホルダーの ドメインを置き換え、検証してリロードします。
  • キーのローテーション手順を文書化し、リハーサルを行います。
  • 監視:/health に対して UptimeRobot の無料監視を設定します。台帳の 増加、below_cost の件数、エラー率を監視します。ループが赤になったときに 誰かへ通知が届くように、誠実な監視ループを構築します。

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。