mcpField
N
Neutra

Neutra

リモート
github.com/emokeo生産性01 週間前に更新
リポジトリ

Neutra について

Neutraは、双方の空き時間を相手に明かさずに、2人のAIアシスタントが面会を調整できるリモートサービスです。時間帯を照合して共通のカレンダー招待を送り、片方はアシスタントを使わずGoogleログインのページから回答できます。

主な機能

  1. 01双方の空き時間の照合
  2. 02共通のカレンダー招待の送信
  3. 03双方の時間情報の保護
  4. 04アシスタント不要のウェブ回答
  5. 05確定後の予定データ削除

活用シーン

  1. 01異なるアシスタント間での面会調整
  2. 02アシスタントを使わない人への招待
  3. 03カレンダーを共有せずに予定を調整

MCP 対応

NeutraはGoogleログインに対応するリモートMCPサーバーです。予定調整の作成と回答、状態確認、キャンセルのツールを提供します。

設定

リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。

エンドポイントhttps://neutra.day/mcp
インストールコマンドをコピー
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。

ツール

詳細

Neutra

人々の AI アシスタントが、互いのデータを見ずに、持ち主に代わって合意できる中立的な場所です。

現在できることは 1 つです。2 人のアシスタントが、会う時間を見つけます。それぞれのアシスタントが、持ち主の空いている時間を Neutra に伝えます。Neutra は共通の時間を見つけ、2 人にカレンダーの招待を 1 件送ります。どちらも、相手の空いている時間を見ることはありません。

sequenceDiagram
    participant A as Anna's assistant
    participant N as Neutra
    participant B as Ben's assistant
    A->>N: Anna's free times
    N-->>A: a message for Anna to forward to Ben
    Note over A,B: Anna forwards it in any chat
    B->>N: Ben's free times + the code
    N-->>A: calendar invite
    N-->>B: calendar invite

異なるアシスタント間でも利用できます。Anna が Claude を使い、Ben が別のアシスタントを使っていても、両方が MCP コネクターに対応していれば動作します。Ben はアシスタントを使わずに回答することもできます。メッセージには、Google でサインインして空いている時間を追加できるシンプルなページへのリンクが含まれます。

プライバシーを設計に組み込む

  • Neutra 側では AI を使いません。 Neutra は時間帯を比較するだけのシンプルなコードです。あなたの空いている時間が、Neutra の AI モデルに渡されることはありません。
  • 誰も相手の空いている時間を見ることはありません。 返されるのは、両者に合う会議時間だけです。相手の空いている時間が返されることはなく、コードはハッシュとしてのみ保存されます。
  • 時間は、決定が確定するとすぐに削除されます。 遅くとも 14 日後には削除されます。回答する人の空いている時間は、そもそも保存されません。
  • 再試行しても、カレンダーの空き状況を探ることはできません。 回答する人が試せるのは最大 3 回です。また、各回答で指定する時間は、会議の長さの少なくとも 2 倍必要なため、空き時間を 1 つずつ探ることはできません。
  • データは EU 内に留まります。 Cloudflare の EU 管轄内で処理されます。
  • テストで確認済みです。 test/decisions.test.ts では、どのレスポンスにも時間やコードが含まれないことを検証しています。

詳細:プライバシーページ。

試してみる

  1. Claude の場合:コネクタディレクトリで Neutra を開き、Connect を選択します。他のアシスタントの場合は、カスタムコネクターとして https://neutra.day/mcp を追加します。
  2. Google でサインインします。Neutra が使用するのはあなたの名前とメールアドレスだけです。招待を正しい宛先に送信するためと、あなたのみが回答できるようにするためです。
  3. 次のように依頼します。「Neutra を使って、来週 Ben と 1 時間会う時間を見つけてください。火曜日と木曜日の 18:00~21:00 が空いています。」 返されたメッセージを転送します。

エージェントの開発者向け

Google サインインに対応したリモート MCP サーバーです。リソースはGoogle の AIP に準拠しています:decisions/{decision} と decisions/{decision}/answers/{answer}。

ツール内容
create_decision持ち主の空いている時間と会議の長さを指定して、調整を開始します。コードと転送用のメッセージを返します。
create_answerメッセージに記載されたコード(neutra:<id>.<code>)と、持ち主の空いている時間を指定して回答します。双方に合う時間が見つかると、招待が送信されます。
get_decisionステータス(WAITING、NO_MATCH、INVITE_SENT、ACCEPTED、DECLINED、EXPIRED)と会議時間を取得します。
delete_decision開始した調整を、招待も含めてキャンセルします。
get_answer自分の回答を読み取ります。
create_feature_requestNeutra ではまだできないことで、持ち主が望んでいたことを Neutra の開発者に伝えます。
get_feature_request送信した機能リクエストを読み取ります。
価格の合意(デフォルトでは無効)

2人が、互いの上限を知らないまま、価格(家賃、売買価格、料金)に合意します。価格の合意は決定の一種です。開始者のアシスタントは、decision.price(件名、詳細、currencyCode、単位、answerBy)を指定してcreate_decisionを呼び出し、starterAnswer.priceには1つの数値を設定します。お金を受け取る側ならminimumToAccept、支払う側ならmaximumToPayを指定します。相手側はcreate_answerとanswer.priceを使って回答します。通貨は常に決定で指定されたものを使用します。支払う側の上限が受け取る側の最低額以上なら取引が成立し、そうでなければ両者には「取引不成立」とだけ通知されます。結果は両者にメールで届きます。

decision.price.ruleは、合意できる範囲内のどの価格で取引が成立するか、またその結果何が明らかになるかを指定します。

ルール価格取引成立時に明らかになること
MIDPOINT(デフォルト)数値が重なる範囲の中央双方が相手の数値を推測できます
LOWEST受け取る側の最低額支払う側にはその額が分かります。支払う側の数値は非公開のままです
HIGHEST支払う側の上限額受け取る側にはその額が分かります。受け取る側の数値は非公開のままです
MIDPOINT_ROUNDED中央の値をroundToに丸めた額(デフォルトでは開始者の数値のおよそ1%)。重なる範囲内に収められます双方の数値がおおよそ分かるだけです
RANDOM重なる範囲内から一様ランダムに選んだ値相手の数値が価格を上回る、または下回ることだけが分かります
OVERLAP_ONLYなし。結果は「数値が重なっています」または「重なっていません」のみです(給与、初期選考など)何も分かりません。どちらの数値も明らかになりません

decision.price.maxAnswers(1〜3、デフォルトは1)は、相手側が送信できる数値の回数です。取引が成立しなかった後も回答回数が残っていれば、相手側が再度回答できるようリクエストは開いたままになります。開始者には不成立だった試行の内容は一切表示されません。回答する人には、回答前にルールの平易な説明(ruleText)と回答可能回数が、引き継ぎメッセージ、プレビュー、ウェブページに表示されます。

  • 回答する人の数値は、試行の間も含め、一切保存されません。開始者の数値は、リクエストコードから生成したキー(ハッシュのみ保存)で暗号化され、リクエストが解決または終了するとすぐに消去されます。
  • codeを指定したget_decisionは、回答する前にリクエストの内容を確認するためのpreviewを返します(yourSideがPAYSの場合はmaximumToPay、RECEIVESの場合はminimumToAcceptを送信します)。回答回数は消費されません。
  • 入出力はneutra.v1メッセージ(proto3 JSON)に従います。すべての価格フィールドはpriceの中にあります。例:decision.price.agreedPriceText。
  • 上限は範囲で指定することもできます。例:"10000-20000"(下限のある支払い幅、上限のある価格)。両端が考慮されます。取引成立には双方の範囲が重なる必要があり、ルールに従って重なる範囲内の価格が選ばれます。単一の数値では反対側の端は開いたままです。内側の端は同じ側の端とのみ比較されるため、誇張しても得るものはありません。開始者の範囲の両端は封印され、回答する人の数値は一切保存されません。
  • どちらの呼び出しでもvalidateOnlyを指定すると、何も送信せず、本人が確認できるよう数値を返します。
  • 1人あたり、1日に回答できる価格リクエストは最大3件です(1つのリクエストに対するすべての試行を1件として数えます)。
  • wrangler.jsoncのPRICE_DECISIONSで切り替えます。off(誰にも変更はありません)、testers(ALLOWED_EMAILSに含まれる人だけがcreate_decisionでdecision.priceを指定でき、コードを持つ人は誰でも回答できます)、またはopenです。docs/RUNBOOK.mdを参照してください。

エラーではgoogle.rpcコードを使用します。NOT_FOUND、PERMISSION_DENIED、FAILED_PRECONDITION、INVALID_ARGUMENT、RESOURCE_EXHAUSTED(1日または1時間あたりの上限に達した場合)。

Neutraの実行

Cloudflare WorkersとD1上で動作し、Cloudflareのremote-mcp-google-oauthテンプレートをベースにしています。mainへのプッシュごとに、GitHub Actions(.github/workflows/deploy.yml)が型チェック、テスト、デプロイを実行します。デプロイの前には毎回、migrations/内のマイグレーションが適用されます。変更はプルリクエストを通じて行います。

セットアップ(一度だけ実施)

Cloudflare

  • アカウント ID と MCP_RESOURCE アドレスは wrangler.jsonc にあります。ドメイン neutra.day は、Cloudflare ダッシュボードでカスタムドメインとして Worker に紐付けられています。
  • API トークン:「Edit Cloudflare Workers」テンプレートに加えて D1: Edit を指定します。
  • D1 データベース(EU 管轄)と OAUTH_KV 名前空間は、wrangler d1 create neutra --jurisdiction eu と wrangler kv namespace create OAUTH_KV を使って一度作成済みです。それぞれの ID は wrangler.jsonc にあります。

Google Cloud(プロジェクト neutra)

  • Google Auth Platform:対象ユーザーは External、公開ステータスは In production(テストモードでは更新トークンの有効期限が 7 日になります)。ブランディングには上記のホームページとプライバシーに関するリンクを設定し、承認済みドメインに neutra.day を指定します。
  • リダイレクト URI が https://neutra.day/callback の Web クライアントを作成します。コネクタのサインインとブラウザーの回答ページの両方で使用します(新しい招待者キーを作成するときのみ https://developers.google.com/oauthplayground を追加し、ローカル開発用に http://localhost:8788/callback を追加します)。
  • Google Calendar API と Gmail API を有効にします。
  • サインインで求めるのはメールアドレスとプロフィールのみです。ACCESS_MODE が allowlist の間は、ALLOWED_EMAILS に登録されたメールアドレスのみサインインできます。

招待者([email protected])

  • OAuth 2.0 Playground で、Web クライアント独自の認証情報を使用して、calendar.events と gmail.send スコープを持つ更新トークンを取得します(手順は docs/RUNBOOK.md にあります)。

GitHub シークレット(Settings → Secrets and variables → Actions)

シークレット内容
CLOUDFLARE_API_TOKENCloudflare API トークン
GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRETWeb クライアント
COOKIE_ENCRYPTION_KEY任意の長いランダム文字列
ALLOWED_EMAILSテストユーザーのメールアドレスをカンマ区切りで指定
INVITER_REFRESH_TOKEN招待者の更新トークン
ローカル開発

npm install を実行し、.dev.vars.example を .dev.vars にコピーして値を設定したら、npm run dev を実行します。npx @modelcontextprotocol/inspector@latest で http://localhost:8788/mcp に接続してテストします。

ライセンス

MIT。詳細は LICENSE を参照してください。Cloudflare の MIT ライセンスのテンプレートに含まれるコードを使用しています。

コメント

MCP は初めてですか?

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

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