Vaulken : serveur MCP remote pour mes fichiers
Vaulken ouvre tes fichiers S3 à Claude via un serveur MCP remote. Ce qu'il fait, pour qui, et comment il est construit : OAuth, ton bucket, Qdrant, 12 tools.
Je brainstorm beaucoup avec Claude. Claude Code sur le desktop pour le dev, Claude.ai web quand je réfléchis à un problème, le mobile quand une idée me tombe dessus dans le train. Et à chaque fois que je quittais Claude Code sur mon PC, je perdais l'accès à mes notes. Mon vault Obsidian, mes specs, mes décisions d'architecture, tout restait coincé sur ma machine.
Quand j'ai fait le tour des serveurs MCP pour Obsidian, j'ai trouvé une dizaine de projets. Tous en stdio, tous locaux. Certains proposaient des tunnels Tailscale ou du Docker + reverse proxy, mais aucun n'offrait du remote natif avec OAuth.
Alors j'ai construit Vaulken, un serveur MCP remote qui donne à Claude l'accès à mes fichiers depuis n'importe où. Cet article se lit en deux temps. D'abord ce que fait Vaulken et à qui il sert. Ensuite comment il est construit : la stack, les choix d'architecture, et la conception de ses tools. La première moitié t'intéressera si tu cherches à brancher tes notes sur un LLM, la seconde si tu conçois toi-même un serveur MCP.
Le service est en bêta sur vaulken.dev, et il est gratuit. Pour la petite histoire, cet article a été écrit avec Claude branché sur mes notes via Vaulken.
Un bucket S3 entre tes notes et Claude
Vaulken s'adresse à ceux qui travaillent avec un LLM sur plusieurs appareils et qui gardent leurs connaissances dans des fichiers : notes Obsidian, specs, documentation, comptes rendus. Le problème de départ est simple. Un assistant qui tourne sur ton poste lit ton disque, mais Claude sur le web ou sur ton téléphone n'y a pas accès.
La réponse de Vaulken passe par un bucket S3-compatible. Tes fichiers y vivent. Si tu utilises Obsidian, le plugin Remotely Save synchronise ton vault vers le bucket. Sinon, n'importe quel contenu texte déposé dans un bucket fonctionne.
Vaulken se branche sur ce bucket et expose son contenu via MCPIA pour les développeurs · partie 310 minMCP pour les devs : relier tes LLM au monde réelMCP (Model Context Protocol) évite d'écrire un connecteur par client LLM et par source de données. Son architecture, puis un premier serveur MCP en TypeScript.Lire l'articleNouvel ongletUn bandeau t'y proposera de reprendre ici, section 1., le protocole qui permet à un LLM d'appeler des outils externes. Claude s'y connecte par une URL HTTPS, avec une authentification OAuth. Tu n'as ni tunnel ni serveur à maintenir, et aucun token à copier-coller.
flowchart LR
O["Obsidian<br/>(Remotely Save)"] -- sync --> B[("Ton bucket S3<br/>Scaleway, AWS, R2, MinIO")]
V["Vaulken<br/>serveur MCP remote"] -- "lit et écrit" --> B
C["Claude<br/>web, mobile, desktop"] -- "HTTPS + OAuth" --> VCe que ça change au quotidien
Je commence un brainstorm sur Claude.ai web, je continue sur mobile dans le train, je repasse en Claude Code pour implémenter. Les mêmes notes partout, plus de rupture de contexte quand je change de device.
Les idées qui me viennent loin du bureau finissaient dans les mémos vocaux, et j'oubliais de les réécouter. Maintenant je dicte à Claude, et il range la note dans Obsidian avec le bon nom, les bons tags, dans le bon dossier.
« Retrouve ce qu'on avait décidé sur la stratégie de pricing en février. » Claude cherche par concept, lit les fichiers, me fait une synthèse. Le genre de requête qui me prenait 15 minutes de navigation à la main.
Et quand Claude rédige un article technique, il a accès à ma doc, mes specs, mes analyses. Il travaille avec mon contexte réel.
Tu apportes ton bucket
Vaulken fonctionne en BYOB (Bring Your Own Bucket) : tu connectes ton propre stockage S3-compatible, chez AWS, Scaleway, Cloudflare R2, Backblaze B2 ou sur un MinIO. Je ne voulais pas héberger les notes des gens, et je ne voulais pas que les miennes partent chez un tiers. Vaulken lit et écrit directement dans ton bucket. De son côté, il ne garde que les paramètres de connexion, avec la clé secrète chiffrée en base, et les index de recherche.
Vaulken a proposé un temps un stockage géré. Depuis octobre 2026, il n'existe plus : tout vault est branché sur un bucket qui t'appartient. Si tu supprimes un vault, la connexion et les index disparaissent, tes fichiers restent où ils sont.
Un vault, dans Vaulken, c'est cette connexion entre le service et un bucket. Tu peux la restreindre à un dossier avec un préfixe de chemin. Chaque vault fournit deux URLs MCP :
- une URL en lecture seule, avec laquelle Claude lit et cherche sans pouvoir modifier ;
- une URL en lecture-écriture.
Tu colles l'une ou l'autre dans Claude.ai, Claude Code ou Cursor. L'URL en lecture seule convient bien au téléphone : aucun risque d'écraser un fichier. Tu gardes la lecture-écriture pour Claude Code, par exemple. Chaque URL porte son propre identifiant aléatoire, que tu peux régénérer sans toucher à l'autre.
Deux textes pour guider l'agent
Un LLM qui arrive dans un dossier inconnu ne sait ni ce qu'il contient ni comment tu le ranges. Vaulken lui transmet deux textes dès la connexion, dans les instructions du serveur MCP.
Le premier est la description du vault, une ou deux phrases saisies dans le dashboard. Quand plusieurs vaults sont connectés à la même conversation, c'est elle qui permet à Claude de choisir le bon.
Le second est un fichier VAULKEN.md à la racine du vault. Tu y écris tes conventions : la structure des dossiers, le nommage, ce que l'agent ne doit pas toucher sans demander. Seul le début du fichier est injecté. S'il est long, l'agent voit qu'il est tronqué et peut lire la suite.
Si tu déclares le vault comme un vault Obsidian, Vaulken ajoute les conventions d'Obsidian : frontmatter YAML, liens [[wiki]], fichiers canvas.
Comment Vaulken est construit
Tout est en TypeScript sur Node.js. Le serveur est une application Express, bundlée avec esbuild. Le dashboard, où tu crées tes vaults, est en React Router v7. Prisma gère la base relationnelle, Qdrant stocke les vecteurs de la recherche sémantique, et Redis complète l'ensemble. Le service est hébergé chez Scaleway et déployé sur K3s, une distribution allégée de Kubernetes, avec KEDA pour l'autoscaling.
flowchart LR
C["Clients MCP<br/>Claude, Claude Code, Cursor"] -- "Streamable HTTP<br/>+ OAuth" --> S["Serveur MCP<br/>Node.js, Express"]
S -- "API S3" --> B[("Ton bucket")]
O["Obsidian"] -- sync --> B
I["Indexeur<br/>en arrière-plan"] -- "parcourt" --> B
I --> Q[("Qdrant<br/>vecteurs")]
I --> D[("Base SQL, Prisma<br/>vaults, index")]
S -- "recherche" --> Q
S --> DUn serveur remote en Streamable HTTP, derrière OAuth
Vaulken parle Streamable HTTP, le transport de MCP pour les serveurs distants : le client envoie ses requêtes en POST sur une URL HTTPS. Chaque URL de vault désigne à la fois le vault et le mode d'accès, lecture seule ou lecture-écriture.
L'authentification passe par OAuth. À la première connexion, le client ouvre ton navigateur sur un écran de consentement, tu autorises, et il reçoit un jeton. Tu ne manipules aucun secret à la main. J'ai détaillé ce transport et le parcours OAuth dans l'article sur le MCP remoteMCP en pratique · partie 112 minMCP remote : quand stdio ne suffit plusStdio suffit sur ta machine, pas au-delà. Streamable HTTP sans session depuis la spec de juillet 2026, un serveur MCP remote en TypeScript, puis OAuth 2.1.Lire l'articleNouvel ongletUn bandeau t'y proposera de reprendre ici, section 4..
Un stockage derrière une interface
Les tools n'appellent jamais S3 eux-mêmes. Ils passent par une interface StorageProvider de quelques méthodes : lister, lire les métadonnées, lire, écrire, ajouter, déplacer, supprimer. S3 est le seul backend en service aujourd'hui, via le SDK AWS v3, qui accepte n'importe quel endpoint compatible.
L'interface fixe aussi le contrat du contrôle de concurrence décrit plus bas : chaque backend doit fournir un hash par fichier, et la règle reste la même quel que soit le stockage.
Trois index construits en arrière-plan
Un bucket S3 sait lister et renvoyer des objets. Il ne sait pas chercher dedans. Et des fichiers y arrivent sans passer par Vaulken, par exemple quand Obsidian synchronise. Un indexeur parcourt donc le bucket à intervalles réguliers et maintient trois index.
L'index de fichiers retient les chemins, les tailles et les dates. Il sert à répondre vite à « quels fichiers ont changé récemment » sur un gros vault, sans relister tout le bucket.
L'index de trigrammes sert à la recherche exacte. Un trigramme est une suite de trois caractères. Pour une requête, l'index désigne les fichiers qui contiennent tous ses trigrammes, puis chaque candidat est vérifié contre la chaîne exacte. Le résultat est précis, sans relire tout le bucket à chaque recherche.
L'index vectoriel sert à la recherche sémantique. Les fichiers sont découpés en morceaux, section par section pour le Markdown. Chaque morceau est transformé en embedding, un vecteur de nombres qui représente son sens, et stocké dans Qdrant. Tous les vaults partagent une même collection, et chaque vecteur porte l'identifiant de son vault, ce qui cloisonne les recherches.
Note
Conséquence de ce choix : un fichier écrit il y a quelques minutes peut ne pas encore apparaître dans les résultats de recherche. La lecture et le listing par chemin, eux, interrogent le bucket en direct.
Écrire sans écraser le travail d'un autre
Plusieurs clients peuvent écrire dans le même bucket : Claude sur le web, Claude Code, et Obsidian qui synchronise de son côté. Pour éviter qu'une écriture en efface une autre, chaque lecture complète renvoie un hash du fichier, et chaque écriture doit fournir ce hash. Si le fichier a changé entre-temps, le serveur refuse avec une erreur HASH_MISMATCH. L'agent relit, puis réessaie.
C'est du contrôle de concurrence optimiste, le même principe qu'un If-Match en HTTP. Côté S3, le hash est l'ETag de l'objet : Vaulken n'a rien à stocker pour le calculer. Pour créer un fichier, l'agent passe la valeur spéciale new à la place du hash.
Un versioning délégué au bucket
Vaulken ne garde pas l'historique de tes fichiers. Il s'appuie sur le versioning de S3, que tu actives sur ton bucket. L'indexeur détecte s'il est actif. Si oui, le serveur expose les deux tools qui listent les versions d'un fichier et en restaurent une. Restaurer ne détruit rien : la version courante devient à son tour une version de l'historique.
Attention
vaulken_delete_file supprime définitivement, il n'y a pas de corbeille. Sans versioning sur le bucket, un fichier supprimé ou écrasé par un agent est perdu. Active-le avant de donner un accès en écriture.
Douze tools conçus pour un LLM
Le serveur expose douze tools, dont deux réservés aux buckets versionnés. Ils portent tous le préfixe vaulken_, ce qui évite les collisions quand d'autres serveurs MCP exposent eux aussi un read ou un list.
| Catégorie | Tools | Rôle |
|---|---|---|
| Lecture | vaulken_read, vaulken_list, vaulken_get_file_url | Lire un fichier, lister un dossier, obtenir un lien de téléchargement temporaire pour un fichier trop lourd |
| Écriture | vaulken_edit_file, vaulken_patch_file, vaulken_move_file, vaulken_delete_file | Écrire ou modifier un fichier, appliquer plusieurs retouches d'un coup, déplacer, supprimer |
| Recherche | vaulken_search_text, vaulken_search_semantic, vaulken_get_related | Recherche exacte, recherche par le sens, fichiers proches d'un fichier donné |
| Versions | vaulken_list_versions, vaulken_restore_version | Lister et restaurer les versions précédentes d'un fichier |
vaulken_read a quatre modes. content renvoie le fichier, avec une pagination par lignes pour les gros fichiers. outline renvoie le plan d'un fichier Markdown. section renvoie le contenu d'un seul titre. metadata renvoie le frontmatter, la taille et les dates. Les PDF sont convertis en Markdown par OCR.
vaulken_edit_file regroupe les modifications simples sous cinq commandes : écrire le fichier, ajouter à la fin, remplacer une chaîne unique, remplacer le contenu d'une section, fusionner des champs dans le frontmatter. vaulken_patch_file applique jusqu'à 50 retouches en un appel. Toutes sont validées avant la moindre écriture : si une cible est absente ou ambiguë, rien n'est modifié.
C'est la recherche sémantique qui m'a le plus surpris à l'usage. Quand je demande « retrouve mes notes sur l'architecture de la base de données », Claude tombe sur les bons fichiers même si je n'y ai jamais écrit ces mots-là.
Des tools sobres en tokens
Chaque résultat de tool occupe de la place dans le contexte du LLM, et la description de chaque tool est envoyée à chaque conversation. J'ai posé les principes généraux dans l'article MCP remoteMCP en pratique · partie 112 minMCP remote : quand stdio ne suffit plusStdio suffit sur ta machine, pas au-delà. Streamable HTTP sans session depuis la spec de juillet 2026, un serveur MCP remote en TypeScript, puis OAuth 2.1.Lire l'articleNouvel ongletUn bandeau t'y proposera de reprendre ici, section 6.. Voici comment Vaulken les applique.
Il y a peu de tools, et ils ont des modes. Lire le plan d'un fichier, une section ou ses métadonnées sont des modes de vaulken_read, et les variantes d'écriture sont des commandes de vaulken_edit_file. Moins de tools, c'est moins de descriptions chargées avant même la première question.
L'agent lit le plan avant le contenu. Sur une longue spec, Claude demande l'outline, puis la seule section qui l'intéresse. Il ne charge le fichier entier que s'il en a besoin.
Les listes sont bornées. vaulken_list renvoie 200 fichiers par défaut et accepte un préfixe de chemin. Les recherches renvoient des lignes ou des extraits avec le chemin et le numéro de ligne, jamais des fichiers entiers.
Les écritures sont ciblées. Pour corriger une phrase, l'agent envoie seulement la chaîne à remplacer et sa remplaçante. Chaque écriture renvoie le nouveau hash, ce qui lui permet d'enchaîner une autre modification sans relire.
Les fichiers lourds restent hors du contexte. Une image de moins de 3 Mo est renvoyée telle quelle. Au-delà, comme pour l'audio ou la vidéo, vaulken_get_file_url fournit un lien de téléchargement signé et temporaire. Le résultat de l'OCR d'un PDF est mis en cache, la conversion n'est faite qu'une fois.
Les descriptions orientent l'agent. Chaque description dit quand utiliser le tool et lequel préférer dans le cas voisin. Celle de la recherche exacte renvoie vers la recherche sémantique quand on ne connaît pas les mots, et inversement. L'agent hésite moins, donc il fait moins d'appels inutiles.
Brancher ton vault
- Crée un compte sur vaulken.dev, puis un vault avec les paramètres de ton bucket : endpoint, région, nom du bucket, clé d'accès et clé secrète.
- Copie l'une des deux URLs MCP depuis la page du vault.
- Ajoute-la dans Claude.ai (Settings → Connectors). Dans Claude Code, la commande est
claude mcp add --transport http notes <url>. - À la première utilisation, ton navigateur s'ouvre sur l'écran de consentement. Tu autorises, et Claude accède à tes fichiers.
La documentation détaille le montage complet avec Obsidian et Remotely Save.
Au-delà d'Obsidian
Vaulken est un serveur MCP pour S3. J'ai choisi Obsidian comme porte d'entrée parce que la communauté est large et que le problème mobile y est bien identifié. Mais le serveur se moque de ce qu'il y a dans le bucket, tant que c'est du texte.
Quelques usages auxquels je n'avais pas pensé au départ :
- Un agent écrit ses résultats dans S3, un autre les lit via Vaulken. Le bucket devient une mémoire partagée entre agents.
- Un script dépose des rapports ou des extractions dans S3, et tu interroges le contenu depuis Claude.
- Des fichiers Markdown de doc dans un bucket, pour faire du Q&A sans monter un RAG.
La suite
Deux chantiers devant moi : améliorer la recherche sémantique, et simplifier la configuration du bucket S3.
Si tu veux écrire ton propre serveur plutôt qu'utiliser le mien, l'article MCP remoteMCP en pratique · partie 112 minMCP remote : quand stdio ne suffit plusStdio suffit sur ta machine, pas au-delà. Streamable HTTP sans session depuis la spec de juillet 2026, un serveur MCP remote en TypeScript, puis OAuth 2.1.Lire l'articleNouvel ongletUn bandeau t'y proposera de reprendre ici, section 9. montre un serveur Streamable HTTP minimal en TypeScript et le parcours OAuth qu'un client suit pour s'y connecter.
À lire ensuite
MCP pour les devs : relier tes LLM au monde réel
MCP (Model Context Protocol) évite d'écrire un connecteur par client LLM et par source de données. Son architecture, puis un premier serveur MCP en TypeScript.
Cité dans cet article, à propos de MCP
MCP remote : quand stdio ne suffit plus
Stdio suffit sur ta machine, pas au-delà. Streamable HTTP sans session depuis la spec de juillet 2026, un serveur MCP remote en TypeScript, puis OAuth 2.1.
Cité dans cet article
Inkfate : quand l'IA devient maître de jeu
Inkfate est un jeu de rôle solo où une IA tient le rôle du maître de jeu. Les règles du Year Zero Engine, et le pipeline LangGraph et Mistral derrière le MJ.