{"title":"Architecture de Synapse","slug":"architecture","category":"concepts","summary":"Comment Synapse est construit — Fastify, PostgreSQL, FTS5, embeddings, serveur MCP.","audience":["human","llm"],"tags":["architecture","design","components"],"difficulty":"intermediate","updated":"2026-06-27","word_count":498,"read_minutes":2,"lang":"fr","translated":true,"requested_lang":"fr","content_markdown":"\n# Architecture de Synapse\n\nSynapse est une API de mémoire multi-tenant construite sur Fastify, PostgreSQL avec\nFTS5, et un service d'embeddings optionnel pour la recherche sémantique.\n\n## Architecture globale\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## Composants principaux\n\n### 1. API Synapse (Fastify)\n\nLe serveur HTTP principal. Gère :\n\n- Endpoints REST (`/memory`, `/chat`, `/mind/tasks`, etc.)\n- Authentification (Mind Key pour les agents, JWT pour les humains)\n- Limitation de débit (auth `?key=` uniquement)\n- Service de fichiers statiques (interface web sur `/human`, `/docs`, etc.)\n- Dispatch des webhooks\n\nConstruit avec **Fastify 5** pour la performance. Fonctionne sur le port 12800 en\nproduction.\n\n### 2. PostgreSQL avec FTS5\n\nLe magasin de données principal. Utilise PostgreSQL avec l'extension FTS5 pour la\nrecherche en texte intégral.\n\n**Tables principales :**\n\n| Table | Rôle |\n|-------|---------|\n| `users` | Comptes utilisateurs |\n| `minds` | Scopes de mind (chacun a une Mind Key) |\n| `memories` | Enregistrements de mémoire avec table virtuelle FTS5 |\n| `tasks` | Gestion des tâches |\n| `chat_messages` | Historique de chat |\n| `scripts` | Scripts persistants |\n| `webhooks` | Enregistrements de webhooks |\n| `cron_jobs` | Tâches planifiées |\n| `variables` | Magasin clé-valeur |\n| `audit_log` | Piste d'audit |\n\n**FTS5** permet la recherche en texte intégral sub-milliseconde sur tout le contenu\nde mémoire. Voir [Recherche FTS5](/docs/concepts/fts5-search) pour plus de détails.\n\n### 3. Service d'embeddings (optionnel)\n\nPour la recherche sémantique, Synapse génère des embeddings vectoriels du contenu des\nmémoires. Ils sont stockés à côté des mémoires et utilisés pour la recherche de\nsimilarité.\n\n- Fournisseur : configurable (OpenAI, modèle local, etc.)\n- Stocké comme colonne `vector` dans la table `memories`\n- Utilisé par l'endpoint `/memory/semantic-search`\n- Voir [Recherche sémantique](/docs/concepts/semantic-search)\n\n### 4. Serveur MCP (service séparé)\n\nLe serveur MCP Synapse s'exécute comme un processus distinct (port 13100). Il :\n\n- Expose 79 outils via Model Context Protocol\n- Prend en charge les transports stdio, HTTP/SSE et WebSocket\n- Traduit les appels d'outils MCP en appels d'API Synapse\n- Multi-tenant : une Mind Key par session\n\n### 5. Proxy navigateur (service séparé)\n\nPour l'automatisation de navigateur, un service distinct basé sur Playwright\ns'exécute sur le port 13000. Le serveur MCP peut l'appeler pour les outils\n`browser_*`.\n\n### 6. Proxy SSH (service séparé)\n\nPour les commandes distantes basées sur SSH, un service distinct s'exécute sur le\nport 12900.\n\n## Modèle multi-tenant\n\n```\nCompte utilisateur (email + mot de passe)\n  │\n  ├── Mind 1 (Mind Key 1)\n  │   ├── Memories\n  │   ├── Tasks\n  │   ├── Chat\n  │   └── Scripts\n  │\n  ├── Mind 2 (Mind Key 2)\n  │   └── ... (isolé du Mind 1)\n  │\n  └── Mind 3 (Mind Key 3)\n      └── ...\n```\n\nChaque mind est entièrement isolé. Les Mind Keys accordent l'accès à un seul mind.\nLes JWT accordent l'accès au compte utilisateur (pour gérer les minds).\n\nVoir [Multi-tenancy](/docs/concepts/multi-tenancy) pour plus de détails.\n\n## Flux de requêtes\n\n### Requête de stockage mémoire\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### Requête de recherche mémoire\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## Déploiement\n\nSynapse est déployé comme conteneur Docker. Voir `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## Caractéristiques de performance\n\n| Opération | Latence | Débit |\n|-----------|---------|------------|\n| Stockage mémoire | ~5 ms | 1000+ req/s |\n| Rappel mémoire | ~20 ms | 500 req/s |\n| Recherche FTS5 | ~10 ms | 800 req/s |\n| Recherche sémantique | ~50 ms | 200 req/s |\n| Polling chat | ~5 ms | 2000 req/s |\n\n## Prochaines étapes\n\n- [Modèle de mémoire](/docs/concepts/memory-model)\n- [Multi-tenancy](/docs/concepts/multi-tenancy)\n- [Recherche FTS5](/docs/concepts/fts5-search)\n","content_html":"<h1>Architecture de Synapse</h1>\n<p>Synapse est une API de mémoire multi-tenant construite sur Fastify, PostgreSQL avec\nFTS5, et un service d&#39;embeddings optionnel pour la recherche sémantique.</p>\n<h2>Architecture globale</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>Composants principaux</h2>\n<h3>1. API Synapse (Fastify)</h3>\n<p>Le serveur HTTP principal. Gère :</p>\n<ul>\n<li>Endpoints REST (<code>/memory</code>, <code>/chat</code>, <code>/mind/tasks</code>, etc.)</li>\n<li>Authentification (Mind Key pour les agents, JWT pour les humains)</li>\n<li>Limitation de débit (auth <code>?key=</code> uniquement)</li>\n<li>Service de fichiers statiques (interface web sur <code>/human</code>, <code>/docs</code>, etc.)</li>\n<li>Dispatch des webhooks</li>\n</ul>\n<p>Construit avec <strong>Fastify 5</strong> pour la performance. Fonctionne sur le port 12800 en\nproduction.</p>\n<h3>2. PostgreSQL avec FTS5</h3>\n<p>Le magasin de données principal. Utilise PostgreSQL avec l&#39;extension FTS5 pour la\nrecherche en texte intégral.</p>\n<p><strong>Tables principales :</strong></p>\n<table>\n<thead>\n<tr>\n<th>Table</th>\n<th>Rôle</th>\n</tr>\n</thead>\n<tbody><tr>\n<td><code>users</code></td>\n<td>Comptes utilisateurs</td>\n</tr>\n<tr>\n<td><code>minds</code></td>\n<td>Scopes de mind (chacun a une Mind Key)</td>\n</tr>\n<tr>\n<td><code>memories</code></td>\n<td>Enregistrements de mémoire avec table virtuelle FTS5</td>\n</tr>\n<tr>\n<td><code>tasks</code></td>\n<td>Gestion des tâches</td>\n</tr>\n<tr>\n<td><code>chat_messages</code></td>\n<td>Historique de chat</td>\n</tr>\n<tr>\n<td><code>scripts</code></td>\n<td>Scripts persistants</td>\n</tr>\n<tr>\n<td><code>webhooks</code></td>\n<td>Enregistrements de webhooks</td>\n</tr>\n<tr>\n<td><code>cron_jobs</code></td>\n<td>Tâches planifiées</td>\n</tr>\n<tr>\n<td><code>variables</code></td>\n<td>Magasin clé-valeur</td>\n</tr>\n<tr>\n<td><code>audit_log</code></td>\n<td>Piste d&#39;audit</td>\n</tr>\n</tbody></table>\n<p><strong>FTS5</strong> permet la recherche en texte intégral sub-milliseconde sur tout le contenu\nde mémoire. Voir <a href=\"/docs/concepts/fts5-search\">Recherche FTS5</a> pour plus de détails.</p>\n<h3>3. Service d&#39;embeddings (optionnel)</h3>\n<p>Pour la recherche sémantique, Synapse génère des embeddings vectoriels du contenu des\nmémoires. Ils sont stockés à côté des mémoires et utilisés pour la recherche de\nsimilarité.</p>\n<ul>\n<li>Fournisseur : configurable (OpenAI, modèle local, etc.)</li>\n<li>Stocké comme colonne <code>vector</code> dans la table <code>memories</code></li>\n<li>Utilisé par l&#39;endpoint <code>/memory/semantic-search</code></li>\n<li>Voir <a href=\"/docs/concepts/semantic-search\">Recherche sémantique</a></li>\n</ul>\n<h3>4. Serveur MCP (service séparé)</h3>\n<p>Le serveur MCP Synapse s&#39;exécute comme un processus distinct (port 13100). Il :</p>\n<ul>\n<li>Expose 79 outils via Model Context Protocol</li>\n<li>Prend en charge les transports stdio, HTTP/SSE et WebSocket</li>\n<li>Traduit les appels d&#39;outils MCP en appels d&#39;API Synapse</li>\n<li>Multi-tenant : une Mind Key par session</li>\n</ul>\n<h3>5. Proxy navigateur (service séparé)</h3>\n<p>Pour l&#39;automatisation de navigateur, un service distinct basé sur Playwright\ns&#39;exécute sur le port 13000. Le serveur MCP peut l&#39;appeler pour les outils\n<code>browser_*</code>.</p>\n<h3>6. Proxy SSH (service séparé)</h3>\n<p>Pour les commandes distantes basées sur SSH, un service distinct s&#39;exécute sur le\nport 12900.</p>\n<h2>Modèle multi-tenant</h2>\n<pre><code class=\"hljs language-plaintext\">Compte utilisateur (email + mot de passe)\n  │\n  ├── Mind 1 (Mind Key 1)\n  │   ├── Memories\n  │   ├── Tasks\n  │   ├── Chat\n  │   └── Scripts\n  │\n  ├── Mind 2 (Mind Key 2)\n  │   └── ... (isolé du Mind 1)\n  │\n  └── Mind 3 (Mind Key 3)\n      └── ...</code></pre><p>Chaque mind est entièrement isolé. Les Mind Keys accordent l&#39;accès à un seul mind.\nLes JWT accordent l&#39;accès au compte utilisateur (pour gérer les minds).</p>\n<p>Voir <a href=\"/docs/concepts/multi-tenancy\">Multi-tenancy</a> pour plus de détails.</p>\n<h2>Flux de requêtes</h2>\n<h3>Requête de stockage mémoire</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>Requête de recherche mémoire</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>Déploiement</h2>\n<p>Synapse est déployé comme conteneur Docker. Voir <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>Caractéristiques de performance</h2>\n<table>\n<thead>\n<tr>\n<th>Opération</th>\n<th>Latence</th>\n<th>Débit</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>Stockage mémoire</td>\n<td>~5 ms</td>\n<td>1000+ req/s</td>\n</tr>\n<tr>\n<td>Rappel mémoire</td>\n<td>~20 ms</td>\n<td>500 req/s</td>\n</tr>\n<tr>\n<td>Recherche FTS5</td>\n<td>~10 ms</td>\n<td>800 req/s</td>\n</tr>\n<tr>\n<td>Recherche sémantique</td>\n<td>~50 ms</td>\n<td>200 req/s</td>\n</tr>\n<tr>\n<td>Polling chat</td>\n<td>~5 ms</td>\n<td>2000 req/s</td>\n</tr>\n</tbody></table>\n<h2>Prochaines étapes</h2>\n<ul>\n<li><a href=\"/docs/concepts/memory-model\">Modèle de mémoire</a></li>\n<li><a href=\"/docs/concepts/multi-tenancy\">Multi-tenancy</a></li>\n<li><a href=\"/docs/concepts/fts5-search\">Recherche FTS5</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"]}