mcpField
B
Binky

Binky

ローカル
github.com/andreisilva1開発ツール113 週間前に更新

Binky について

BinkyはGit worktreeごとに独立したローカル環境を作り、ポート、環境変数、サービスプロセス、共有データベースなどのリソーススライスを管理します。1台のマシンでコーディングエージェントやブランチを並行して動かすチーム向けです。

主な機能

  1. 01worktreeごとのポート・URL・環境分離
  2. 02サービス別リソーススライスの用意
  3. 03worktreeサービスの起動・停止・確認
  4. 04アドミッション制御とバックグラウンド監視
  5. 05コマンドラインとライブダッシュボード

活用シーン

  1. 01コーディングエージェントをポート競合なく並行実行
  2. 02ブランチごとに独立したデータベーススライスを用意
  3. 03テストやエージェントにworktreeのURLと環境を渡す

MCP 対応

`binky mcp`はstdioでMCPサーバーを実行し、CLIと同じデーモンを使う`up`、`down`、`status`、`env`、`verify`ツールを公開します。

設定

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

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

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

パッケージ
pypibinky0.1.2

ツール

5

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

パラメーター型必須説明
rootstringいいえ
groupstringいいえ
worktreestringはい

詳細

README の画像

Binky

git worktree ごとに独立したローカル環境を用意します。ポート、環境変数、データベース、URL を分離します。

1 台のマシンでコーディングエージェントを並列実行しても、互いに干渉しません。

CI PyPI Python License

ドキュメント · クイックスタート · アダプター · コマンド · エージェント向け · 仕組み · トラブルシューティング


docker-compose は一度に 1 つのプロセスを実行するために作られました。Binky は一度に 15 個のプロセスを実行するために作られています。

ステータス:アルファ版。 worktree の分離、ポート、アダプター、監視、調整、受け入れ制御、プロキシ、HTTPS といった中核機能は、最初から最後まで動作します。設定形式は安定していますが、CLI は今後変更される可能性があります。

問題

同じリポジトリで 3 つのエージェントを動かしているとします。2 つ目が pnpm dev を実行すると EADDRINUSE が発生します。3 つ目がマイグレーションを実行し、1 つ目が読み取り中のテーブルを削除してしまいます。.env ファイルを手作業で編集し始め、気づけば自分がスケジューラーになっています。

Binky がそのスケジューラーになります。エージェントごとに binky up <branch> を実行するだけで、それぞれに専用のポート、データベース、URL が割り当てられます。すべて同じコミット済みの設定から作成されます。

インストール

Binky が実際にテストされている Linux と Windows のどちらかで、Python 3.11 以降と git が必要です。macOS はまだサポート対象ではありません。十分にテストされた移植への貢献を歓迎します。

uv tool install binky          # or: pipx install binky
binky --version

未リリースの main を実行したい場合や、開発に取り組む場合は、クローンからインストールすることもできます。

git clone https://github.com/andreisilva1/binky && cd binky
uv tool install .               # or: pipx install .

ドライバーが必要なアダプターは、追加機能として提供されます。Redis 用に Binky をインストールしても、boto3 はインストールされません。

uv tool install "binky[postgres]"        # or [redis], [mysql], [mongodb], [s3], [kafka]
uv tool install "binky[all-adapters]"    # the whole matrix

クイックスタート

すでに docker-compose.yml がある場合は、そこから始められます。

binky init                 # writes a binky.toml you can read and edit
binky check                # validate it

または、手作業で記述することもできます。設定全体は次のとおりです。

[project]
name = "acme"

[services.web]
cmd = "pnpm dev --port ${self.port}"
url = "web"                              # → web.<worktree>.acme.localhost
depends_on = ["api"]
env = { API_URL = "${api.url}" }

[services.api]
cmd = "go run ./cmd/server"
url = "api"                              # asking for a URL is what asks for a port
depends_on = ["db"]
env = { DATABASE_URL = "${db.url}" }

[services.db]
adapter = "postgres"                     # a private database per worktree
admin_url = "${env.POSTGRES_ADMIN_URL}"
migrate = "make migrate"
seed = "make seed"
clone_from = "golden"                    # migrate+seed once, then copy per worktree

続いて、worktree を並列で起動します。

$ binky up login-fix
  api  pid 16560  :4846
  web  pid 29732  :4504
✓ up: login-fix (2 service(s))

$ binky up checkout-v2
  api  pid 21768  :4137
  web  pid 46336  :4605
✓ up: checkout-v2 (2 service(s))

$ binky status
acme
  checkout-v2  [running]
      api  :4137
      web  :4605
  login-fix  [running]
      api  :4846
      web  :4504

ブランチ 2 つ、プロセス 4 つ、手作業で選ぶ必要のないポート 4 つです。worktree の接続情報を、必要とする相手(シェル、エージェント、テスト実行など)に渡します。

$ binky env login-fix --dotenv
WEB_URL=http://web.login-fix.acme.localhost
API_URL=http://api.login-fix.acme.localhost

残りのライフサイクル操作は次のとおりです。

binky down login-fix       # pause (keeps files + ports); `up` again is instant
binky remove login-fix     # destroy it (refuses if there are uncommitted changes)

ハードコードされた値はなく、実行時に検出されるものもありません。すべてのプロセスは、自身と依存先のポートマップ全体を把握した状態で起動します。

覚えておくべきルールが 1 つあります。 サービスに url または ports を宣言すると、ポートが割り当てられます。ポートの要求は明示的に行います。どちらも宣言されていないサービスにはポートが割り当てられません。ワーカーや単発ジョブにはこれが正しい動作ですが、そのサービスの cmd に ${self.port} を書くと問題になります。不明なトークンは空文字列に置き換えず、そのまま残すため、文字列 ${self.port} がシェルに渡り、プロセスは自身の引数解析時にエラー終了します。このような記述があると、binky check が警告します。

N 個のワールドを実行するコスト

N 個の隔離されたワールドを実行しても、コストが 1 個のワールドの N 倍になる必要はありません。これは主張ではなく、測定結果です。benchmarks/worlds.py はこのリポジトリにあり、以下の表を再現できます(postgres:16、各ワールド 200,000 行、Windows 11 上の Docker Desktop)。

worldsRAM: a container eachRAM: Binkytime: a container eachtime: Binky
1150 MiB174 MiB6s4s
2298 MiB182 MiB11s6s
4596 MiB228 MiB20s10s
81197 MiB295 MiB40s16s

8 個目のワールドは、それぞれを独立したコンテナーにすると +150 MiB、+4.8s かかりますが、Binky では +17 MiB、+1.7s です。

最初の行も確認してください。ワールドが 1 つの場合、Binky は劣ります。サーバーと、まだ使うものがないゴールデンテンプレートの分のコストがかかり、それを回収できるのは 2 つ目以降です。また、ディスク容量の面で有利になるわけではありません。CREATE DATABASE ... TEMPLATE はコピーオンライトではなくファイルのコピーなので、各ワールドには引き続き行データの完全なコピーが必要です。Binky が取り除くのはワールドごとの サーバー であり、ワールドごとの バイト数 ではありません。また、アプリのプロセス自体のコストも下がりません。ワークツリーごとに開発サーバーを 1 つ実行する場合、どちらの方法でもコストは同じです。

python benchmarks/worlds.py --sweep 1,2,4,8 --rows 200000

Binky が不要な場合

表の最初の行にもあるとおり、これははっきり述べておく価値があります。

  • 一度に 1 つのブランチしか使わない場合。 2 つのワールドを同時に起動することがないなら、Binky は不要なデーモンと設定ファイルを増やすだけです。2 つ目のエージェントが登場したら使いましょう。
  • すべてがすでにコンテナーで動いていて、それで問題ない場合。 Binky の利点は、ワールドごとの サーバー をなくせることです。Docker Compose のスタックが十分に小さく、N 個のコピーを無理なく動かせるなら、取り戻せるものはありません。
  • ローカルでの隔離ではなく、実際の隔離が必要な場合。 Binky はお使いのマシン上で、あなたと同じユーザーとしてコマンドを実行します。サンドボックスではありません。詳しくはセキュリティをご覧ください。

アダプター

アダプターは、ワークツリーごとに 1 つのサーバーを実行する代わりに、共有サーバー 1 つの独立したスライス(データベース、キーのプレフィックス、バケットなど)を切り分けます。16 個の名前、10 個の実装すべてについて、CI で実サーバーを使ったテストを実施しています。

sliceadapters
データベースpostgres · mysql · mariadb · percona · mongodb · clickhouse
キーのプレフィックスredis · valkey
バケット/プレフィックスs3 · minio
vhost/トピックのプレフィックスrabbitmq · kafka · redpanda
コレクションqdrant
インデックスのプレフィックスelasticsearch · opensearch

プロトコル互換の名前は、それぞれ別の実装を複製するのではなく、共通の実装を使用します。valkey は Redis アダプター、percona は MySQL アダプター、opensearch は Elasticsearch アダプターです。

clone_from:migrate+seed のコストを 1 回にする

clone_from を使用すると、最初の binky up でゴールデンテンプレートが作成されます。プロビジョニング、マイグレーション、シードを行い、それ以降の各ワークツリーはそのテンプレートをコピーします。テンプレートは migrate と seed の各コマンドのハッシュで識別されるため、どちらかを変更すると自動的に再構築されます。

サーバー側でスライスをコピーできる場合(postgres、mysql、mariadb、percona、mongodb)に対応しています。対応していない場合や、環境上の理由(認証に必要なクライアントバイナリが古い、必要な権限がないなど)でクローンに失敗した場合、Binky はそのワークツリーについてプロビジョニング、マイグレーション、シードにフォールバックし、clone_fallback をログに記録します。正しさはクローンに依存しません。クローンが左右するのは速度だけです。

注意すべき点が 1 つあります。ハッシュに含まれるのは migrate と seed の コマンド であり、それらが呼び出すファイルではありません。コマンドから実行されるスクリプトを編集しても、テンプレートは再構築されません。再構築を強制するには、~/.binky/golden/ 内のマーカーを削除してください。

独自のアダプターを作成する

2つの方式があり、契約は共通です。どちらも同じ4つの操作を実装します。

操作内容
provision(slice)スライスを作成します(CREATE DATABASE ...)
resolve(slice)アドレスを返します → ${db.url}
teardown(slice)スライスを破棄します
capabilities()対応機能を返します。例:{"clone": true}

プロセス内アダプターは、このリポジトリ内のPythonクラスで、名前で検出されます。外部アダプターは、任意の言語で作成した実行ファイルで、PATH 上の binky-adapter-<name> として検出され、1回限りのサブプロセスとJSONプロトコルで動作します。

$ binky-adapter-filestore provision   <<< '{"slice": "acme_login-fix", "config": {}}'
{"ok": true}
$ binky-adapter-filestore resolve     <<< '{"slice": "acme_login-fix", "config": {}}'
{"ok": true, "address": "file:///tmp/binky-filestore/acme_login-fix"}

Pythonで作成する場合、プロトコルは自動的に利用できます。binky.adapter_sdk.run() が通常のアダプタークラスとプロトコルの橋渡しをします。依存関係なしで30行で実装した完全な例は、examples/adapters/filestore.py を参照してください。

コマンド

コマンド内容
binky init [dir] [--force]docker-compose.yml と .env から初期設定用の binky.toml を作成します
binky check [path]binky.toml を検証し、危険な設定を警告します
binky up <name> [--group g]ブランチのワークツリーを作成/使用し、ポートを割り当て、リソースをプロビジョニングして、サービスを起動します
binky reload <name> [--group g]その場で再起動します。停止後、同じポートとデータで起動し直します
binky down <name>ワークツリーのプロセスを停止します(ファイルとポートは保持します)
binky remove <name> [--force]ワークツリーを破棄します。停止し、スライスを削除して、ファイルを取り除きます
binky status [.]ワークツリーを一覧表示します(プロジェクト別にグループ化)。. は現在のプロジェクトのみを示します
binky env <name> [--dotenv]ワークツリーの公開された接続情報を、自分またはエージェント向けに出力します
binky curl <name> <service> [path]Host ヘッダーを設定して、プロキシ経由でサービスを呼び出します(-X/-d/-H/-i/-f)
binky verify <name>プロジェクトの agents.verify チェックを実行します。失敗するとゼロ以外の終了コードを返します
binky logs <name>ワークツリーで取得したサービスログを出力します
binky gcクラッシュによってプロビジョニングが途中で止まった、孤立したアダプタースライスを一掃します
binky configマシン全体に適用される設定(RAM/ディスクの予約量、プロキシポート)を表示します
binky reserve [--ram %] [--disk gb]Binkyが常に空けておくRAM/ディスク容量を設定します
binky port [--proxy p] [--https p]プロキシ/HTTPSポートを設定します
binky dashboardすべてのワークツリーをリアルタイムで表示するTUI
binky doctorインストールとデーモンを診断します。問題がある場合はゼロ以外の終了コードを返します
binky metricsデーモンの特定時点のメトリクスをJSON形式で出力します
binky mcpエージェントがBinkyの操作をツールとして呼び出せるよう、MCP サーバーを実行します
binky daemon start|stop|statusバックグラウンドデーモンを管理します

エージェント向け

binky mcp はstdio経由でMCPを使用し、up、down、status、env、verify を公開します。これらはCLIが呼び出すものと同じ操作で、同じデーモンを使用します。

Claude Codeでは、1行で接続できます。

claude mcp add binky -- binky mcp

プロトコルに対応する他のクライアントでも、同じstdioサーバーを設定ブロックとして指定します。どこでも同じ設定を使い、異なるのはファイルだけです。

{ "mcpServers": { "binky": { "command": "binky", "args": ["mcp"] } } }

何もインストールせずに実行するには、代わりに uvx を使います。claude mcp add binky -- uvx --from "binky[mcp]" binky mcp と実行するか、設定ブロックとして "command": "uvx"、"args": ["--from", "binky[mcp]", "binky", "mcp"] を指定します。ワークツリーでアダプタースライスをプロビジョニングするプロジェクトでは、該当する追加機能も指定します。例:binky[mcp,postgres](すべてのアダプターを含める場合は binky[mcp,all-adapters])。

BinkyはMCP Registryに io.github.andreisilva1/binky として公開されているため、レジストリに対応するクライアントから検索してインストールできます。

ツール一覧とエージェント向けの手順については、AGENTS.md を参照してください。

仕組み

マシン全体で動作する単一のデーモンが、ワークツリーとマシンの間に配置されます。

flowchart TB
    CLI["agents · CLI · MCP"] -->|"up · down · status"| D(("binky daemon<br/>machine-global"))

    D --> ADM{"admission<br/>RAM · disk · max_parallel"}
    ADM -.->|"no room → queue / suspend"| Q["waiting"]
    ADM -->|"admit"| W["worktree<br/>git worktree per name"]
    W --> P["ports<br/>whole map before start"]
    P --> R["adapters<br/>isolated slice per worktree"]
    R --> S["supervisor<br/>depends_on · health · logs"]
    S --> X["proxy<br/>svc.worktree.domain → port"]

    D -.->|"reads · writes"| ST[("~/.binky<br/>SQLite + settings")]
  1. ワークツリー — 名前ごとに Git ワークツリーを作成または使用します。
  2. ポート — グローバルアロケーターが、プロセスの起動前にすべてのプロセスへポートを割り当て、ポートのマップ全体を注入するため、競合は発生しません(${self.port}、${api.url} など)。
  3. リソース — アダプターがワークツリーごとに分離された領域を切り出し、削除時に後片付けをします。
  4. 監視 — depends_on の順にサービスを起動し、ヘルスチェックを待ち、ログを取得します。
  5. プロキシ — <service>.<worktree>.<domain> を適切なポートにルーティングします(WebSocket/HMR にも対応)。https = true を設定すると、Caddy が PATH 上にある場合、Binky はローカル CA を介した TLS のために Caddy の前段に配置されます。
  6. 起動制御 — マシンに余裕がある場合にのみワークツリーを起動する FIFO キューです。実行中のワークツリーが max_parallel 未満で、かつ十分な空き RAM(一定割合を予備として確保)と十分な空きディスク容量(固定 GB の余裕)がある場合に起動します。実行中のワークツリー群が後から RAM の予備量を下回ると、デーモンは負荷を軽減するため、最も新しいワークツリーを一時停止し、余裕が戻ったら公平性に基づく順序で再開します。binky reserve で予備量を調整し、binky config で確認できます。

状態は ~/.binky/ に保存されます(SQLite レジストリと設定ストアがあり、アップグレード時にその場で移行されます)。クラウド上では何も実行されず、Binky がホームに情報を送信することもありません。

例

  • examples/hello — 最小構成のプロジェクトです。
  • examples/rag — 各ワークツリーが独自の埋め込みコーパスを持つベクトル検索です。 データベースを共有すると実際に問題が起きるケースです。2 つのエージェントが再インデックスを行い、一方が TRUNCATE します。
  • examples/adapters/filestore.py — 完全な外部アダプターです。

セキュリティ

Binky は、あなたのマシン上で、あなたとして、あなたのコマンドを実行します。これは単一ユーザーのワークステーション向けの開発ツールであり、マルチテナントのサンドボックスではありません。binky.toml は Makefile と同じくらい信頼できるものであり、信頼できないリポジトリで binky up を実行するのは、信頼できないリポジトリで make を実行するのと同じです。脅威モデルと、明示的に対象外としている内容は SECURITY.md に記載されています。

ここで改めて強調しておきたいルールは 1 つです。コミットする binky.toml に認証情報を直接記述しないでください。${env.NAME} または env_file を使用してください。binky check はそのような記述があると警告し、binky init が認証情報を書き込むことはありません。

動作しない場合

TROUBLESHOOTING.md では、実際によく起きるケースを説明しています。外部で使用中のポート、$PORT を無視する開発サーバー、古いゴールデンテンプレート、名前解決できない *.localhost などです。まずは binky doctor を実行してください。

開発

python -m venv .venv && . .venv/bin/activate   # or .venv\Scripts\activate on Windows
pip install -e ".[dev,all-adapters]"
pytest
ruff check src tests examples benchmarks

実サーバーを指定しない限り、アダプターの統合テストはスキップされます。対象となる環境変数は BINKY_TEST_PG、BINKY_TEST_REDIS、BINKY_TEST_MYSQL、BINKY_TEST_MONGO、BINKY_TEST_S3、BINKY_TEST_RABBITMQ、BINKY_TEST_KAFKA、BINKY_TEST_QDRANT、BINKY_TEST_CLICKHOUSE、BINKY_TEST_ELASTICSEARCH です。CI ではこれらすべてが用意されています。

貢献

バグ報告、新しいアダプター、PR を歓迎します。環境のセットアップ方法は CONTRIBUTING.md を、内部構造の概要は ARCHITECTURE.md をご覧ください。

ライセンス

Apache-2.0 — LICENSE と NOTICE をご覧ください。

コメント

MCP は初めてですか?

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

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