{"_id":"@aveplus_dev/mcp-chat-sdk","_rev":"3-635dd7c435ede7c4355de72021e93caf","name":"@aveplus_dev/mcp-chat-sdk","dist-tags":{"latest":"0.1.2"},"versions":{"0.1.0":{"name":"@aveplus_dev/mcp-chat-sdk","version":"0.1.0","keywords":["mcp","chat","sdk","widget"],"license":"Apache-2.0","_id":"@aveplus_dev/mcp-chat-sdk@0.1.0","maintainers":[{"name":"aveplus-dev","email":"lfranck@aveplus.net"},{"name":"kjonathan","email":"jonathankabore82@gmail.com"}],"dist":{"shasum":"911fd9c686bdb6140aee164ad01f88c25f010a89","tarball":"https://registry.npmjs.org/@aveplus_dev/mcp-chat-sdk/-/mcp-chat-sdk-0.1.0.tgz","fileCount":27,"integrity":"sha512-/WccME5ObZOwr3fC+CScVIUfd+cgtqjMsIAvGndViT2I/03Y4nMgFn2np9tMbiBEIyIrVodrJBV/CREmlplUaQ==","signatures":[{"sig":"MEQCIFfI76fWpb9gR+Aq2kH/1jQN+6r2HgRvWe8iTOp401JFAiBfePg2Q0iuebnqedALq2EtWcObGOOEM65QYmxa0iyHJg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":81758},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"2ea60f889c13610ad771a6d729528ea16bf8a877","scripts":{"test":"vitest run","build":"tsc -b","clean":"rm -rf dist tsconfig.tsbuildinfo","typecheck":"tsc --noEmit"},"_npmUser":{"name":"kjonathan","email":"jonathankabore82@gmail.com"},"_npmVersion":"10.9.2","description":"SDK JavaScript pour integrer un chat conversationnel MCP dans une application tierce","directories":{},"sideEffects":false,"_nodeVersion":"22.17.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.10","typescript":"^7.0.2"},"_npmOperationalInternal":{"tmp":"tmp/mcp-chat-sdk_0.1.0_1787574503338_0.04149622219319893","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@aveplus_dev/mcp-chat-sdk","version":"0.1.1","keywords":["mcp","chat","sdk","widget"],"license":"Apache-2.0","_id":"@aveplus_dev/mcp-chat-sdk@0.1.1","maintainers":[{"name":"aveplus-dev","email":"lfranck@aveplus.net"},{"name":"kjonathan","email":"jonathankabore82@gmail.com"}],"dist":{"shasum":"4e091ad06e1ff878d8a1630bca376b224c206930","tarball":"https://registry.npmjs.org/@aveplus_dev/mcp-chat-sdk/-/mcp-chat-sdk-0.1.1.tgz","fileCount":27,"integrity":"sha512-zAXfNRLyX1F+oPuOOirixj5UDR4eqWRAFgmZfnDl19ydQ+FvUuU+Yg4e8ZyFuCOofMMpmAP+ehSFv3z9tLWLxw==","signatures":[{"sig":"MEQCIA4V+bJLw3dRkBlI2gmyh4wWo9yjo7v0rBD3WuDk0XRUAiBaaY/q3mx7bl3ehYwYgVe6MPbuPSn1LV5QbuIWTbLa2g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":82641},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"520681123ec63a1e917bc738898987d5e832d77e","scripts":{"test":"vitest run","build":"tsc -b","clean":"rm -rf dist tsconfig.tsbuildinfo","typecheck":"tsc --noEmit"},"_npmUser":{"name":"kjonathan","email":"jonathankabore82@gmail.com"},"_npmVersion":"10.9.2","description":"SDK JavaScript pour integrer un chat conversationnel MCP dans une application tierce","directories":{},"sideEffects":false,"_nodeVersion":"22.17.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.10","typescript":"^7.0.2"},"_npmOperationalInternal":{"tmp":"tmp/mcp-chat-sdk_0.1.1_1787845346918_0.8661240332845361","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@aveplus_dev/mcp-chat-sdk","version":"0.1.2","description":"SDK JavaScript pour integrer un chat conversationnel MCP dans une application tierce","license":"Apache-2.0","type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"sideEffects":false,"engines":{"node":">=18"},"scripts":{"build":"tsc -b","typecheck":"tsc --noEmit","clean":"rm -rf dist tsconfig.tsbuildinfo","test":"vitest run"},"keywords":["mcp","chat","sdk","widget"],"publishConfig":{"access":"public"},"devDependencies":{"typescript":"^7.0.2","vitest":"^4.1.10"},"_id":"@aveplus_dev/mcp-chat-sdk@0.1.2","gitHead":"6b19bd3d43642e27cc92692f6233017bd441f82c","_nodeVersion":"22.17.1","_npmVersion":"10.9.2","dist":{"integrity":"sha512-oqK5Aza0LYP6biJ9Fkm1Ms8551KZT3b202DNNe5Uc4PDQ6N52HAXsCfpYur2qkwQqh3P0BgimxYqhZn2Nuw1Gg==","shasum":"be0b7abf10f7a7765dc7f311cf2fdd75df55906a","tarball":"https://registry.npmjs.org/@aveplus_dev/mcp-chat-sdk/-/mcp-chat-sdk-0.1.2.tgz","fileCount":31,"unpackedSize":96957,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIAh2nc+osTBYYR6u73PDWZDqwZQmjmputqVWYXD295FjAiBCKUSCg94njIYcmZj5LUCNhwg2oR8fsuSQ3dFuaYfxMw=="}]},"_npmUser":{"name":"kjonathan","email":"jonathankabore82@gmail.com"},"directories":{},"maintainers":[{"name":"aveplus-dev","email":"lfranck@aveplus.net"},{"name":"kjonathan","email":"jonathankabore82@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/mcp-chat-sdk_0.1.2_1788467513111_0.09001710806503427"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-24T12:28:23.066Z","modified":"2026-09-03T20:31:53.437Z","0.1.0":"2026-08-24T12:28:23.475Z","0.1.1":"2026-08-27T15:42:27.060Z","0.1.2":"2026-09-03T20:31:53.275Z"},"license":"Apache-2.0","keywords":["mcp","chat","sdk","widget"],"description":"SDK JavaScript pour integrer un chat conversationnel MCP dans une application tierce","maintainers":[{"name":"aveplus-dev","email":"lfranck@aveplus.net"},{"name":"kjonathan","email":"jonathankabore82@gmail.com"}],"readme":"# @aveplus_dev/mcp-chat-sdk\n\nSDK JavaScript pour intégrer un assistant conversationnel dans une\napplication tierce. Fournit un client bas niveau et un widget prêt à\nl'emploi.\n\n## Installation\n\n```bash\nnpm install @aveplus_dev/mcp-chat-sdk\n```\n\n## Principe\n\nLe SDK s'exécute dans le navigateur. La clé API de votre projet ne doit\ndonc jamais lui être confiée : tout ce que le navigateur envoie est\nlisible dans les outils de développement, et une clé exposée donnerait à\nn'importe qui accès à votre projet.\n\nVotre application expose donc un endpoint de relais. Le widget l'appelle,\net c'est votre serveur qui ajoute la clé avant de transmettre à l'API MCP :\n\n```\nnavigateur (widget)  →  votre serveur  →  API MCP\n                             ↑\n                     la clé de projet est ici\n```\n## Démarrage rapide\n\n```javascript\nimport { ChatWidget } from \"@aveplus_dev/mcp-chat-sdk\";\n\nnew ChatWidget({\n  baseUrl: \"/api\",\n  theme: {\n    primaryColor: \"#0F5132\",\n    title: \"Assistant\",\n  },\n}).mount();\n```\n\nLe widget appelle `/api/chat/messages/stream` et\n`/api/chat/sessions/:id/status` sur votre serveur, qui les relaie vers\nl'API MCP.\n\n## L'endpoint de relais\n\nExemple minimal en Node :\n\n```javascript\napp.all(\"/api/chat/*\", async (req, res) => {\n  // Vérifiez ici la session de VOTRE utilisateur avant de laisser passer.\n  const target = `${MCP_BASE_URL}${req.path.replace(\"/api\", \"\")}`;\n\n  const upstream = await fetch(target, {\n    method: req.method,\n    headers: {\n      authorization: `Bearer ${process.env.MCP_API_KEY}`,\n      \"content-type\": \"application/json\",\n      accept: req.headers.accept ?? \"application/json\",\n    },\n    body: req.method === \"GET\" ? undefined : JSON.stringify(req.body),\n  });\n\n  res.status(upstream.status);\n\n  // Retransmettez le flux morceau par morceau : le mettre en tampon\n  // annulerait l'intérêt du streaming.\n  const reader = upstream.body.getReader();\n\n  for (;;) {\n    const { done, value } = await reader.read();\n    if (done) break;\n    res.write(value);\n  }\n\n  res.end();\n});\n```\n\nUn exemple complet et fonctionnel se trouve dans `examples/demo`.\n\n## Authentification de l'utilisateur final\n\nAu premier message, l'API ne connaît pas l'utilisateur et demande une\nconnexion. Le SDK expose ce moment par `onAuthRequired`.\n\n**Si votre utilisateur est déjà connecté chez vous**, validez en arrière-plan\net retournez `true` : le widget reprend la conversation sans rien afficher.\n\n```javascript\nnew ChatWidget({\n  baseUrl: \"/api\",\n  onAuthRequired: async ({ token, sessionId }) => {\n    // Votre backend connaît l'utilisateur : il appelle directement le\n    // callback de vérification MCP.\n    await fetch(\"/api/chat-link/validate\", {\n      method: \"POST\",\n      headers: { \"content-type\": \"application/json\" },\n      body: JSON.stringify({ token, sessionId }),\n    });\n\n    return true;\n  },\n}).mount();\n```\n\n`/api/chat-link/validate` n'est fourni ni par le SDK ni par l'API MCP :\nc'est un endpoint que **vous** implémentez dans votre propre backend. Son\nrôle est de retrouver l'utilisateur via votre propre session, puis\nd'appeler le callback de vérification MCP en y ajoutant le secret de\nvérification du projet — qui, comme la clé API, ne doit jamais atteindre\nle navigateur :\n\n```javascript\napp.post(\"/api/chat-link/validate\", async (req, res) => {\n  const { token } = req.body;\n  const externalUserId = req.session.userId; // votre propre authentification\n\n  const upstream = await fetch(`${MCP_AUTH_URL}/auth/chat-link/callback`, {\n    method: \"POST\",\n    headers: { \"content-type\": \"application/json\" },\n    body: JSON.stringify({\n      projectId: MCP_PROJECT_ID,\n      token,\n      secret: MCP_VERIFICATION_SECRET,\n      externalUserId,\n    }),\n  });\n\n  res.status(upstream.status).end();\n});\n```\n\n**Sinon**, retournez `false` (ou n'implémentez pas l'option) : le widget\naffiche le lien de connexion et attend que la session devienne active.\n\nVotre page de connexion reçoit `?token=...&sessionId=...`. Après\nauthentification, appelez le callback de vérification MCP avec ce token,\nvotre secret de vérification et l'identifiant de votre utilisateur.\n\n## Options\n\n### `ChatWidgetOptions`\n\n| Option | Type | Description |\n|---|---|---|\n| `baseUrl` | `string` | Préfixe des appels, vers votre relais |\n| `headers` | `Record<string, string>` | En-têtes additionnels |\n| `container` | `HTMLElement` | Élément hôte (défaut : `document.body`) |\n| `theme` | `ChatTheme` | Personnalisation visuelle |\n| `showToolCalls` | `boolean` | Affiche les appels d'outils (défaut : `false`) |\n| `onAuthRequired` | `(info) => boolean` | Point d'extension d'authentification |\n| `authPollIntervalMs` | `number` | Intervalle de sondage du statut (défaut : 2000) |\n| `authPollTimeoutMs` | `number` | Délai maximal d'attente (défaut : 300000) |\n\n### `ChatTheme`\n\n| Option | Défaut |\n|---|---|\n| `primaryColor` | `#0F5132` |\n| `onPrimaryColor` | `#FFFFFF` |\n| `logoUrl` | aucun |\n| `title` | `Assistant` |\n| `subtitle` | `En ligne` |\n| `placeholder` | `Écrivez votre message…` |\n\n## Conserver une conversation\n\nLe widget crée une session au premier message. Pour la restaurer après\nrechargement de page, conservez son identifiant de votre côté :\n\n```javascript\nconst widget = new ChatWidget({ baseUrl: \"/api\" });\n\nconst saved = localStorage.getItem(\"chat-session\");\nif (saved) widget.resumeSession(saved);\n\nwidget.mount();\n\n// À sauvegarder après chaque échange\nlocalStorage.setItem(\"chat-session\", widget.getSessionId());\n```\n\n## Client sans interface\n\nSi vous construisez votre propre interface, utilisez `ChatClient`\ndirectement :\n\n```javascript\nimport { ChatClient } from \"@aveplus_dev/mcp-chat-sdk\";\n\nconst client = new ChatClient({ baseUrl: \"/api\" });\n\nawait client.send(\"Bonjour\", {\n  onToken: (text) => process.stdout.write(text),\n  onToolCall: (event) => console.log(\"outil :\", event.toolName),\n  onAuthRequired: (info) => console.log(\"connexion :\", info.loginUrl),\n  onDone: (sessionId) => console.log(\"\\nsession :\", sessionId),\n  onError: (message) => console.error(message),\n});\n```\n\n## Actions nécessitant confirmation\n\nUne action qui modifie des données ne s'exécute jamais sans accord\nexplicite. L'événement `onConfirmationRequired` porte un résumé de\nl'action ; répondre « oui » au message suivant l'exécute, toute autre\nréponse l'annule.\n\n## Exemple complet\n\n```bash\ncd examples/demo\nMCP_API_KEY=mcp_... node server.mjs\n```\n\nPuis ouvrez `http://localhost:5000`.\n\n## Licence\n\nApache-2.0","readmeFilename":"README.md"}