{"title":"Synapse アーキテクチャ","slug":"architecture","category":"concepts","summary":"Synapse の構成 — Fastify、PostgreSQL、FTS5、埋め込み、MCP サーバー。","audience":["human","llm"],"tags":["architecture","design","components"],"difficulty":"intermediate","updated":"2026-06-27","word_count":263,"read_minutes":1,"lang":"ja","translated":true,"requested_lang":"ja","content_markdown":"\n# Synapse アーキテクチャ\n\nSynapse は Fastify、FTS5 搭載 PostgreSQL、セマンティック検索用のオプションの埋め込みサービスで構築されたマルチテナントメモリ API です。\n\n## 全体アーキテクチャ\n\n```\n┌──────────────────────────────────────────────────────────┐\n│                       Clients                            │\n├──────────────┬──────────────┬──────────────┬─────────────┤\n│  LLM Agents  │  Web Browsers│  MCP Clients │  Webhooks   │\n│  (curl/SDK)  │  (humans)    │ (Claude/etc) │  (external) │\n└──────┬───────┴──────┬───────┴──────┬───────┴──────┬──────┘\n       │              │              │              │\n       └──────────────┴──────────────┴──────────────┘\n                              │\n                              ▼\n              ┌───────────────────────────────┐\n              │    Synapse API (Fastify)      │\n              │    port 12800                 │\n              │    - REST endpoints           │\n              │    - Auth (Mind Key / JWT)    │\n              │    - Rate limiting            │\n              │    - Static file serving      │\n              └───────────────┬───────────────┘\n                              │\n              ┌───────────────┼───────────────┐\n              ▼               ▼               ▼\n       ┌─────────────┐ ┌─────────────┐ ┌─────────────┐\n       │ PostgreSQL  │ │ Embeddings  │ │ MCP Server  │\n       │ + FTS5      │ │ Service     │ │ (separate)  │\n       │             │ │ (optional)  │ │ port 13100  │\n       │ - memories  │ │             │ │             │\n       │ - tasks     │ │ - generate  │ │ - 79 tools  │\n       │ - chat      │ │   embeddings│ │ - stdio/SSE │\n       │ - scripts   │ │             │ │ - WebSocket │\n       └─────────────┘ └─────────────┘ └─────────────┘\n```\n\n## コアコンポーネント\n\n### 1. Synapse API（Fastify）\n\nメインの HTTP サーバーです。以下を処理します。\n\n- REST エンドポイント（`/memory`、`/chat`、`/mind/tasks` など）\n- 認証（エージェントは Mind Key、人間は JWT）\n- レート制限（`?key=` 認証のみ）\n- 静的ファイル配信（`/human`、`/docs` などの Web UI）\n- Webhook ディスパッチ\n\nパフォーマンス重視で **Fastify 5** により構築されています。本番環境ではポート 12800 で動作します。\n\n### 2. FTS5 搭載 PostgreSQL\n\nプライマリデータストアです。フルテキスト検索用に FTS5 拡張を備えた PostgreSQL を使用します。\n\n**主なテーブル：**\n\n| テーブル | 目的 |\n|-------|---------|\n| `users` | ユーザーアカウント |\n| `minds` | Mind スコープ（各々が Mind Key を持つ） |\n| `memories` | FTS5 仮想テーブル付きのメモリレコード |\n| `tasks` | タスク管理 |\n| `chat_messages` | チャット履歴 |\n| `scripts` | 永続スクリプト |\n| `webhooks` | Webhook 登録 |\n| `cron_jobs` | スケジュールタスク |\n| `variables` | キーバリューストア |\n| `audit_log` | 監査トレイル |\n\n**FTS5** により、全メモリコンテンツに対するサブミリ秒のフルテキスト検索が可能です。詳しくは [FTS5 Search](/docs/concepts/fts5-search) を参照。\n\n### 3. 埋め込みサービス（オプション）\n\nセマンティック検索のため、Synapse はメモリコンテンツのベクトル埋め込みを生成します。これらはメモリと一緒に保存され、類似度検索に使用されます。\n\n- プロバイダー：構成可能（OpenAI、ローカルモデルなど）\n- `memories` テーブルの `vector` カラムとして保存\n- `/memory/semantic-search` エンドポイントで使用\n- [Semantic Search](/docs/concepts/semantic-search) を参照\n\n### 4. MCP サーバー（別サービス）\n\nSynapse MCP サーバーは別プロセス（ポート 13100）として動作します。以下を行います。\n\n- Model Context Protocol 経由で 79 のツールを公開\n- stdio、HTTP/SSE、WebSocket トランスポートをサポート\n- MCP ツール呼び出しを Synapse API 呼び出しに変換\n- マルチテナント：セッションごとに 1 つの Mind Key\n\n### 5. Browser Proxy（別サービス）\n\nブラウザ自動化用に、Playwright ベースの別サービスがポート 13000 で動作します。MCP サーバーは `browser_*` ツールのためにこれを呼び出せます。\n\n### 6. SSH Proxy（別サービス）\n\nSSH ベースのリモートコマンド用に、別サービスがポート 12900 で動作します。\n\n## マルチテナントモデル\n\n```\nUser Account (email + password)\n  │\n  ├── Mind 1 (Mind Key 1)\n  │   ├── Memories\n  │   ├── Tasks\n  │   ├── Chat\n  │   └── Scripts\n  │\n  ├── Mind 2 (Mind Key 2)\n  │   └── ... (isolated from Mind 1)\n  │\n  └── Mind 3 (Mind Key 3)\n      └── ...\n```\n\n各 mind は完全に分離されています。Mind Key は厳密に 1 つの mind へのアクセスを許可します。JWT はユーザーアカウントへのアクセスを許可します（mind 管理用）。\n\n詳しくは [Multi-Tenancy](/docs/concepts/multi-tenancy) を参照。\n\n## リクエストフロー\n\n### メモリ保存リクエスト\n\n```\n1. Client sends POST /memory with Authorization: Bearer mk_xxx\n2. Fastify receives request\n3. Auth middleware validates Mind Key, attaches mind_id to request\n4. Memory route handler:\n   a. Validate JSON body (zod schema)\n   b. Insert into memories table\n   c. Update FTS5 index\n   d. (Async) Generate embedding if embeddings enabled\n   e. Trigger webhooks for memory.store event\n5. Return { id, status: \"stored\" }\n```\n\n### メモリ検索リクエスト\n\n```\n1. Client sends GET /memory/search?q=docker\n2. Auth middleware validates Mind Key\n3. Memory route handler:\n   a. Parse query (FTS5 syntax)\n   b. Execute FTS5 MATCH against memories table\n   c. Filter by mind_id (tenant isolation)\n   d. Rank by relevance\n   e. Return results\n```\n\n## デプロイ\n\nSynapse は Docker コンテナとしてデプロイされます。`docker-compose.yml` を参照：\n\n```yaml\nservices:\n  synapse:\n    image: registry.gitlab.com/schaefer-services/synapse:latest\n    ports:\n      - \"12800:12800\"\n    environment:\n      - DATABASE_URL=postgres://...\n      - JWT_SECRET=...\n      - SYNAPSE_HOST=0.0.0.0\n      - SYNAPSE_PORT=12800\n    depends_on:\n      - postgres\n  \n  postgres:\n    image: postgres:16\n    volumes:\n      - pgdata:/var/lib/postgresql/data\n    environment:\n      - POSTGRES_DB=synapse\n      - POSTGRES_PASSWORD=...\n```\n\n## パフォーマンス特性\n\n| 操作 | レイテンシ | スループット |\n|-----------|---------|------------|\n| メモリ保存 | ~5ms | 1000+ req/s |\n| メモリ再取得 | ~20ms | 500 req/s |\n| FTS5 検索 | ~10ms | 800 req/s |\n| セマンティック検索 | ~50ms | 200 req/s |\n| チャットポーリング | ~5ms | 2000 req/s |\n\n## 次のステップ\n\n- [Memory Model](/docs/concepts/memory-model)\n- [Multi-Tenancy](/docs/concepts/multi-tenancy)\n- [FTS5 Search](/docs/concepts/fts5-search)\n","content_html":"<h1>Synapse アーキテクチャ</h1>\n<p>Synapse は Fastify、FTS5 搭載 PostgreSQL、セマンティック検索用のオプションの埋め込みサービスで構築されたマルチテナントメモリ API です。</p>\n<h2>全体アーキテクチャ</h2>\n<pre><code class=\"hljs language-plaintext\">┌──────────────────────────────────────────────────────────┐\n│                       Clients                            │\n├──────────────┬──────────────┬──────────────┬─────────────┤\n│  LLM Agents  │  Web Browsers│  MCP Clients │  Webhooks   │\n│  (curl/SDK)  │  (humans)    │ (Claude/etc) │  (external) │\n└──────┬───────┴──────┬───────┴──────┬───────┴──────┬──────┘\n       │              │              │              │\n       └──────────────┴──────────────┴──────────────┘\n                              │\n                              ▼\n              ┌───────────────────────────────┐\n              │    Synapse API (Fastify)      │\n              │    port 12800                 │\n              │    - REST endpoints           │\n              │    - Auth (Mind Key / JWT)    │\n              │    - Rate limiting            │\n              │    - Static file serving      │\n              └───────────────┬───────────────┘\n                              │\n              ┌───────────────┼───────────────┐\n              ▼               ▼               ▼\n       ┌─────────────┐ ┌─────────────┐ ┌─────────────┐\n       │ PostgreSQL  │ │ Embeddings  │ │ MCP Server  │\n       │ + FTS5      │ │ Service     │ │ (separate)  │\n       │             │ │ (optional)  │ │ port 13100  │\n       │ - memories  │ │             │ │             │\n       │ - tasks     │ │ - generate  │ │ - 79 tools  │\n       │ - chat      │ │   embeddings│ │ - stdio/SSE │\n       │ - scripts   │ │             │ │ - WebSocket │\n       └─────────────┘ └─────────────┘ └─────────────┘</code></pre><h2>コアコンポーネント</h2>\n<h3>1. Synapse API（Fastify）</h3>\n<p>メインの HTTP サーバーです。以下を処理します。</p>\n<ul>\n<li>REST エンドポイント（<code>/memory</code>、<code>/chat</code>、<code>/mind/tasks</code> など）</li>\n<li>認証（エージェントは Mind Key、人間は JWT）</li>\n<li>レート制限（<code>?key=</code> 認証のみ）</li>\n<li>静的ファイル配信（<code>/human</code>、<code>/docs</code> などの Web UI）</li>\n<li>Webhook ディスパッチ</li>\n</ul>\n<p>パフォーマンス重視で <strong>Fastify 5</strong> により構築されています。本番環境ではポート 12800 で動作します。</p>\n<h3>2. FTS5 搭載 PostgreSQL</h3>\n<p>プライマリデータストアです。フルテキスト検索用に FTS5 拡張を備えた PostgreSQL を使用します。</p>\n<p><strong>主なテーブル：</strong></p>\n<table>\n<thead>\n<tr>\n<th>テーブル</th>\n<th>目的</th>\n</tr>\n</thead>\n<tbody><tr>\n<td><code>users</code></td>\n<td>ユーザーアカウント</td>\n</tr>\n<tr>\n<td><code>minds</code></td>\n<td>Mind スコープ（各々が Mind Key を持つ）</td>\n</tr>\n<tr>\n<td><code>memories</code></td>\n<td>FTS5 仮想テーブル付きのメモリレコード</td>\n</tr>\n<tr>\n<td><code>tasks</code></td>\n<td>タスク管理</td>\n</tr>\n<tr>\n<td><code>chat_messages</code></td>\n<td>チャット履歴</td>\n</tr>\n<tr>\n<td><code>scripts</code></td>\n<td>永続スクリプト</td>\n</tr>\n<tr>\n<td><code>webhooks</code></td>\n<td>Webhook 登録</td>\n</tr>\n<tr>\n<td><code>cron_jobs</code></td>\n<td>スケジュールタスク</td>\n</tr>\n<tr>\n<td><code>variables</code></td>\n<td>キーバリューストア</td>\n</tr>\n<tr>\n<td><code>audit_log</code></td>\n<td>監査トレイル</td>\n</tr>\n</tbody></table>\n<p><strong>FTS5</strong> により、全メモリコンテンツに対するサブミリ秒のフルテキスト検索が可能です。詳しくは <a href=\"/docs/concepts/fts5-search\">FTS5 Search</a> を参照。</p>\n<h3>3. 埋め込みサービス（オプション）</h3>\n<p>セマンティック検索のため、Synapse はメモリコンテンツのベクトル埋め込みを生成します。これらはメモリと一緒に保存され、類似度検索に使用されます。</p>\n<ul>\n<li>プロバイダー：構成可能（OpenAI、ローカルモデルなど）</li>\n<li><code>memories</code> テーブルの <code>vector</code> カラムとして保存</li>\n<li><code>/memory/semantic-search</code> エンドポイントで使用</li>\n<li><a href=\"/docs/concepts/semantic-search\">Semantic Search</a> を参照</li>\n</ul>\n<h3>4. MCP サーバー（別サービス）</h3>\n<p>Synapse MCP サーバーは別プロセス（ポート 13100）として動作します。以下を行います。</p>\n<ul>\n<li>Model Context Protocol 経由で 79 のツールを公開</li>\n<li>stdio、HTTP/SSE、WebSocket トランスポートをサポート</li>\n<li>MCP ツール呼び出しを Synapse API 呼び出しに変換</li>\n<li>マルチテナント：セッションごとに 1 つの Mind Key</li>\n</ul>\n<h3>5. Browser Proxy（別サービス）</h3>\n<p>ブラウザ自動化用に、Playwright ベースの別サービスがポート 13000 で動作します。MCP サーバーは <code>browser_*</code> ツールのためにこれを呼び出せます。</p>\n<h3>6. SSH Proxy（別サービス）</h3>\n<p>SSH ベースのリモートコマンド用に、別サービスがポート 12900 で動作します。</p>\n<h2>マルチテナントモデル</h2>\n<pre><code class=\"hljs language-plaintext\">User Account (email + password)\n  │\n  ├── Mind 1 (Mind Key 1)\n  │   ├── Memories\n  │   ├── Tasks\n  │   ├── Chat\n  │   └── Scripts\n  │\n  ├── Mind 2 (Mind Key 2)\n  │   └── ... (isolated from Mind 1)\n  │\n  └── Mind 3 (Mind Key 3)\n      └── ...</code></pre><p>各 mind は完全に分離されています。Mind Key は厳密に 1 つの mind へのアクセスを許可します。JWT はユーザーアカウントへのアクセスを許可します（mind 管理用）。</p>\n<p>詳しくは <a href=\"/docs/concepts/multi-tenancy\">Multi-Tenancy</a> を参照。</p>\n<h2>リクエストフロー</h2>\n<h3>メモリ保存リクエスト</h3>\n<pre><code class=\"hljs language-plaintext\">1. Client sends POST /memory with Authorization: Bearer mk_xxx\n2. Fastify receives request\n3. Auth middleware validates Mind Key, attaches mind_id to request\n4. Memory route handler:\n   a. Validate JSON body (zod schema)\n   b. Insert into memories table\n   c. Update FTS5 index\n   d. (Async) Generate embedding if embeddings enabled\n   e. Trigger webhooks for memory.store event\n5. Return { id, status: &quot;stored&quot; }</code></pre><h3>メモリ検索リクエスト</h3>\n<pre><code class=\"hljs language-plaintext\">1. Client sends GET /memory/search?q=docker\n2. Auth middleware validates Mind Key\n3. Memory route handler:\n   a. Parse query (FTS5 syntax)\n   b. Execute FTS5 MATCH against memories table\n   c. Filter by mind_id (tenant isolation)\n   d. Rank by relevance\n   e. Return results</code></pre><h2>デプロイ</h2>\n<p>Synapse は Docker コンテナとしてデプロイされます。<code>docker-compose.yml</code> を参照：</p>\n<pre><code class=\"hljs language-yaml\"><span class=\"hljs-attr\">services:</span>\n  <span class=\"hljs-attr\">synapse:</span>\n    <span class=\"hljs-attr\">image:</span> <span class=\"hljs-string\">registry.gitlab.com/schaefer-services/synapse:latest</span>\n    <span class=\"hljs-attr\">ports:</span>\n      <span class=\"hljs-bullet\">-</span> <span class=\"hljs-string\">&quot;12800:12800&quot;</span>\n    <span class=\"hljs-attr\">environment:</span>\n      <span class=\"hljs-bullet\">-</span> <span class=\"hljs-string\">DATABASE_URL=postgres://...</span>\n      <span class=\"hljs-bullet\">-</span> <span class=\"hljs-string\">JWT_SECRET=...</span>\n      <span class=\"hljs-bullet\">-</span> <span class=\"hljs-string\">SYNAPSE_HOST=0.0.0.0</span>\n      <span class=\"hljs-bullet\">-</span> <span class=\"hljs-string\">SYNAPSE_PORT=12800</span>\n    <span class=\"hljs-attr\">depends_on:</span>\n      <span class=\"hljs-bullet\">-</span> <span class=\"hljs-string\">postgres</span>\n  \n  <span class=\"hljs-attr\">postgres:</span>\n    <span class=\"hljs-attr\">image:</span> <span class=\"hljs-string\">postgres:16</span>\n    <span class=\"hljs-attr\">volumes:</span>\n      <span class=\"hljs-bullet\">-</span> <span class=\"hljs-string\">pgdata:/var/lib/postgresql/data</span>\n    <span class=\"hljs-attr\">environment:</span>\n      <span class=\"hljs-bullet\">-</span> <span class=\"hljs-string\">POSTGRES_DB=synapse</span>\n      <span class=\"hljs-bullet\">-</span> <span class=\"hljs-string\">POSTGRES_PASSWORD=...</span></code></pre><h2>パフォーマンス特性</h2>\n<table>\n<thead>\n<tr>\n<th>操作</th>\n<th>レイテンシ</th>\n<th>スループット</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>メモリ保存</td>\n<td>~5ms</td>\n<td>1000+ req/s</td>\n</tr>\n<tr>\n<td>メモリ再取得</td>\n<td>~20ms</td>\n<td>500 req/s</td>\n</tr>\n<tr>\n<td>FTS5 検索</td>\n<td>~10ms</td>\n<td>800 req/s</td>\n</tr>\n<tr>\n<td>セマンティック検索</td>\n<td>~50ms</td>\n<td>200 req/s</td>\n</tr>\n<tr>\n<td>チャットポーリング</td>\n<td>~5ms</td>\n<td>2000 req/s</td>\n</tr>\n</tbody></table>\n<h2>次のステップ</h2>\n<ul>\n<li><a href=\"/docs/concepts/memory-model\">Memory Model</a></li>\n<li><a href=\"/docs/concepts/multi-tenancy\">Multi-Tenancy</a></li>\n<li><a href=\"/docs/concepts/fts5-search\">FTS5 Search</a></li>\n</ul>\n","urls":{"html":"/docs/concepts/architecture","text":"/docs/concepts/architecture?format=text","json":"/docs/concepts/architecture?format=json","llm":"/docs/concepts/architecture?format=llm"},"translations_available":["en","zh","hi","es","fr","ar","pt","ru","ja","de","it","ko","nl","pl","tr","sv","vi","th","id","uk"]}