turva.dev について
turva.dev は、連絡先や日付付きの測定結果など、turva.dev の公開情報を返す読み取り専用の MCP サーバーです。同サイトの情報を調べる MCP クライアント向けで、他ドメインの監査や取引は行いません。
主な機能
- 01サービスと料金の情報を提供
- 02エージェント対応状況の測定値を提示
- 03日付付きのセキュリティテスト結果を共有
- 04運営方針と連絡先を説明
- 05引数不要の読み取り専用ツールを提供
活用シーン
- 01連絡手段と依頼開始の手順を確認
- 02サイト掲載のサービス一覧を確認
- 03対応状況やセキュリティ証拠の日付とリンクを確認
MCP 対応
https://mcp.turva.dev/mcp のホスト型 Streamable HTTP MCP エンドポイントで、5 つの読み取り専用ツールを提供します。認証や API キーは不要です。
設定
リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。
https://mcp.turva.dev/mcpclaude mcp add --transport http turva https://mcp.turva.dev/mcp{"mcpServers":{"turva":{"type":"http","url":"https://mcp.turva.dev/mcp"}}}Cursor で開く{"servers":{"turva":{"type":"http","url":"https://mcp.turva.dev/mcp"}}}VS Code で開く{"mcpServers":{"turva":{"type":"http","url":"https://mcp.turva.dev/mcp"}}}{"mcpServers":{"turva":{"serverUrl":"https://mcp.turva.dev/mcp"}}}コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。
ツール
5このツールにパラメーターはありません。
詳細
turva-mcp
TypeScript で記述された、turva.dev 向けの公開読み取り専用 Model Context Protocol サーバーです。AI クライアントが、連絡先や日付付きの測定結果など、サイトで公開されている情報を検索できます。
たとえば、誰かが連絡方法を尋ねたとき、クライアントは get_contact を使用できます。応答には、開始方法が記載されています。このサーバーが回答するのは turva.dev 自体に関する質問です。別のドメインをスキャンしたり、監査を実施したり、取引を行ったりすることはありません。
接続
Streamable HTTP エンドポイント:
https://mcp.turva.dev/mcp
ホストされたサーバーに直接接続できます。npm のインストール、認証、API キーは不要です。Streamable HTTP に対応した MCP クライアントでエンドポイントを設定してください。URL ベースの mcpServers 設定を使用するクライアントでは、一般に次の形式を使用できます。
{
"mcpServers": {
"turva": {
"url": "https://mcp.turva.dev/mcp"
}
}
}
エンドポイントは MCP の POST リクエストを想定しています。ブラウザーで /mcp を開くと 405 が返されます。代わりに、ディスカバリードキュメントから接続可能か確認してください。
curl https://mcp.turva.dev/
Windows PowerShell で curl が Invoke-WebRequest に解決される場合は、curl.exe を使用してください。
このサーバーは、公式 MCP レジストリに dev.turva/turva-mcp として、また Glama MCP ディレクトリに掲載されています。
ツールを試す
接続後、引数オブジェクトを空にして get_contact を呼び出してください。MCP クライアント SDK では、次のように呼び出します。
const result = await client.callTool({ name: "get_contact", arguments: {} });
const contact = result.structuredContent;
console.log(contact.email, contact.first_reply);
ここで client は、接続済みの MCP クライアントです。テキストのみを読み取るクライアント向けに、同じ JSON が result.content[0].text にも含まれています。応答のこの抜粋は、src/index.ts で管理されている連絡先フィールドを示しています。
{
"email": "[email protected]",
"location": "Tampere, Finland",
"engagement": "async_only",
"first_reply": "Within one business day, in writing, by email or Signal. LinkedIn messages have no set reply time."
}
完全な応答には、その他の連絡手段、業務を開始する手順、および turva.dev の運営者を示す operator オブジェクトも含まれています。
SDK を使わない場合、現在のプロトコルレーンでリクエストを送信するには、JSON-RPC 本文に加えて 4 つの項目が必要です。MCP-Protocol-Version ヘッダー、tools/call に対する Mcp-Method ヘッダーと Mcp-Name ヘッダー、そしてプロトコルバージョンとクライアントの機能を指定する params 内の _meta オブジェクトです。同じ呼び出しを curl で行う例:
curl https://mcp.turva.dev/mcp \
-H "Content-Type: application/json" \
-H "MCP-Protocol-Version: 2026-07-28" \
-H "Mcp-Method: tools/call" \
-H "Mcp-Name: get_contact" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"get_contact","arguments":{},"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientCapabilities":{}}}}'
応答は 1 つの JSON-RPC レスポンスで、連絡先データは result.structuredContent に含まれています。
ツール
5 つの読み取り専用ツールがあり、いずれもべき等です。各ツールはデータを structuredContent として返し、その形式はツールの outputSchema で記述されています。また、同じ JSON をテキストブロックでも返します。引数を取るツールはありません。入力スキーマで引数は許可されておらず、引数を渡す呼び出しはツールエラーになります。書き込みツールや取引ツールはありません。
| ツール | 返される内容 |
|---|---|
get_services | 業務モデル、サービス一覧(Shopify エージェントのストアフロントチェック、監査、アドバイザリー、実装、エージェント運用、MCP サーバー設計)、料金(固定価格 4 件と要問い合わせ 2 件)、および固定価格で、診断後に限り提供される実装オプション 2 件 |
get_agent_readiness | turva.dev のエージェント対応度スコア、カテゴリ別スコア、測定日、スキャナーの開始ページへのリンク |
get_security_evidence | turva.dev の公開 Hardenize および Internet.nl の結果と測定日 |
get_principles | 書面での業務、アクセス、検証に関する原則 |
get_contact | turva.dev の運営者、連絡手段、初回返信までの時間、監査に必要なアクセス権 |
証拠
ツールの応答は、Worker にバンドルされた静的な TypeScript オブジェクトから取得されます。稼働中の上流へのリクエストには依存しません。測定ツールには measured_at の日付と公開検証リンクが含まれているため、現在の状態を確認する必要がある場合は、記録された値と最新のスキャン結果を比較してください。
バンドルされたスナップショットには、isitagentready.com で 100/100、Level 5 Agent-Native、Internet.nl のウェブサイトテスト で 98/100、メールテスト で 90/100 と記録されています。また、Hardenize で全 24 カテゴリーに合格したことも記録されています。これらすべての測定日は 2026-10-21 です。これらの測定値はサードパーティによるものです。このサーバーは、いずれのスコアも算出していません。
エンドポイント
| メソッドとパス | 動作 |
|---|---|
POST /mcp | Streamable HTTP による MCP。64 KiB を超える本文には 413 を返し、JSON-RPC バッチにはエラー -32600 を伴う 400 を返します |
GET /mcp、DELETE /mcp | Allow: POST, OPTIONS を伴う 405。GET ストリームおよびセッションの終了には対応していません |
OPTIONS /mcp | 許可された MCP プリフライトには 200 を返し、ブラウザーの Origin が許可されていない場合は 403 を返します |
/mcp/ | メソッドとクエリ文字列を維持して /mcp に 308 でリダイレクトします。ブラウザーはプリフライト時にリダイレクトを追跡しないため、プリフライトの OPTIONS には /mcp と同じ応答を返します |
GET / | サーバー名、トランスポート、エンドポイントを含む最小限の検出用 JSON |
GET /.well-known/mcp | 同じ検出用 JSON |
GET /.well-known/glama.json | Glama のドメイン検証ドキュメント |
その他の任意のパスに対する OPTIONS | 検出用 CORS プリフライトとして 204 |
/mcp と /mcp/ 以外の任意のパスに対する POST、PUT、DELETE、または PATCH | Allow: GET, HEAD, OPTIONS を伴う 405 |
その他の任意のパスに対する GET または HEAD | 404 |
検出ドキュメントに対する HEAD は、本文を返さずにヘッダーを返します。検出ドキュメントには Cache-Control: public, max-age=3600 が設定されています。これは、tools/list と server/discover が宣言している時間と同じ 1 時間です。
メインサイトでは、署名済みの完全な MCP サーバーカードを turva.dev/.well-known/mcp/server-card.json で提供しています。
プロトコルと実装
Cloudflare Agents SDK を基盤とする単一の Cloudflare Worker が、agents/mcp/server の createMcpHandler を通じてエンドポイントを提供し、リクエストごとに @modelcontextprotocol/server から新しい McpServer を作成します。Durable Object も、永続的な MCP セッションもありません。
現在のプロトコルレーンでは、リビジョン 2026-07-28 を使用します。同じエンドポイントにあるレガシーレーンは、2025 年当時のクライアントに対応します。このレーンは Agents SDK のアダプターであり、@modelcontextprotocol/server のウェブ標準サーバートランスポートを通じて応答します。
現在のレーンでは、すべてのリクエストに MCP-Protocol-Version と Mcp-Method が必要です。また、tools/call には Mcp-Name も必要です。いずれかが欠けているリクエストには、エラー -32020 を伴う 400 が返されます。リクエストボディの検証が最初に行われ、-32602 またはツールエラーで応答します。不正な params と未知のツール名はこれに該当し、__proto__ という名前の引数も同様です。その他の想定外の引数は、ヘッダーの検証後にチェックされ、SDK がツールエラーを返します。JSON-RPC 通知は、このヘッダー検証を行わずに SDK に渡されます。@modelcontextprotocol/server は Mcp-Method と Mcp-Name をチェックし、Worker はハンドラーの実行前に MCP-Protocol-Version をチェックします。このパッケージはリクエストボディからバージョンを読み取るため、そうしなければヘッダーのないリクエストにも応答してしまうためです。
現在のレーンでは Accept をチェックしませんが、レガシーレーンでは Accept に application/json と text/event-stream の両方が含まれていない場合、406 を返します。標準の MCP クライアントは、これらの詳細に対応します。
server/discover は @modelcontextprotocol/server が提供します。ツールセットはデプロイ時にのみ変更され、サーバーは変更通知を送信しないため、listChanged: false を指定して tools ケイパビリティを宣言します。また、どのツールがどの質問に答えるかを示す簡潔な説明を返します。
ディスカバリー用ドキュメントとツールデータは、Worker にコンパイルされます。この Worker はメインの turva.dev Worker とは別のため、ここでの変更がウェブサイトに影響することはありません。
依存関係
コードは @modelcontextprotocol/server、agents、zod をインポートします。package.json には、コードではインポートされない @modelcontextprotocol/client と @modelcontextprotocol/sdk も記載されています。package.json で固定されている agents のバージョンは、3 つすべての MCP パッケージを正確なバージョン指定の必須ピア依存関係として宣言しているため、npm はそれらをインストールする必要があります。ただし、ビルドされた Worker に @modelcontextprotocol/client と @modelcontextprotocol/sdk は含まれません。
セキュリティと運用上の制限
このサーバーには書き込み経路がなく、公開データのみを返すため、対処すべきなのはエンドポイント自体への悪用です。1つのアドレスからの負荷、処理コストの高いリクエスト、別のサイト上で訪問者のブラウザーからこのサーバーを呼び出すページなどが該当します。
- 設計上、公開されており、認証は不要です。公開される値はすべてすでに公開済みのものです。
- すべてのツールに読み取り専用の MCP アノテーションが付いています。破壊的な操作やオープンワールド操作は宣言されておらず、引数を取るツールもありません。
- レート制限:クライアント IP ごとに約60秒あたり100リクエストです。上限を超えると
429とRetry-After: 60が返されます。Cloudflare のレート制限バインディングは、各ロケーションで個別かつ概算のカウントを保持するため、最初の429が返るまでに、バーストによってさらに多くのリクエストが通過する場合があります。レート制限バインディングが見つからない場合やエラーが発生した場合、エンドポイントは制限を適用せずに処理を続行します。 - リクエストサイズ:64 KiB を超える本文は、ハンドラーが読み取る前に
413が返されます。また、JSON-RPC バッチはどちらのレーンでも400が返されるため、1つのリクエストで多数のツール呼び出しをレート制限を超えて送信することはできません。 /mcpのブラウザー CORS では、スキームやポートを問わず、ホスト名がturva.devのOriginを受け入れ、それ以外のすべてのオリジンは403で拒否します。通常、ブラウザー以外の MCP クライアントはOriginヘッダーを送信せず、直接接続できます。ディレクトリが読み取れるように、ディスカバリードキュメントではオープン CORS を使用します。- このコードは、リクエスト本文、クライアントの識別情報、ツール入力を保存しません。Cloudflare Workers のオブザーバビリティは無効になっています。レート制限に失敗した場合は、リクエストデータを含まない診断エラーが記録されます。
- MCP とディスカバリーのレスポンスには、セキュリティヘッダーが適用されます。
非公開の脆弱性報告については、SECURITY.md を参照するか、[email protected] にメールでご連絡ください。
このサーバー以外の関連ツール
以下の2つのチェックは、それぞれ独立したツールです。MCP ツールではなく、このサーバーも実行しません。別のウェブサイトをチェックするには、単体の npm パッケージを使用してください。
- turva-llms-txt-validator は、llms.txt の構造とホームページのディスカバリー宣言をチェックします。ブラウザー版では、任意の公開ドメインを指定できます。
- markdown-parity-check は、HTML ページと Markdown ページの主要コンテンツを比較します。ブラウザー版でチェックできるのは、turva.dev 自身が公開しているページのみです。
どちらも npx で実行します。どちらも Node.js 22 以降が必要です。バリデーターの手順と比較の手順に、引数と終了コードの説明があります。
開発とテスト
Worker には Node.js ^22.18.0 || >=24.11.0 が必要です。これは package.json の engines フィールドに記載されている範囲です。エントリーポイントは src/index.ts です。ビルド工程はありません。実行時またはデプロイ時に Wrangler が TypeScript をバンドルし、Node が型を削除してテストを実行します。
npm ci
npm run dev
npm test
npm run typecheck
npm run devはwrangler devを起動し、Worker のローカルコピーを実行します。npm testはnode --experimental-strip-types --testを実行し、test/catalog.test.tsとtest/protocol.test.tsをテストします。npm run typecheckはtsc --noEmitを2回実行します。1回目はtsconfig.jsonを使用してsrcを、2回目はtsconfig.test.jsonを使用してtestを型チェックします。package.jsonにある2つのoverridesは意図的なものです。一方は SECURITY.md で説明しているとおり、@hono/node-serverを修正済みリリースに固定し、もう一方は Workers の型のすべてのコピーが直接の依存関係を参照するようにします。どちらかを削除する前に、npm ciとnpm auditを再度実行してください。
ワークフロー は、読み取り専用の権限で、すべてのプッシュとプルリクエストのたびに実行されます。Node.js 22 と 24 で実行する test ジョブが1つあります。このジョブは npm ci、npm audit --omit=dev --audit-level=moderate、続いて npm test と npm run typecheck を実行します。中程度以上のアドバイザリがあるランタイム依存関係が見つかると、監査の段階でビルドが失敗します。ワークフローによるデプロイはありません。
このリポジトリに残っていた最後の JavaScript ファイルは、2つのテストファイルでした。サイト Worker の名称を変更した2026年10月20日に、これらを TypeScript に移行し、それ以降は tsconfig.test.json で型チェックしています。src/index.ts のサーバーソースは、すでに TypeScript でした。
自分用のコピーをデプロイする
このリポジトリは MIT ライセンスで公開されており、別のサイト向けに改変できます。フォークをデプロイする前に、次の作業を行ってください。
src/index.tsにある静的なサービスオブジェクトとエビデンスオブジェクトを、自分が公開するデータに置き換えます。- ハードコードされた
turva.devドメイン、MCP エンドポイント、ブラウザーのオリジン、検証リンクを、自分が管理する値に置き換えます。 - Worker に一意の
nameを設定し、Cloudflare アカウント内の別の Worker と共有しないレート制限用のnamespace_idを割り当てます。 - 独自のカスタムドメインを割り当てます。
wrangler.jsoncではworkers_devが無効になっています。
「開発とテスト」のチェックを実行してから、自分の Cloudflare アカウントでデプロイします。
npm run deploy
Workers & Pages、対象の Worker、Settings、Domains & Routes の順に開き、カスタムドメインを設定します。独自のホスト名を使用し、src/index.ts のディスカバリーエンドポイントをそのホスト名に合わせて更新してください。
メンテナー
Erik Rekola が turva.dev で開発しました。実装についてのご質問は [email protected] までお寄せください。私は文章の執筆を仕事にしています。turva.dev は、MCP サーバー設計などのサービスとして、このサーバーのようなサーバーを他のサイト向けに構築しています。
事業者登録情報は、フィンランド企業情報システムで確認できます。
ライセンス
MIT。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。