Doroseek について
Doroseekは、DenoとFreshで構築されたアプリで、OpenAI互換エンドポイントとAPIキーを管理し、MCPサーバーやプロキシとしても動作します。ローカルサービスのトンネル、リアルタイム通信ルーム、小さなファイルの共有機能も備えています。
主な機能
- 01エンドポイントとAPIキーを管理
- 02モデルにエイリアスを設定
- 03組み込みMCPサービスを提供
- 04他のMCPサーバーをプロキシ
- 05ローカルサービスのトンネルと通信ルーム
- 06URLで小さなファイルを共有
活用シーン
- 01複数のOpenAI互換エンドポイントを利用
- 02クライアントを他のMCPサーバーに接続
- 03トンネル経由でローカルWebサービスを公開
- 04小さなファイルの共有やルーム内通信
MCP 対応
Doroseekは組み込みMCPサービスを提供し、他のMCPサーバーのプロキシとしても動作します。SSEルートでサーバーに接続でき、Agent ModeではリモートのDoroseekインスタンスを介してローカルサービスを中継します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
このサーバーのパッケージやリモートエンドポイントはまだ取得できていません。プロジェクトの README の手順に従ってください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
Doroseek
Deno と Fresh で構築されたシンプルな AI アプリです。
- 同じベース URL と API キーで、すべての OpenAI Compatible エンドポイントにアクセスできます。また、
DoroseekAPI キーを他のユーザーと共有して、エンドポイントにアクセスできます。 - いくつかの組み込みサーバーを備えた MCP サーバーとして動作します。
- MCP プロキシサーバーとして、他の MCP サーバーに接続できます。

機能
- OpenAI Compatible エンドポイント
- エンドポイントと API キーの管理
DoroseekAPI キーの生成- モデルへのエイリアスの割り当て
- ルート
- ルートの管理:
/{key} - OpenAI Compatible ルート:
/api
- ルートの管理:
- MCP SSE サーバー
- sequentialthinking - Sequential Thinking
- think - Think Tool MCP サーバー
- ルート
/mcp/{server}/sse?apiKey={apiKey}
- MCP プロキシサーバー
- ルート
- stdio:
/mcp/proxy/sse?apiKey={apiKey}&transport=stdio&command=&args=&env= - sse:
/mcp/proxy/sse?apiKey={apiKey}&transport=sse&url=
- stdio:
- 使用例
- Sequential Thinking:
/mcp/proxy/sse?apiKey={apiKey}&transport=stdio&command=npx&args=-y @modelcontextprotocol/server-sequential-thinking&env={}
- Sequential Thinking:
- ルート
新しいコア機能(MCP ベース)
Doroseek に、高度なユースケース向けの強力な MCP ベースのサービスがいくつか追加されました。
- イントラネットへの侵入(トンネリング): ローカルサービスをインターネットに公開します。
- 複数ユーザーのコミュニケーションルーム: 複数のクライアント間でリアルタイム通信を可能にします。
- リソース共有: 小さなファイルやデータの断片をアップロードして共有します。
これらの機能では、リアルタイム通信に WebSocket を活用し、該当する場合は永続化に Deno KV を使用します。
1. イントラネットのトンネリング
概要:
この機能を使用すると、Doroseek インスタンスとの間に確立されたセキュアなトンネルを通じて、プライベートネットワーク上で実行中のサービス(ローカル開発サーバー、データベース、その他の TCP/HTTP サービスなど)をパブリックインターネットに公開できます。
ローカルエージェント:
この機能を使用するには、プライベートサービスにアクセスできるマシン上でローカルエージェント(クライアントソフトウェア)を実行する必要があります。Doroseek 自体をこの「エージェントモード」で実行することもできます。Doroseek をローカルエージェントとして構成して実行する方法については、以下のエージェントモードセクションを参照してください。エージェントは、リモートの Doroseek インスタンス(リレーとして動作)への接続、トンネルの管理、リレーとローカルサービス間のトラフィック転送を担います。
登録プロセス(エージェントからリレー):
-
接続: ローカルエージェントは、次の WebSocket 接続を
DoroseekMCP サーバーに確立します。wss://your-doroseek-instance/mcp/tunnel/register?apiKey=<your_api_key>登録には API キーが必須です。
-
登録メッセージ: WebSocket 接続が確立された後、エージェントは
registerメッセージを送信します。このメッセージには、公開するサービスの詳細が含まれます。 エージェントからのregisterメッセージの例:{ "type": "register", "data": { "services": [ { "type": "http", "local_port": 3000, "subdomain_or_path": "my-web-app" }, { "type": "http", "local_port": 8080, "subdomain_or_path": "api-service" } // 今後、エージェントのプロトコルで 'tcp' などの種類がサポートされる可能性があります。 ] } } -
サーバーの応答: 登録が成功すると、
Doroseekは一意のtunnelIdと、トンネル経由でサービスにアクセスするためのパブリックベース URL を含むregisteredメッセージを返します。 サーバーからのregisteredメッセージの例:{ "type": "registered", "data": { "tunnelId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "public_base_url": "https://your-doroseek-instance/t/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" } }
トンネル経由のサービスへのアクセス:
トンネルが確立されると、登録時に定義した public_base_url と subdomain_or_path から導出されたパブリック URL を介して、ローカルサービスにアクセスできます。たとえば、your-doroseek-instance が example.com で、あるサービスが subdomain_or_path: 'my-web-app' として登録されている場合、次の URL からアクセスできる可能性があります。
https://example.com/t/<tunnelId>/my-web-app/...
正確な URL 構造は、パブリック向けルーティング(/t/:tunnelId/...)が特定のサービスにマッピングされるよう、どのように構成されているかによって異なります。
ローカルエージェントの役割(概要):
/mcp/tunnel/registerへの WebSocket 接続を開始し、維持します。- サービス定義を含む
registerメッセージを送信します。 - WebSocket 経由で
Doroseekから送信されるhttpRequestメッセージを待ち受けます。各httpRequestメッセージには、次の情報が含まれます。requestId:リクエストの一意の ID。data:受信したパブリックリクエストのmethod、path、headers、bodyを含むオブジェクト。
httpRequestを受信すると、ローカルサービス(例:http://localhost:3000/some/path)に対応するリクエストを送信します。- ローカルサービスから応答を受け取ると、元の
requestIdと応答の詳細(ステータス、ヘッダー、本文)を含むhttpResponseメッセージを WebSocket 経由でDoroseekに返します。 - (トンネル経由の WebSocket プロキシは今後の拡張機能として計画されていますが、現在は
Doroseekのパブリック向けトンネルルートでスタブ実装になっています。)
2. マルチユーザーコミュニケーションルーム
コンセプト: 複数のクライアント間で、リアルタイムかつ双方向の通信を可能にします。Web アプリケーションでのライブチャット、共同編集、その他のマルチユーザー向けインタラクティブな体験などの機能を実現するバックエンドとして使用できます。
ルームへの接続:
クライアントは WebSocket 接続を使用してルームに接続します。パスには roomId を指定します。
- WebSocket エンドポイント:
wss://your-doroseek-instance/mcp/room/:roomId?apiKey=<optional_api_key> - 認証:
- 匿名アクセス: 現在、クライアントは API キーなしで接続できます。
- API キー認証済みアクセス: クエリ文字列に
apiKeyが指定されている場合、その値が検証されます。必要に応じて、ユーザーを API キーの所有者に関連付けることができます。
主な機能:
- ルームへの参加: ユーザーは、ルームのエンドポイントへの WebSocket 接続を正常に確立すると、ルームに参加します。
- 参加時に、サーバーはすでにルームにいるユーザーの一覧を含む
ServerRoomInfoMessageを参加ユーザーに送信します。 - ルーム内の他のユーザーには
ServerUserJoinedMessageが届きます。
- 参加時に、サーバーはすでにルームにいるユーザーの一覧を含む
- ルームからの退出: ユーザーの WebSocket 接続が閉じられると、そのユーザーはルームから自動的に削除されます。
- ルーム内の他のユーザーには
ServerUserLeftMessageが届きます。
- ルーム内の他のユーザーには
- チャットメッセージの送信: クライアントは WebSocket 経由でチャットメッセージを送信します。
クライアントからの
ClientChatMessageの例:{ "type": "chatMessage", "payload": { "roomId": "your-target-room-id", // Though roomId is in path, can be in payload "message": "Hello everyone!" } } - メッセージの受信: クライアントはサーバーからのメッセージを待ち受けます。
ServerChatMessage:ルーム内の別のユーザーが送信したチャットメッセージです。{ "type": "chatMessage", "payload": { "roomId": "the-room-id", "fromUserId": "user-id-of-sender", "message": "Hello everyone!", "timestamp": "2023-01-01T12:00:00.000Z" } }ServerUserJoinedMessage:新しいユーザーが参加したことを通知します。ServerUserLeftMessage:ユーザーが退出したことを通知します。
概念的なクライアント側のインタラクション例(JavaScript):
const roomId = "my-chat-room";
const apiKey = "your-optional-api-key"; // Or leave undefined for anonymous
const socket = new WebSocket(`wss://your-doroseek-instance/mcp/room/${roomId}?apiKey=${apiKey}`);
socket.onopen = () => {
console.log("Connected to room:", roomId);
// Send a chat message
socket.send(JSON.stringify({
type: "chatMessage",
payload: { roomId, message: "Hi from client!" }
}));
};
socket.onmessage = (event) => {
const serverMessage = JSON.parse(event.data);
console.log("Received message:", serverMessage);
if (serverMessage.type === "chatMessage") {
// Display chat: serverMessage.payload.fromUserId, serverMessage.payload.message
} else if (serverMessage.type === "userJoined") {
// Update user list
} // etc.
};
socket.onclose = () => {
console.log("Disconnected from room:", roomId);
};
socket.onerror = (error) => {
console.error("WebSocket error:", error);
};
3. リソース共有
概要:
ユーザーが小さなファイルやデータの断片(設定ファイル、JSON データ、小さな画像など)を Doroseek にアップロードし、一意の一般公開 URL を使って共有できます。
アップロード手順(MCP WebSocket):
-
エンドポイント:
/mcp/fileshare/uploadに WebSocket で接続します。wss://your-doroseek-instance/mcp/fileshare/upload?apiKey=<your_api_key>ファイルのアップロードには有効な API キーが必要です。
-
メッセージの流れ:
- クライアント -> サーバー:
ClientInitiateUploadMessageクライアントはまず、ファイルのメタデータを指定してアップロード開始メッセージを送信します。{ "type": "initiateUpload", "payload": { "filename": "config.json", "filetype": "application/json", "size": 1024 // Size in bytes } } - サーバー -> クライアント:
ServerUploadReadyMessageサーバーがアップロードを受け付けると(サイズが上限内である場合など)、一意のresourceIdを返します。{ "type": "uploadReady", "payload": { "resourceId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" } } - クライアント -> サーバー:
ClientFileDataMessageクライアントは、実際のファイルデータを base64 エンコードして送信します。{ "type": "fileData", "payload": { "resourceId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "data": "eyJrZXkiOiAidmFsdWUifQ==" // Base64 encoded content of the file } } - サーバー -> クライアント:
ServerUploadCompleteMessageファイルデータの保存に成功すると、サーバーは完了を通知し、ダウンロード URL を返します。{ "type": "uploadComplete", "payload": { "resourceId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "downloadUrl": "https://your-doroseek-instance/shared/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" } }
- クライアント -> サーバー:
ダウンロード手順(HTTP GET):
- URL 形式: 次の URL に HTTP GET リクエストを送信すると、ファイルをダウンロードできます。
https://your-doroseek-instance/shared/:resourceId - 認証: デフォルトでは、ダウンロードに API キーは必要ありません。リンクを知っていれば、誰でもアクセスできます。
制限事項:
- ファイルサイズの上限: 現在、この機能は小さなファイルを対象としています。ファイルデータの保存に Deno KV をバックエンドとして直接使用するため、個々のファイルサイズは事実上、通常約 60KB の Deno KV の値サイズ上限に制限されます。これを超えるアップロードは拒否されます。大きなファイル向けの分割アップロードは、将来的に追加される可能性があります。
ローカルでの実行
このセクションでは、Doroseek をデフォルトのサーバーモードで実行する方法を説明します。トンネリング機能で Doroseek をローカルエージェントとして実行する方法については、エージェントモードのセクションを参照してください。
サーバーモードの設定
.env.example を .env にコピーします
# .env
ADMIN_KEY=the_admin_key_here
MCP_MAX_DURATION=60
デフォルトでは、プロジェクトは任意のキーによる対応する設定の作成を許可します。特定のキーのみがアクセスできるように制限するには、ADMIN_KEY 環境変数を設定してください。
MCP SSE 接続の継続時間は MCP_MAX_DURATION 秒に設定できます。
必要に応じて DB を設定します
// services/database.ts
export const db = await Deno.openKv("./db");
サーバーモードでの実行
アプリをデフォルトのサーバーモードで実行するには、DOROSEEK_AGENT_MODE_ENABLED が "true" に設定されていないことを確認してください。
Deno をインストールしてから、このリポジトリのルートディレクトリで次を実行します。
deno task start
エージェントモード(イントラネットへの侵入用)
Doroseek はエージェントモードでも動作できます。このモードでは、Fresh Web サーバーを起動しません。その代わりに、リモートの Doroseek インスタンス(リレーサーバーとして動作)に接続するローカルクライアントエージェントとして機能し、プライベートネットワーク上のサービスをインターネットに公開します。
これは、デフォルトのサーバーモードに代わる動作モードです。エージェントモードが有効化され、正しく設定されている場合、Doroseek はエージェントの役割のみを実行します。
エージェントモードの設定
エージェントモードを有効化して設定するには、次の環境変数を設定する必要があります。
-
DOROSEEK_AGENT_MODE_ENABLED:"true"に設定すると、エージェントモードが有効になります。"true"に設定されていない場合、Doroseekはサーバーモードでの起動を試みます。
-
DOROSEEK_RELAY_URL:- このエージェントが接続するリモートの
Doroseekインスタンス(リレーサーバーとして動作)の WebSocket URL です。この URL は、リレーのトンネル登録エンドポイントを指す必要があります。 - 例:
wss://your-remote-doroseek.com/mcp/tunnel/register
- このエージェントが接続するリモートの
-
DOROSEEK_AGENT_API_KEY:- このエージェントがリモートの
Doroseekリレーサーバーとの認証に使用する API キーです。この API キーは、リレーサーバーによって認識され、認証されている必要があります。
- このエージェントがリモートの
-
DOROSEEK_AGENT_SERVICES_JSON:-
このエージェントがトンネルを通じて公開するローカルサービスの配列を定義する JSON 文字列です。
-
配列内の各サービスオブジェクトには、次のフィールドが必要です。
id(文字列):サービスの一意の識別子です(「my-web」など、任意に指定します)。name(文字列):サービスのユーザーフレンドリーな名前です(「My Local Web Server」など)。type(文字列):サービスの種類です。現在、エージェントの HTTP ハンドラーがサポートしているのは"http"のみです。local_host(文字列):ローカルサービスのホスト名または IP アドレスです("localhost"、"127.0.0.1"など)。local_port(数値):ローカルサービスが実行されているポート番号です(8080など)。subdomainOrPath(文字列):リレーサーバーがこのサービスの公開 URL を構成するために使用する文字列です。/やスペースを含めないでください。これは、リレーの公開トンネル URL のパスセグメントになります。- たとえば、リレーがベース URL として
https://<relay-public-domain>/t/<tunnelId>を提供し、subdomainOrPathを"myweb"に設定した場合、サービスにはhttps://<relay-public-domain>/t/<tunnelId>/myweb/...でアクセスできます。
- たとえば、リレーがベース URL として
-
DOROSEEK_AGENT_SERVICES_JSONの設定例:[ { "id": "web1", "name": "My Local Web Server", "type": "http", "local_host": "localhost", "local_port": 8080, "subdomainOrPath": "myweb" }, { "id": "api2", "name": "Backend API", "type": "http", "local_host": "127.0.0.1", "local_port": 3000, "subdomainOrPath": "myapi" } ]これを環境変数として設定するには、通常、JSON 文字列をコンパクトな形式(改行なし)にし、特定のシェル環境で設定する場合は適切にエスケープする必要があります。たとえば、
.envファイルまたはシェルでは次のように指定します。DOROSEEK_AGENT_SERVICES_JSON='[{"id":"web1","name":"My Local Web Server","type":"http","local_host":"localhost","local_port":8080,"subdomainOrPath":"myweb"},{"id":"api2","name":"Backend API","type":"http","local_host":"127.0.0.1","local_port":3000,"subdomainOrPath":"myapi"}]'
-
エージェントモードでの実行
- 上記に記載されている必須の環境変数をすべて設定します。
DOROSEEK_AGENT_MODE_ENABLEDが"true"に設定されていることを確認してください。 - 標準コマンドを使用してアプリケーションを実行します。
deno task start - 設定が有効な場合、
Doroseekはエージェントモードで起動します。通常の Fresh サーバーの起動ログ(例:「Listening on http://localhost:8000/」)は表示されません。 - 代わりに、次のようなエージェントモードの動作を示すログメッセージを確認します。
[Main] Doroseek starting in Agent Mode.[Agent Config] Agent configuration loaded successfully.[Agent Connector] Initialized with Relay URL: wss://your-remote-doroseek.com/mcp/tunnel/register[Agent Connector] Attempting to connect to ...[Agent Connector] WebSocket connection established.[Agent Connector] Sent registration request: ...[Agent Connector] Successfully registered. Tunnel ID: <your-tunnel-id>, Public URL: <your-public-base-url>[Main] Agent is connected and registered with the relay.[Main] Tunnel ID: <your-tunnel-id>[Main] Public Base URL: <your-public-base-url>- Service 'My Local Web Server' (web1) accessible via: <your-public-base-url>/myweb- Service 'Backend API' (api2) accessible via: <your-public-base-url>/myapi
リレーとのやり取り(エージェントの視点)
- エージェント(エージェントモードで実行されるこの
Doroseekインスタンス)は、DOROSEEK_RELAY_URLに WebSocket 接続を確立します。この URL は、サーバーモードで実行されるリモートのDoroseekインスタンスの/mcp/tunnel/registerエンドポイントを指定する必要があります。 DOROSEEK_AGENT_SERVICES_JSONで定義されたローカルサービスの詳細を含む登録メッセージを送信します。- 登録が成功すると、リモートのリレーサーバーはエージェントに一意の
tunnelIdとpublic_base_urlを提供します。 - その後、リレーサーバーがトンネルに一致するパブリック HTTP リクエストを受信すると、確立済みの WebSocket トンネルを介して、これらのリクエストを(
httpRequestメッセージとして)エージェントに転送します。 - エージェントはこれらの
httpRequestメッセージを処理し、設定済みのローカルサービスにリクエストを送り、httpResponseメッセージをリレーに返します。 - また、エージェントはリレーからの
pingメッセージにpongメッセージで応答し、自身の状態と主要なローカルサービスの健全性を示します。
トンネルのヘルスチェック API
確立済みのトンネルと、その基盤となるローカルサービスのステータスを監視するため、Doroseek はヘルスチェック API エンドポイントを提供します。
-
エンドポイント:
GET /tunnel/:tunnelId/status -
説明: このエンドポイントを使用すると、
:tunnelIdで識別される特定のトンネルの現在のステータスを確認できます。リレーからローカルエージェントへの WebSocket 接続と、エージェントが設定済みのローカルサービスにアクセスできるかどうかの両方をチェックします。 -
認証: このエンドポイントでは現在、特定の API キー認証は必要ありませんが、
tunnelIdは有効で、システムに登録されている必要があります。必要に応じて、標準的なリバースプロキシやゲートウェイの仕組みを利用して、アクセス制御を追加できます。 -
レスポンス本文(
HealthStatusReport): API は、次の構造を持つ JSON オブジェクトを返します。{ "tunnelId": "string", // チェック対象のトンネル ID "tunnelStatus": "connected" | "disconnected" | "unknown", "localServiceStatus": "ok" | "error" | "unconfigured" | "timeout" | "unknown" | "agent_unresponsive", "checkedByInstanceId": "string", // チェックを実行/報告したリレーインスタンスの ID "timestamp": "string" // チェックが実行された時刻の ISO 8601 タイムスタンプ }tunnelId:チェック対象のトンネル ID です。tunnelStatus:"connected":リレーサーバーが、このトンネルのローカルエージェントとアクティブな WebSocket 接続を確立しています。"disconnected":リレーサーバーは、ローカルエージェントとのアクティブな WebSocket 接続を確立していません。"unknown":トンネルのステータスを判定できませんでした(例:プライマリデータベースにトンネル ID が見つからない場合)。
localServiceStatus:"ok":ローカルエージェントがヘルスチェックの ping に応答し、主要な設定済みローカルサービスに到達可能であると報告しました。"error":ローカルエージェントは応答しましたが、ローカルサービスのチェック中にエラーが発生したと報告しました。"unconfigured":ローカルエージェントは応答しましたが、チェック対象のローカルサービスが設定されていないか、サービスの種類がエージェントによるチェックに対応していません。"timeout":ローカルエージェントは応答しましたが、ローカルサービスのチェックがタイムアウトしました。"agent_unresponsive":リレーサーバーはエージェントに接続していますが、エージェントは所定の時間内にヘルスチェックの ping に応答しませんでした。"unknown":ローカルサービスのステータスを判定できませんでした(例:tunnelStatusが"connected"ではない場合)。
checkedByInstanceId:ヘルスステータスを判定した、または最後に報告したリレーサーバーインスタンスの一意の ID です。複数インスタンス構成で役立ちます。timestamp:ヘルスステータスが判定された時刻の ISO 8601 タイムスタンプです。
-
使用例: リクエスト:
GET /tunnel/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/statusレスポンス例:
{ "tunnelId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "tunnelStatus": "connected", "localServiceStatus": "ok", "checkedByInstanceId": "yyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy", "timestamp": "2023-10-27T10:30:00.000Z" }別の例(エージェントは接続されていますが、ローカルサービスは停止しています):
{ "tunnelId": "zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz", "tunnelStatus": "connected", "localServiceStatus": "error", "checkedByInstanceId": "wwwwwww-wwww-wwww-wwww-wwwwwwwwwwww", "timestamp": "2023-10-27T10:35:00.000Z" }
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。