mcpField
M
MCP Tenant Pair

MCP Tenant Pair

ローカル
github.com/studiomeyer-io開発ツール01 週間前に更新

MCP Tenant Pair について

MCP Tenant Pairは、カップル、家族、小規模グループ向けのマルチユーザーテナンシーライブラリと参考MCPサーバーです。利用者ごとに分離された共有状態、二時点ストレージ、交換可能な競合解決器、SQLiteおよびPostgresアダプターを備えています。

主な機能

  1. 01ペア作成、招待、メンバー管理
  2. 02メンバー個別状態と共有状態
  3. 03二時点履歴と同時書き込み検出
  4. 04交換可能な競合解決器
  5. 05SQLiteおよびPostgresストレージアダプター

活用シーン

  1. 01家庭向けアプリでの状態共有
  2. 02共有カレンダーでのメンバーデータ管理
  3. 03MCPサーバーへのペア作成・招待機能の追加
  4. 04共有状態の変更履歴の確認

MCP 対応

ライブラリはトランスポートに依存せず、プロジェクトにはstdioで動作する参考MCPサーバーが含まれます。ペア、メンバー、状態を管理するツールを提供し、MCP 2025-06-18仕様に準拠します。

設定

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

mcp.json · 共通設定
{
"mcpServers": {
"io-studiomeyer-tenant-pair": {
"command": "npx",
"args": [
"-y",
"mcp-tenant-pair-demo"
]
}
}
}
起動コマンドnpx -y mcp-tenant-pair-demo

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

パッケージ
npmmcp-tenant-pair-demo0.1.2

ツール

ツール一覧はまだ取得されていません

ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。

詳細

StudioMeyer MCP Stack の一部 — マヨルカ島で開発 🌴 · 使用したら ⭐

mcp-tenant-pair

npm version npm downloads License Last commit GitHub stars コンシューマー向け MCP サーバー(カップル、家族、小グループ)でのマルチユーザーテナント管理を実現する基盤ライブラリとリファレンス MCP サーバーです。IDごとに分離された状態、双時制ストレージ、競合解決インターフェースを備えています。

仕様: MCP 2025-06-18 ライセンス: MIT リポジトリ構成: モノレポ(npm ワークスペース)

packages/
  lib/        mcp-tenant-pair          (TypeScript library)
  cli/        mcp-tenant-pair-cli      (commander CLI)
  demo/       mcp-tenant-pair-demo     (reference Low-Level MCP server, stdio)

開発者からのメッセージ

私たちは過去2年間、自分たちのためにツールやシステムを作ってきました。このリポジトリが小さく、スターが少ないのは、新しいからではありません。作ってきたものを公開することにしたのが、つい最近だからです。これは新たな実験ではなく、最近のコミットに至るまで長く続いてきた取り組みです。

私たちはものづくりと共有が大好きです。ソーシャルメディアの戦術や成長ハック、スターやフォロワーの追求は好みません。そのため、このリポジトリは小規模です。コードは実際に使われており、問題には回答しています。ご自身で判断してください。

役に立った場合は、共有、テスト、フィードバックで応援していただけるとうれしいです。改善できそうな点があれば、イシューをお寄せいただくのが一番役立ちます。これを使って何かを作った場合は、[email protected] までお知らせください。本当にうれしいです。

マヨルカ島パルマの小さなスタジオより。

このプロジェクトの目的

現在、ほとんどの MCP サーバーはシングルユーザー向けです。2人以上の人間(カップル、家族、小グループ)で状態を共有しようとすると、毎回同じ5つの課題に直面します。ペアの作成、招待フロー、IDごとに分離された状態、競合解決、自主的な退出/メンバーの除名です。このライブラリはこれらを一度解決するため、下流の MCP サーバー(Pet-Platform、レシピ共有、家庭、カレンダー)が同じ仕組みを再実装せずに済みます。

5分で始める

ライブラリ
import { TenantPair, SqliteTenantStore, LWWResolver } from "mcp-tenant-pair";

const tp = new TenantPair({
  store: new SqliteTenantStore({ path: "./tenant-pair.sqlite" }),
  resolver: new LWWResolver(),
});

const { pairId, inviteToken } = await tp.createPair({ creatorMemberId: "alice" });
await tp.acceptInvite({ inviteToken, memberId: "bob" });

await tp.setMemberPreference(pairId, "alice", "allergy", ["nuts"]);
await tp.setSharedState(pairId, "alice", "tonight", "pizza");

const aliceConstraints = await tp.getMemberConstraints(pairId, "alice");
const shared = await tp.getSharedState(pairId);
CLI
npx mcp-tenant-pair-cli pair create --member-id alice
npx mcp-tenant-pair-cli pair invite --pair-id <id> --member-id alice
npx mcp-tenant-pair-cli state set --pair-id <id> --member-id alice --key tonight --value pizza
npx mcp-tenant-pair-cli state get --pair-id <id>
デモ MCP サーバー
node packages/demo/dist/server.js
# or via stdio in your MCP client config

MCP_TENANT_PAIR_DB 環境変数を読み取ります(デフォルトは :memory:)。

ツール(12)

ToolreadOnlyHintdestructiveHint
create_pairfalsefalse
invite_memberfalsefalse
accept_invitefalsefalse
list_memberstruefalse
set_member_preferencesfalsefalse
get_member_constraintstruefalse
get_shared_statetruefalse
set_shared_statefalsefalse
resolve_conflictsfalsetrue
kick_memberfalsetrue
leave_pairfalsetrue
forget_memberfalsetrue

互換性マトリックス

ConcernSupported
MCP Spec2025-06-18
Node使用には >= 20.0.0 が必要です。このリポジトリのビルドには 20.19+ または 22.12+ が必要です(Vite 8)。
StorageSQLite(デフォルト)、Postgres(peer-dep)
Conflict ResolverLWWResolver(デフォルト)、ManualResolver、カスタム(インターフェース)
Transportstdio(デモ)、ライブラリはトランスポート非依存

ストレージアダプター

  • SqliteTenantStore — デフォルトの組み込み型、単一プロセス向けです。WAL モードで better-sqlite3 を使用します。{ path: "./pair.sqlite" } または :memory: を渡します。
  • PostgresTenantStore — マルチプロセス、マルチテナント向けです。pg.Pool と同じ形状のクライアント({ query<R>(text, params): Promise<{rows: R[]}>, end?(): Promise<void> })を受け付けます。pg はピア依存関係です。

競合解決

ConflictResolver はインターフェースです。次の 2 つの実装を同梱しています。

  • LWWResolver — 最新の validFrom を持つ行を選び、同値の場合は最も大きい version を選びます。候補リストが空の場合は例外をスローします。
  • ManualResolver — 解決結果を返しません。人が外部で解決するまで、競合は保留状態のままです。

{ name: string; resolve(conflicts: Conflict[]): Resolution[] } を実装して、独自のリゾルバーを挿入できます。

バイテンポラルモデル

(pairId, namespace, key) の組み合わせを上書きするたびに、以前のアクティブな行に valid_to を設定し、新しい valid_from を持つ新しい行を挿入します。version はキーごとに単調増加します。これにより、履歴を再生(getPairStateHistory)し、同時書き込みを決定論的に検出できます。

ID の分離

member_state はメンバーごとのデータです(get_member_constraints を通じて、そのメンバーのみが読み取れます)。 pair_state は共有データです(すべてのアクティブなメンバーが get_shared_state を通じて読み取れます)。

後に脱退または追放されたメンバーによる書き込みも、共有状態で引き続き確認できます。

セキュリティに関する注意事項

  • 招待トークンは <uuid v4>.<XXXX-XXXX> の形式です。uuid v4(node:crypto による 122 ビットの CSPRNG エントロピー)と、音声で読み上げやすい base32 の短縮コード(デフォルトの RNG は node:crypto.randomInt。テスト用に挿入可能)を組み合わせています。
  • ペアごとの保留中の招待数には上限があります(デフォルトは 25、maxPendingInvites で設定可能)。
  • キックできるのはオーナーのみです。オーナーは自分自身をキックできません。代わりに脱退してください。
  • DSGVO Art. 17 の消去処理:forgetMember(pairId, memberId) は、メンバーの member_state の行(アレルギー、食事の好み)を完全に削除し、display_name を null にします。監査用にメンバーシップの記録(left_at)は保持されます。
  • Postgres アダプターは、構築時に /^[a-z_][a-z0-9_]{0,62}$/ に一致しないスキーマ名を拒否します(インテグレーターが指定したスキーマ文字列を介した SQL インジェクションへの対策)。
  • acceptInvite は競合状態に安全です。両方のアダプターがアトミックなトランザクションを使用します(better-sqlite3 の即時トランザクション、または pg の BEGIN + SELECT ... FOR UPDATE)。
  • 時刻はテストを決定論的にするために挿入可能です(now: () => Date)。

開発

npm install
npm run build
npm test

テスト対象(142 + 条件付き 1 件):

  • ペア作成(8)
  • 招待フロー(10)
  • 招待の有効期限境界(6)— 2 つのアダプターとも、expires_at と完全に同じ時刻では accept と pending の結果が一致します
  • メンバー設定(8)
  • 共有状態(8)
  • 競合解決(13)
  • リゾルバー(11)
  • エラー処理(17)— TenantPairError のコードを網羅的にカバー
  • ストアアダプター(6)
  • Postgres アダプター(26)— スキーマ識別子の検証、アトミックなトランザクション、フォールバック経路(モックプール、実データベースなし)
  • アダプター間の同等性(6 + 1)— SQLite と Postgres で同じ操作を実行し、同一の結果が得られることを検証します。Postgres のテストは、TENANT_PAIR_TEST_PG_URL/DATABASE_URL が接続可能なデータベースを指す場合のみ実行され、それ以外の場合はスキップされます(誤って失敗することはありません)
  • デモサーバーの統合(9)
  • 第 1 ラウンドのリグレッション修正(14)— SQL インジェクションに対するスキーマ検証、TOCTOU による acceptInvite の競合、競合解決時の勝者マーカー、asOf クロック、DSGVO 消去、CSPRNG のデフォルト設定

実際の Postgres に対して、アダプター間の同等性テストを実行します。

TENANT_PAIR_TEST_PG_URL=postgres://user:pass@host:5432/db npm test

ステータス

基盤ビルドです。レビュー済み(Cold-Cross-Review + MCP Factory Reviewer + Tester)。HIGH/MEDIUM の指摘事項はすべて修正済みです。tsc はクリーン(strict)、テスト 142 件が成功(Postgres 条件付きテスト 1 件はスキップ)。本番用の依存関係ツリーに既知のアドバイザリはありません(npm audit --omit=dev)。

StudioMeyer について

StudioMeyer は、パルマ・デ・マヨルカを拠点に世界中のクライアントと協業する、AI とデザインのスタジオです。中小企業向けに、カスタムウェブサイトと AI インフラストラクチャを構築しています。本番スタックには Claude Agent SDK、MCP、n8n を使用し、可観測性のために Sentry、Langfuse、LangGraph を、自社開発のガードレイヤーとともに採用しています。

コメント

MCP は初めてですか?

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

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