Keystash について
Keystashは、AIエージェントやコマンドラインのワークフロー向けのmacOS用シークレット管理ツールです。値はログインキーチェーンに保管し、エージェントはメタデータや許可された操作を通じて管理します。MCPインターフェースにシークレット値を読み取ったり返したりするツールはありません。
主な機能
- 01値をmacOSログインキーチェーンに保管
- 02シークレットのメタデータと更新時期の管理
- 03シークレットの生成と置き換え
- 04許可リスト内のURLで認証情報を使用
- 05認証情報を使ったリクエストの監査
- 06stdioで6つのMCPツールを提供
活用シーン
- 01キーを見せずにエージェントから許可済みAPIを呼び出す
- 02チャットやファイルの外で認証情報を保管・更新
- 03更新時期を過ぎた項目の確認
- 04保存済み認証情報を使ったリクエストの監査
MCP 対応
`keystash mcp`はstdio経由で、シークレットの一覧表示、保存、更新、生成、使用、削除を行う6つのツールを提供します。MCPツールが値を返すことはなく、`secret_use`は各項目で許可されたURLにのみ認証情報を送信します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
6掲載時のツール一覧 · 2 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| tag | string | いいえ | このタグが付いたエントリのみを返します。 |
| name | string | いいえ | このエントリのみを返します。 |
詳細
keystash 🔑
値はキーチェーンに保管し、AI には参照名だけを渡します。 キーチェーンが値を保管し、AI エージェントが受け取るのは参照名だけです。
keystash を使うと、AI アシスタント(MCP、Claude Code、あらゆるエージェント)が API キー、トークン、パスワードを管理できます。
その中身を見ることはできません。
v0.4.0 以降、値は macOS のログインキーチェーンに保管され、ディスク上に残るのはメタデータだけです。また、全体を通して read ツールはありません。どのインターフェースからも AI に秘密情報が渡されることはありません。
ひと言で言えば、このバージョンの安全性は「read ツールがない」ことと「全体を通して平文の出力経路がない」ことによるもので、「何らかの暗号化を使っている」ことによるものではありません。
English
keystash を使う理由
よくあるアドバイスの「API キーをチャットに貼り付けない」は、エージェントが役立つようになった日から通用しなくなりました。OPENAI_API_KEY を読み取れないエージェントは、そのキーをローテーションできず、あなたに代わって API を呼び出すことも、来月期限が切れるキーを教えることもできません。
目指すのは「エージェントにキーを一切触らせない」ことではありません。エージェントが見られないキーを管理することです。
- 値は macOS のログインキーチェーンに保存されます。このツールが管理するファイルに書き込まれたり、表示されたり、いずれかの API から返されたりすることはありません。
- ディスクに保存されるのはメタデータ(名前、タグ、ローテーションスケジュール、許可された URL)だけで、平文の 0600 JSON 形式です。メタデータは意図的に秘密情報ではないため、一覧表示や編集にロック解除は不要です。
secret_readツールはなく、値を標準出力に表示する CLI コマンドもありません。無効化されたフラグがあるのではなく、そのコードパス自体が存在しません。- 外部に接続できる唯一の経路である
secret_useがアクセスできるのは、エントリーごとに事前承認した URL だけです。
クイックスタート
pip install keystash # or: uv tool install keystash
keystash doctor # check Keychain / osascript / security / pbcopy
# Store a key. The value is typed into a native hidden dialog — never argv, never the shell history.
keystash add OPENAI_PROD_KEY -a https://api.openai.com/ -r 90
# Let keystash invent one instead; it prints a fingerprint, never the value.
keystash generate STRIPE_PROD_SECRET -a https://api.stripe.com/ -r 180
# generated STRIPE_PROD_SECRET sha256:1f3a9c02 (43 chars)
keystash list # metadata only
keystash list --json
keystash use OPENAI_PROD_KEY https://api.openai.com/v1/models
keystash rm OPENAI_PROD_KEY
値をパイプで渡す場合(CI、別のボールト、パスワードマネージャーからのエクスポートなど)は、ダイアログを省略できます。
printf '%s' "$VALUE" | keystash add MY_SERVICE_PROD_KEY --stdin -a https://api.myservice.com/
命名規則:SERVICE_ENV_PURPOSE — OPENAI_PROD_KEY、ALIYUN_OSS_STAGING_SECRET。
次の形式が適用されます:^[A-Z][A-Z0-9_]{0,63}$。
Touch ID によるロック解除
値はログインキーチェーンに保存されます。keystash copy NAME を実行すると、値がクリップボードにコピーされ、30 秒後に消去されます(--clear-after 0 を指定すると消去されません)。値が表示されることはありません。
Touch ID のプロンプトが表示されるのは、実際に値が必要なときだけです。list、show、doctor の実行時や、メタデータの編集時には表示されません。
keystash doctor — すでにある問題を整理する
keystash doctor は、プラットフォーム、キーチェーンバックエンドが利用可能かどうか、osascript/security/pbcopy のパス、メタデータファイル、監査ログ、レガシーボールトのパスを報告します。
メタデータファイルが存在する場合は、エントリー数と、ローテーション間隔を過ぎているエントリーも表示します。
AI エージェント向け、平文ゼロ:keystash mcp
keystash mcp は stdio のみ で MCP を提供します。ソケットは一切開かず、127.0.0.1 でも開きません。
公開するツールは正確に6つです。secret_read も run_command もありません。
| ツール | 内容 | AI に値が見えますか? |
|---|---|---|
secret_list | エントリーの一覧表示:名前、タグ、ローテーション日、許可 URL | いいえ — メタデータのみ |
secret_store | ユーザーがダイアログに入力した値を保存 | いいえ |
secret_rotate | 同じ方法で値を置き換え | いいえ |
secret_generate | 強力な値を生成して保存 | いいえ — フィンガープリントが返されます |
secret_use | 許可された URL を認証情報付きで呼び出し、応答を返す | いいえ — キーはリクエストヘッダーにとどまります |
secret_delete | ネイティブダイアログで確認した後、エントリーとその Keychain アイテムを消去 | いいえ |
MCP クライアントに接続します。
{
"mcpServers": {
"keystash": {
"command": "keystash",
"args": ["mcp"],
"env": { "KEYSTASH_META": "/Users/you/.keystash/entries.json" }
}
}
}
secret_use について知っておくべきことは3つあります。
- エントリーごとの許可リスト。 各エントリーには
allowed_urlsがあり、URL はそのいずれかにプレフィックス一致する必要があります。https://api.openai.com.evil.com/はhttps://api.openai.com/に一致しません。 また、プレフィックス一致を使うため、エントリーの末尾は/にする必要があります。許可リストが空の場合はすべて拒否されます — AI は宛先ホストを選べないため、secret_useがデータ流出の手段になることはありません。 - リダイレクトは拒否され、追跡されません(
allow_redirects=False)。そのため、許可されたホストが認証情報を別の場所に転送することはできません。 - レスポンス本文はモデルに渡される前に、値とそのエンコード形式(生データ、base64、URL エンコード、16進数)を対象にスクラブされ、20 000 文字で切り詰められます。
secret_use を呼び出すたびに、監査ログ(~/.keystash/audit.log、モード 0600)に1行追加されます。記録されるのはタイムスタンプ、エントリー名、メソッド、URL、HTTP ステータスです。誰が何を呼び出したかを記録し、値は記録しません。
コマンド
| コマンド | 目的 |
|---|---|
keystash list [-t TAG] [--json] | エントリーを一覧表示(メタデータのみ) |
keystash show NAME | 1つのエントリーのメタデータを表示 |
keystash add NAME [-t TAG] [-r DAYS] [-a URL] [--auth-header H] [--auth-prefix P] [--stdin] [--force] | 新しいシークレットを保存 |
keystash rotate NAME [--stdin] | メタデータを維持したまま値を置き換え |
keystash generate NAME [-t TAG] [-r DAYS] [-a URL] [-l LEN] | 生成して保存(16~128文字、デフォルトは43文字) |
keystash edit NAME [-t TAG] [-r DAYS] [-a URL] | メタデータのみ — 値の読み取りや書き換えは行いません |
keystash copy NAME [--clear-after SECONDS] | クリップボードにコピーし、自動消去(デフォルトは30秒) |
keystash use NAME URL [-X METHOD] [-d BODY] [--timeout SECONDS] | 許可リストに登録された URL を呼び出し |
keystash rm NAME [--yes] | エントリーとその Keychain アイテムを削除 |
keystash migrate [-s VAULT] [--verify/--no-verify] [--retire-vault] | v0.3 の暗号化済み Vault を Keychain に移行 |
keystash doctor | このマシンの前提条件を確認 |
keystash mcp | MCP stdio インターフェースを提供 |
v0.3 からの移行
v0.3 では、すべての値を 1 つの PBKDF2 + Fernet ボールトファイルに保存していました。migrate はそのボールトを一度読み込み、各値を Keychain に書き込みます。
keystash migrate -s ~/keystash-vault.json --retire-vault
以前のマスターパスワードは、v0.3 と同じ方法で取得します。まず KEYSTASH_MASTER_PASSWORD が設定されていればそれを使い、次にログイン Keychain(サービス keystash、アカウントはボールトの絶対パスです。v0.3 が書き込んだ項目なので、手動でパスワードを入力したことがない場合でも、入力する必要はありません)を確認し、最後に非表示のプロンプトを表示します。値はメモリ内だけを経由します。
出力されるのは、旧名/新名/タグ/検証結果の表だけです。--verify(デフォルトで有効)は、移行済みと判断する前に各値を Keychain から読み戻して照合するため、Keychain の障害に気づかずキーを失うことはありません。--retire-vault を指定すると、完全に成功した実行の後、古いファイルの名前を *.migrated に変更します。削除はされません。すべてのエントリーを確認するまで、このファイルは保管してください。
移行では、すべてのエントリーの allowed_urls は意図的に空のままです。そのため、ホストを許可するまで secret_use はすべてのアクセスを拒否します。許可するには、keystash edit NAME --allow https://api.example.com/ を実行します(末尾のスラッシュが必要です)。追加したプレフィックスのみアクセスできます。
複数マシン間の同期
メタデータファイルは通常の JSON です。好みの方法で同期できます。値は同期されません。値はこの Mac のログイン Keychain に保存されており、それが本来の目的です。2 台目のマシンでは、各値を再入力するか、keystash add --stdin を一度ずつ実行してから、メタデータファイルをコピーしてください。
セキュリティモデル
このツールを信頼する前に、このセクションをお読みください。
keystash がなくすもの。 平文の一覧です。以前は、キーが ~/.zshrc、.env ファイル、シェル履歴、チャットログ、MCP のトランスクリプト、クリップボードの過去の内容に含まれていました。現在は、AI が読み取るツールを持たない 1 か所に保存され、どのコマンドもキーを出力しません。
keystash がしないこと。 Keychain に保存する場合、保存時の暗号化は OS の役割であり、その下層にあるのはログインセッションです。具体的には、次のとおりです。
- あなたのユーザーとして実行されているプロセスは、すべて同じ値を読み取れます。
security find-generic-password -s keystash -a OPENAI_PROD_KEY -wは、同じユーザーのシェルならどこからでも実行できます。keystash はアカウントの侵害を防御せず、そのような防御を主張するものでもありません。 - 境界となるのは同一ユーザーのプロセス分離であり、暗号化ではありません。 keystash が平文を取り除くのは、ファイル、ログ、トランスクリプト、argv、環境変数といった成果物からであり、信頼されたプロセスのメモリからではありません。
- メタデータは秘密ではありません(通常の 0600 JSON です)。名前、タグ、ローテーション日、許可された URL は、ホームディレクトリを読み取れる人なら誰でも確認できます。名前から意図が漏れることもあります(「ALIYUN_PROD_KEY」なら、攻撃者はどこを探せばよいか分かります)。タグに秘密を入れないでください。
- サニタイズは固定されたエンコーディングの集合(raw、base64、urlsafe-base64、percent-encoded、hex)に対する文字列の置換です。 別の方法で再エンコードされた値(暗号化、複数行への分割、文字のシフトなど)は、サニタイズをすり抜ける可能性があります。8 文字未満の値は文字列そのものが確実に伏せ字になりますが、エンコードされた形式は伏せ字にならないため、短い秘密は一部しか保護されません。
- ローテーションはリマインダーであり、強制ではありません。
-r DAYSを指定すると、doctorと MCP のsecret_listが期限切れのエントリーにフラグを付けます。自動でローテーションされることはありません。 - リクエストに注入された秘密は、原則として同一ユーザーのプロセスから確認できます。 これも前述と同じ境界によるものです。
AI が引き続きできること。 エントリー名の一覧表示、エントリーの削除、保存された認証情報を使った許可済み URL へのアクセス(および応答の読み取り)、さらに新しい値(AI が作り出した値も含む)の保存が可能です。secret_delete と許可リストは、一度設定したら放置するものではなく、確認する対象として扱ってください。監査ログをお読みください。
keystash が取り除くのは平文であり、信頼ではありません。
環境変数
| 変数 | 意味 | デフォルト |
|---|---|---|
KEYSTASH_META | メタデータファイルのパス | ~/.keystash/entries.json |
KEYSTASH_VAULT | 旧 v0.3 ボールトのパス — migrate でのみ使用 | ~/.keystash/vault.json |
--meta/-m と --vault/-V のフラグで上書きできます。
開発
git clone https://github.com/thu-lawyer/keystash.git
cd keystash
pip install -e ".[dev]"
pytest -q # the real Keychain is never touched
ruff check src tests
テストスイートは CLI をサブプロセスとして実行し、インメモリストアを注入するため、Keychain がなくても Linux と Windows の CI でパスします。実際のログイン Keychain に触れる唯一のテストを実行するには、KEYSTASH_TEST_KEYCHAIN=1 を設定してください。
ライセンス
MIT
中国語
keystash を選ぶ理由
「API key を会話に貼り付けない」という助言は、エージェントが役に立つようになった時点で通用しなくなります。
OPENAI_API_KEY を読み取れないエージェントは、そのローテーションを手伝うことも、代わりに API を呼び出すことも、来月どの key が期限切れになるかを説明することもできません。
したがって、目標は「エージェントに決してシークレットを触れさせない」ことではなく、エージェントが見えないシークレットを管理できるようにすることです。
- 値は macOS ログインキーチェーンに保存され、本ツールが所有するファイルには書き込まれず、出力もされず、いかなる API からも返されません。
- ディスク上にあるのはメタデータ(名前、タグ、ローテーション周期、許可された URL)のみで、0600 の平文 JSON です。 メタデータは意図的にシークレットとはみなされません。そのため、一覧表示や編集にロック解除は不要です。
secret_readツールはなく、値を stdout に出力する CLI コマンドもありません。 「オフにされた機能」ではなく、そのコードパス自体が存在しません。- 外部につながる唯一の経路である
secret_useがアクセスできるのは、各エントリーに事前登録した URL のみです。
クイックスタート
pip install keystash # 或:uv tool install keystash
keystash doctor # 检查 Keychain / osascript / security / pbcopy
# 存一个 key。值在系统隐藏输入框里手打 —— 不走 argv,不进 shell 历史。
keystash add OPENAI_PROD_KEY -a https://api.openai.com/ -r 90
# 也可以让 keystash 生成;它只打印指纹,不打印值。
keystash generate STRIPE_PROD_SECRET -a https://api.stripe.com/ -r 180
# generated STRIPE_PROD_SECRET sha256:1f3a9c02 (43 chars)
keystash list # 只有元数据
keystash list --json
keystash use OPENAI_PROD_KEY https://api.openai.com/v1/models
keystash rm OPENAI_PROD_KEY
パイプから値を渡す場合(CI、他のパスワードマネージャーからのエクスポートなど)は、ポップアップを省略できます。
printf '%s' "$VALUE" | keystash add MY_SERVICE_PROD_KEY --stdin -a https://api.myservice.com/
命名規則:SERVICE_ENV_PURPOSE —— OPENAI_PROD_KEY、ALIYUN_OSS_STAGING_SECRET。
次の形式が必須です:^[A-Z][A-Z0-9_]{0,63}$。
Touch ID によるロック解除
値はログインキーチェーンに保存されます。keystash copy NAME は値をクリップボードにコピーし、30 秒後に自動で消去します(消去を無効にするには --clear-after 0 を指定します)。
何も出力しません。 Touch ID のプロンプトが表示されるのは、値を実際に取得するときだけです。list、show、doctor、メタデータの変更では表示されません。
keystash doctor —— すでにまき散らした平文を積極的に一掃します
keystash doctor は、プラットフォーム、Keychain バックエンドが利用可能かどうか、osascript / security / pbcopy のパス、
メタデータファイル、監査ログ、旧バージョンの vault のパスを報告します。メタデータファイルが存在する場合は、エントリーの総数とローテーション期限を過ぎたエントリーも表示します。
AI アシスタントによる平文ゼロの管理:keystash mcp
keystash mcp は stdio のみを使用し、ポートは一切開きません(127.0.0.1 でさえ開きません)。
公開するツールはちょうど 6 つで、secret_read も run_command もありません。
| ツール | 内容 | AI に値が見えますか? |
|---|---|---|
secret_list | エントリーを一覧表示します:名前、タグ、ローテーション日、許可された URL | いいえ —— メタデータのみです |
secret_store | ユーザーがポップアップで手入力した値を保存します | いいえ |
secret_rotate | 同じ方法で値を置き換えます | いいえ |
secret_generate | 強力なランダム値を生成して保存します | いいえ —— 指紋のみを返します |
secret_use | 認証情報を付けて許可された URL を呼び出し、レスポンスを返します | いいえ —— key はリクエストヘッダー内にのみ存在します |
secret_delete | ネイティブのポップアップで確認した後、エントリーとそのキーチェーン項目を削除します | いいえ |
MCP クライアントに接続します。
{
"mcpServers": {
"keystash": {
"command": "keystash",
"args": ["mcp"],
"env": { "KEYSTASH_META": "/Users/you/.keystash/entries.json" }
}
}
}
secret_use について、知っておくべき点が 3 つあります。
- エントリーごとの許可リストです。 各エントリーには
allowed_urlsがあり、URL はその中のいずれかのプレフィックスと一致する必要があります。https://api.openai.com.evil.com/はhttps://api.openai.com/とは一致しません。 これが、プレフィックス一致の許可リスト項目で末尾に/を必須にしている理由です。許可リストが空の場合はすべて拒否します。 AI は宛先ホストを自由に選べないため、secret_useがデータ持ち出し経路になることはありません。 - リダイレクトには追従しません(
allow_redirects=False)。許可されたホストが認証情報を別の場所へ転送することはできません。 - レスポンス本文はモデルに返す前にサニタイズされます(値そのものと、その raw / base64 / URL エンコード / hex 形式)。また、20 000 文字で切り詰められます。
secret_use を実行するたびに、監査ログ(~/.keystash/audit.log、0600)に 1 行追記されます。
記録されるのは、タイムスタンプ、エントリー名、メソッド、URL、HTTP ステータスです。いつ誰がどの key を使ったかだけを記録し、値は決して記録しません。
コマンド一覧
| コマンド | 説明 |
|---|---|
keystash list [-t TAG] [--json] | エントリーを一覧表示します(メタデータのみ) |
keystash show NAME | 単一エントリーのメタデータを表示します |
keystash add NAME [-t TAG] [-r DAYS] [-a URL] [--auth-header H] [--auth-prefix P] [--stdin] [--force] | 新しいシークレットを保存します |
keystash rotate NAME [--stdin] | 値を置き換え、メタデータは保持します |
keystash generate NAME [-t TAG] [-r DAYS] [-a URL] [-l LEN] | 生成して保存します(16~128 文字、デフォルトは 43) |
keystash edit NAME [-t TAG] [-r DAYS] [-a URL] | メタデータのみを変更します —— 値の読み取りや書き換えは行いません |
keystash copy NAME [--clear-after SECONDS] | クリップボードにコピーして自動で消去します(デフォルトは 30 秒) |
keystash use NAME URL [-X METHOD] [-d BODY] [--timeout SECONDS] | 許可リストにある URL を呼び出します |
keystash rm NAME [--yes] | エントリーとそのキーチェーン項目を削除します |
keystash migrate [-s VAULT] [--verify/--no-verify] [--retire-vault] | v0.3 の暗号化 vault をキーチェーンに移行します |
keystash doctor | ローカルの前提条件を確認します |
keystash mcp | MCP stdio インターフェースを提供します |
v0.3 からの移行
v0.3 では、すべてのデータが PBKDF2 + Fernet の vault ファイル 1 つに保存されていました。migrate はその vault を一度読み込み、各値をキーチェーンに書き込みます。
keystash migrate -s ~/keystash-vault.json --retire-vault
旧マスターパスワードの取得方法は v0.3 と同じです。まず KEYSTASH_MASTER_PASSWORD を確認し、次にログインキーチェーンを検索します
(service keystash、account = 旧 vault の絶対パスです。これは v0.3 が当時書き込んだ項目なので、これまでパスワードを手入力したことがない人も、今後入力する必要はありません)。
最後に、非表示のウィンドウを表示して手入力を求めます。値はメモリ内のみを通過します。
出力は、旧名/新名/タグ/検証済みの一覧表のみです。
--verify(デフォルトで有効)は、各値をキーチェーンから読み戻して照合し、一致を確認してから移行成功とします。
これにより、キーチェーンが無言で失敗して key が失われることもありません。--retire-vault は、移行全体が成功した後にのみ旧ファイルの名前を *.migrated に変更し、削除はしません。すべてのエントリーを確認するまでは、そのファイルを残しておいてください。
移行後、各エントリーの allowed_urls は空になっています(意図的な設定です)。ホストを許可するまでは、secret_use は常に拒否されます:
keystash edit NAME --allow https://api.example.com/(末尾の / は必須です)。追加したプレフィックスにのみアクセスできます。
複数マシン間の同期
メタデータは平文 JSON なので、好きな方法で同期できます。値は同期されません。この Mac のログインキーチェーンに保存されており、それがまさに意図した動作です。2 台目のマシンで値を再登録する(または keystash add --stdin で一度渡す)と、メタデータファイルをコピーしてください。
安全模型
信这个工具之前,请读完这一段。
keystash 消掉了什么。 明文清单。过去你的 key 散在 ~/.zshrc、.env、shell 历史、
对话记录、MCP 转录、剪贴板的历史里。现在它们在一个地方,AI 没有工具能读,也没有命令会打印。
它不做什么。 值放在钥匙串里,静态加密是操作系统的活,而它下面那一层是你的登录会话。具体说:
- 任何以你的身份运行的进程都能读到同样的值。 在同一个用户下的任意 shell 里,
security find-generic-password -s keystash -a OPENAI_PROD_KEY -w就能取出来。 keystash 不防「账号已被攻破」,也不声称能防。 - 边界是「同用户进程隔离」,不是「加密」。 keystash 把明文从产物里去掉 —— 文件、日志、转录、argv、环境变量 —— 而不是从一个受信任进程的内存里去掉。
- 元数据不是秘密(0600 明文 JSON):名字、标签、轮换日期、允许的 URL,
能读你家目录的人都能读。名字本身就泄露意图(
ALIYUN_PROD_KEY直接告诉攻击者去哪儿找)。 不要把秘密写进标签。 - 擦洗是「固定编码集合上的字面替换」(raw、base64、urlsafe-base64、百分号编码、hex)。 值若被换成别的编码形态 —— 加密、跨行拆开、字符位移 —— 可能活下来。 短于 8 个字符的值仍会被原样擦除,但不做编码变体扩展,所以短密钥只被部分覆盖。
- 轮换是提醒,不是强制。
-r DAYS只让doctor和 MCP 的secret_list标出逾期条目, 没有任何自动轮换。 - 注入请求的密钥原则上对同用户进程可见,与上面同一条边界。
AI 仍然能做什么。 它能列出你的条目名、删除条目、用存好的凭据调白名单内的 URL
(并读到响应)、以及存新值(包括它自己生成的)。
把 secret_delete 和白名单当成需要你复核的东西,而不是设一次就完事的东西。审计日志要读。
keystash 消掉的是明文,不是信任。
环境变量
| 变量 | 含义 | 默认 |
|---|---|---|
KEYSTASH_META | 元数据文件路径 | ~/.keystash/entries.json |
KEYSTASH_VAULT | 旧版 v0.3 vault 路径 —— 只有 migrate 会读 | ~/.keystash/vault.json |
--meta/-m 与 --vault/-V 可覆盖它们。
参与开发
git clone https://github.com/thu-lawyer/keystash.git
cd keystash
pip install -e ".[dev]"
pytest -q # 不会碰真实钥匙串
ruff check src tests
测试以子进程方式驱动 CLI,并把存储换成内存实现,所以在无钥匙串的 Linux / Windows CI 上也能过。
设 KEYSTASH_TEST_KEYCHAIN=1 才会启用唯一那个会碰真实登录钥匙串的测试。
License
MIT
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。