boondmanager-mcp-server 2.15.2 → 2.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/NOTICE +16 -2
- package/README.md +60 -15
- package/dist/config/access-policy.d.ts.map +1 -1
- package/dist/config/access-policy.js +6 -18
- package/dist/config/access-policy.js.map +1 -1
- package/dist/config/dictionary-overrides.d.ts.map +1 -1
- package/dist/config/dictionary-overrides.js +2 -12
- package/dist/config/dictionary-overrides.js.map +1 -1
- package/dist/config/env.d.ts +63 -0
- package/dist/config/env.d.ts.map +1 -0
- package/dist/config/env.js +116 -0
- package/dist/config/env.js.map +1 -0
- package/dist/config/profiles.d.ts +22 -8
- package/dist/config/profiles.d.ts.map +1 -1
- package/dist/config/profiles.js +48 -4
- package/dist/config/profiles.js.map +1 -1
- package/dist/constants.d.ts +13 -2
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +25 -1
- package/dist/constants.js.map +1 -1
- package/dist/icons.d.ts.map +1 -1
- package/dist/icons.js +6 -1
- package/dist/icons.js.map +1 -1
- package/dist/index.js +33 -15
- package/dist/index.js.map +1 -1
- package/dist/instructions.d.ts +1 -1
- package/dist/instructions.d.ts.map +1 -1
- package/dist/instructions.js +6 -6
- package/dist/instructions.js.map +1 -1
- package/dist/prompts/index.d.ts +19 -1
- package/dist/prompts/index.d.ts.map +1 -1
- package/dist/prompts/index.js +495 -25
- package/dist/prompts/index.js.map +1 -1
- package/dist/prompts/periods.d.ts +45 -0
- package/dist/prompts/periods.d.ts.map +1 -0
- package/dist/prompts/periods.js +154 -0
- package/dist/prompts/periods.js.map +1 -0
- package/dist/resources/index.d.ts +14 -0
- package/dist/resources/index.d.ts.map +1 -1
- package/dist/resources/index.js +285 -0
- package/dist/resources/index.js.map +1 -1
- package/dist/resources/templates.d.ts +1 -1
- package/dist/resources/templates.d.ts.map +1 -1
- package/dist/resources/templates.js +2 -0
- package/dist/resources/templates.js.map +1 -1
- package/dist/schema-dialect.js.map +1 -1
- package/dist/schemas/filter-aliases.d.ts +1 -1
- package/dist/schemas/filter-aliases.d.ts.map +1 -1
- package/dist/schemas/filter-aliases.js +101 -2
- package/dist/schemas/filter-aliases.js.map +1 -1
- package/dist/schemas/index.d.ts +987 -161
- package/dist/schemas/index.d.ts.map +1 -1
- package/dist/schemas/index.js +853 -323
- package/dist/schemas/index.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +10 -3
- package/dist/server.js.map +1 -1
- package/dist/services/boond-client.d.ts +29 -213
- package/dist/services/boond-client.d.ts.map +1 -1
- package/dist/services/boond-client.js +29 -1168
- package/dist/services/boond-client.js.map +1 -1
- package/dist/services/dictionary.d.ts +27 -3
- package/dist/services/dictionary.d.ts.map +1 -1
- package/dist/services/dictionary.js +60 -23
- package/dist/services/dictionary.js.map +1 -1
- package/dist/services/document-text.d.ts +32 -0
- package/dist/services/document-text.d.ts.map +1 -0
- package/dist/services/document-text.js +120 -0
- package/dist/services/document-text.js.map +1 -0
- package/dist/services/format/detail.d.ts +16 -0
- package/dist/services/format/detail.d.ts.map +1 -0
- package/dist/services/format/detail.js +36 -0
- package/dist/services/format/detail.js.map +1 -0
- package/dist/services/format/html.d.ts +19 -0
- package/dist/services/format/html.d.ts.map +1 -0
- package/dist/services/format/html.js +87 -0
- package/dist/services/format/html.js.map +1 -0
- package/dist/services/format/list.d.ts +3 -0
- package/dist/services/format/list.d.ts.map +1 -0
- package/dist/services/format/list.js +44 -0
- package/dist/services/format/list.js.map +1 -0
- package/dist/services/format/summary.d.ts +16 -0
- package/dist/services/format/summary.d.ts.map +1 -0
- package/dist/services/format/summary.js +172 -0
- package/dist/services/format/summary.js.map +1 -0
- package/dist/services/format/tab.d.ts +9 -0
- package/dist/services/format/tab.d.ts.map +1 -0
- package/dist/services/format/tab.js +32 -0
- package/dist/services/format/tab.js.map +1 -0
- package/dist/services/http/auth.d.ts +44 -0
- package/dist/services/http/auth.d.ts.map +1 -0
- package/dist/services/http/auth.js +146 -0
- package/dist/services/http/auth.js.map +1 -0
- package/dist/services/http/download.d.ts +60 -0
- package/dist/services/http/download.d.ts.map +1 -0
- package/dist/services/http/download.js +160 -0
- package/dist/services/http/download.js.map +1 -0
- package/dist/services/http/errors.d.ts +45 -0
- package/dist/services/http/errors.d.ts.map +1 -0
- package/dist/services/http/errors.js +188 -0
- package/dist/services/http/errors.js.map +1 -0
- package/dist/services/http/rate-limit.d.ts +40 -0
- package/dist/services/http/rate-limit.d.ts.map +1 -0
- package/dist/services/http/rate-limit.js +92 -0
- package/dist/services/http/rate-limit.js.map +1 -0
- package/dist/services/http/retry.d.ts +46 -0
- package/dist/services/http/retry.d.ts.map +1 -0
- package/dist/services/http/retry.js +101 -0
- package/dist/services/http/retry.js.map +1 -0
- package/dist/services/http/transport.d.ts +73 -0
- package/dist/services/http/transport.d.ts.map +1 -0
- package/dist/services/http/transport.js +272 -0
- package/dist/services/http/transport.js.map +1 -0
- package/dist/services/logger.d.ts +53 -2
- package/dist/services/logger.d.ts.map +1 -1
- package/dist/services/logger.js +82 -21
- package/dist/services/logger.js.map +1 -1
- package/dist/services/oauth.d.ts +12 -0
- package/dist/services/oauth.d.ts.map +1 -1
- package/dist/services/oauth.js +21 -8
- package/dist/services/oauth.js.map +1 -1
- package/dist/services/rate-limiter.d.ts +9 -2
- package/dist/services/rate-limiter.d.ts.map +1 -1
- package/dist/services/rate-limiter.js +18 -6
- package/dist/services/rate-limiter.js.map +1 -1
- package/dist/services/request-context.d.ts +47 -0
- package/dist/services/request-context.d.ts.map +1 -0
- package/dist/services/request-context.js +112 -0
- package/dist/services/request-context.js.map +1 -0
- package/dist/services/search.d.ts +26 -0
- package/dist/services/search.d.ts.map +1 -0
- package/dist/services/search.js +98 -0
- package/dist/services/search.js.map +1 -0
- package/dist/services/update-checker.d.ts.map +1 -1
- package/dist/services/update-checker.js +15 -8
- package/dist/services/update-checker.js.map +1 -1
- package/dist/tools/absences.d.ts +9 -0
- package/dist/tools/absences.d.ts.map +1 -1
- package/dist/tools/absences.js +65 -20
- package/dist/tools/absences.js.map +1 -1
- package/dist/tools/actions.d.ts.map +1 -1
- package/dist/tools/actions.js +11 -27
- package/dist/tools/actions.js.map +1 -1
- package/dist/tools/advantages.d.ts +2 -0
- package/dist/tools/advantages.d.ts.map +1 -1
- package/dist/tools/advantages.js +66 -13
- package/dist/tools/advantages.js.map +1 -1
- package/dist/tools/alerts.d.ts +18 -0
- package/dist/tools/alerts.d.ts.map +1 -0
- package/dist/tools/alerts.js +82 -0
- package/dist/tools/alerts.js.map +1 -0
- package/dist/tools/application.d.ts +2 -1
- package/dist/tools/application.d.ts.map +1 -1
- package/dist/tools/application.js +9 -3
- package/dist/tools/application.js.map +1 -1
- package/dist/tools/contacts.d.ts.map +1 -1
- package/dist/tools/contacts.js +3 -7
- package/dist/tools/contacts.js.map +1 -1
- package/dist/tools/contracts.d.ts +22 -0
- package/dist/tools/contracts.d.ts.map +1 -1
- package/dist/tools/contracts.js +185 -52
- package/dist/tools/contracts.js.map +1 -1
- package/dist/tools/crud-factory.d.ts +33 -2
- package/dist/tools/crud-factory.d.ts.map +1 -1
- package/dist/tools/crud-factory.js +42 -15
- package/dist/tools/crud-factory.js.map +1 -1
- package/dist/tools/deliveries.d.ts +3 -0
- package/dist/tools/deliveries.d.ts.map +1 -1
- package/dist/tools/deliveries.js +50 -94
- package/dist/tools/deliveries.js.map +1 -1
- package/dist/tools/description-builders.d.ts +0 -1
- package/dist/tools/description-builders.d.ts.map +1 -1
- package/dist/tools/description-builders.js +46 -3
- package/dist/tools/description-builders.js.map +1 -1
- package/dist/tools/documents.d.ts.map +1 -1
- package/dist/tools/documents.js +73 -21
- package/dist/tools/documents.js.map +1 -1
- package/dist/tools/expenses.d.ts.map +1 -1
- package/dist/tools/expenses.js +2 -11
- package/dist/tools/expenses.js.map +1 -1
- package/dist/tools/find.d.ts +61 -0
- package/dist/tools/find.d.ts.map +1 -0
- package/dist/tools/find.js +221 -0
- package/dist/tools/find.js.map +1 -0
- package/dist/tools/flags.d.ts +5 -0
- package/dist/tools/flags.d.ts.map +1 -1
- package/dist/tools/flags.js +116 -1
- package/dist/tools/flags.js.map +1 -1
- package/dist/tools/forms.d.ts +5 -0
- package/dist/tools/forms.d.ts.map +1 -0
- package/dist/tools/forms.js +64 -0
- package/dist/tools/forms.js.map +1 -0
- package/dist/tools/groupments.d.ts +5 -0
- package/dist/tools/groupments.d.ts.map +1 -0
- package/dist/tools/groupments.js +68 -0
- package/dist/tools/groupments.js.map +1 -0
- package/dist/tools/inactivities.d.ts +5 -0
- package/dist/tools/inactivities.d.ts.map +1 -0
- package/dist/tools/inactivities.js +59 -0
- package/dist/tools/inactivities.js.map +1 -0
- package/dist/tools/index.d.ts +4 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +4 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/invoices.d.ts.map +1 -1
- package/dist/tools/invoices.js +27 -2
- package/dist/tools/invoices.js.map +1 -1
- package/dist/tools/linked-entity-filters.d.ts +48 -0
- package/dist/tools/linked-entity-filters.d.ts.map +1 -0
- package/dist/tools/linked-entity-filters.js +64 -0
- package/dist/tools/linked-entity-filters.js.map +1 -0
- package/dist/tools/notifications.d.ts.map +1 -1
- package/dist/tools/notifications.js +0 -5
- package/dist/tools/notifications.js.map +1 -1
- package/dist/tools/orders.d.ts.map +1 -1
- package/dist/tools/orders.js +33 -4
- package/dist/tools/orders.js.map +1 -1
- package/dist/tools/parameter-disclosure.js.map +1 -1
- package/dist/tools/payments.d.ts +3 -0
- package/dist/tools/payments.d.ts.map +1 -1
- package/dist/tools/payments.js +43 -109
- package/dist/tools/payments.js.map +1 -1
- package/dist/tools/positionings.d.ts.map +1 -1
- package/dist/tools/positionings.js +9 -39
- package/dist/tools/positionings.js.map +1 -1
- package/dist/tools/projects.d.ts.map +1 -1
- package/dist/tools/projects.js +5 -12
- package/dist/tools/projects.js.map +1 -1
- package/dist/tools/provider-invoices.d.ts +2 -0
- package/dist/tools/provider-invoices.d.ts.map +1 -1
- package/dist/tools/provider-invoices.js +30 -111
- package/dist/tools/provider-invoices.js.map +1 -1
- package/dist/tools/purchases.d.ts +2 -0
- package/dist/tools/purchases.d.ts.map +1 -1
- package/dist/tools/purchases.js +50 -104
- package/dist/tools/purchases.js.map +1 -1
- package/dist/tools/registration-decorators.d.ts +28 -0
- package/dist/tools/registration-decorators.d.ts.map +1 -1
- package/dist/tools/registration-decorators.js +107 -0
- package/dist/tools/registration-decorators.js.map +1 -1
- package/dist/tools/resources.d.ts.map +1 -1
- package/dist/tools/resources.js +27 -5
- package/dist/tools/resources.js.map +1 -1
- package/dist/tools/rights.d.ts +101 -0
- package/dist/tools/rights.d.ts.map +1 -0
- package/dist/tools/rights.js +75 -0
- package/dist/tools/rights.js.map +1 -0
- package/dist/tools/tab-tools.js +3 -3
- package/dist/tools/tab-tools.js.map +1 -1
- package/dist/tools/timesheets.d.ts +29 -0
- package/dist/tools/timesheets.d.ts.map +1 -1
- package/dist/tools/timesheets.js +196 -126
- package/dist/tools/timesheets.js.map +1 -1
- package/dist/tools/todolists.d.ts +2 -0
- package/dist/tools/todolists.d.ts.map +1 -1
- package/dist/tools/todolists.js +64 -1
- package/dist/tools/todolists.js.map +1 -1
- package/dist/tools/validations.d.ts +9 -0
- package/dist/tools/validations.d.ts.map +1 -1
- package/dist/tools/validations.js +86 -9
- package/dist/tools/validations.js.map +1 -1
- package/dist/tools/workflows.js +1 -1
- package/dist/tools/workflows.js.map +1 -1
- package/dist/transports/http.d.ts +116 -0
- package/dist/transports/http.d.ts.map +1 -1
- package/dist/transports/http.js +422 -92
- package/dist/transports/http.js.map +1 -1
- package/dist/types.d.ts +3 -3
- package/dist/types.d.ts.map +1 -1
- package/manifest.json +7 -7
- package/package.json +14 -10
package/LICENSE
CHANGED
|
@@ -185,7 +185,7 @@
|
|
|
185
185
|
same "printed page" as the copyright notice for easier
|
|
186
186
|
identification within third-party archives.
|
|
187
187
|
|
|
188
|
-
Copyright 2025
|
|
188
|
+
Copyright 2025-2026 Silamir
|
|
189
189
|
|
|
190
190
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
191
191
|
you may not use this file except in compliance with the License.
|
package/NOTICE
CHANGED
|
@@ -1,11 +1,25 @@
|
|
|
1
1
|
BoondManager MCP Server
|
|
2
|
-
Copyright 2025
|
|
2
|
+
Copyright 2025-2026 Silamir
|
|
3
3
|
|
|
4
|
-
This product includes software developed by
|
|
4
|
+
This product includes software developed by Silamir
|
|
5
5
|
and contributors to the BoondManager MCP Server project.
|
|
6
6
|
|
|
7
|
+
Originally created by Frédéric Auguste.
|
|
8
|
+
|
|
7
9
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
10
|
you may not use this file except in compliance with the License.
|
|
9
11
|
You may obtain a copy of the License at
|
|
10
12
|
|
|
11
13
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
14
|
+
|
|
15
|
+
Unless required by applicable law or agreed to in writing, software
|
|
16
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
17
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
18
|
+
See the License for the specific language governing permissions and
|
|
19
|
+
limitations under the License.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
BoondManager is a trademark of BoondManager SAS. This project is an
|
|
24
|
+
independent, unofficial client for the BoondManager public API and is
|
|
25
|
+
not affiliated with, endorsed by, or sponsored by BoondManager SAS.
|
package/README.md
CHANGED
|
@@ -1,14 +1,22 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="https://www.silamir.com">
|
|
3
|
+
<img src="https://raw.githubusercontent.com/silamir/boondmanager-mcp-server/main/assets/silamir-logo.png" alt="Silamir" height="56" />
|
|
4
|
+
</a>
|
|
5
|
+
</p>
|
|
6
|
+
|
|
1
7
|
# BoondManager MCP Server
|
|
2
8
|
|
|
3
|
-
|
|
4
|
-
|
|
9
|
+
<p align="center"><em>Un projet open source <a href="https://www.silamir.com">Silamir</a>.</em></p>
|
|
10
|
+
|
|
11
|
+
[](https://github.com/silamir/boondmanager-mcp-server/actions/workflows/ci.yml)
|
|
12
|
+
[](https://github.com/silamir/boondmanager-mcp-server/actions/workflows/codeql.yml)
|
|
5
13
|
[](https://www.npmjs.com/package/boondmanager-mcp-server)
|
|
6
14
|
[](https://www.npmjs.com/package/boondmanager-mcp-server)
|
|
7
15
|
[](https://nodejs.org/)
|
|
8
16
|
[](https://www.typescriptlang.org/)
|
|
9
17
|
[](https://registry.modelcontextprotocol.io/)
|
|
10
18
|
[](https://hub.docker.com/r/fauguste/boondmanager-mcp-server)
|
|
11
|
-
[](https://github.com/silamir/boondmanager-mcp-server/pkgs/container/boondmanager-mcp-server)
|
|
12
20
|
[](https://opensource.org/licenses/Apache-2.0)
|
|
13
21
|
|
|
14
22
|
**Installation 1-clic :**
|
|
@@ -23,7 +31,7 @@
|
|
|
23
31
|
|
|
24
32
|
Serveur MCP (Model Context Protocol) pour l'API BoondManager, permettant a Claude (Desktop, Cowork, Code) de rechercher, consulter, creer et modifier des enregistrements dans votre instance BoondManager.
|
|
25
33
|
|
|
26
|
-
**
|
|
34
|
+
**235 outils** couvrant **42 domaines** de l'API BoondManager. Voir [TOOLS.md](./TOOLS.md) pour le catalogue auto-généré (outils + prompts + ressources).
|
|
27
35
|
|
|
28
36
|
> **Sorties structurées.** En plus du texte lisible, les outils `search`, `create`, `update` et `delete` renvoient un `structuredContent` conforme à un `outputSchema` MCP : `search` → `{ total?, count, items[] }` (résumés compacts, pas les ressources JSON:API complètes), `create`/`update` → `{ id?, type? }`, `delete` → `{ id, deleted, reason? }`. Les clients MCP qui exploitent les sorties structurées obtiennent une référence d'entité fiable pour chaîner les appels. Les outils `get` restent en texte seul (leur texte est déjà du JSON exploitable).
|
|
29
37
|
|
|
@@ -125,8 +133,12 @@ Le serveur expose les dictionnaires de reference Boond comme **ressources MCP**
|
|
|
125
133
|
| URI | Contenu |
|
|
126
134
|
|-----|---------|
|
|
127
135
|
| `boond://application/current-user` | Profil de l'utilisateur courant (id, agence, permissions) |
|
|
128
|
-
| `boond://dictionary/states/{entity}` | Etats par entite : `resources`, `candidates`, `contacts`, `companies`, `opportunities`, `projects`, `invoices`, `orders`, `positionings`, `
|
|
129
|
-
| `boond://dictionary/typeOf/{entity}` | Types par entite : `resources`, `
|
|
136
|
+
| `boond://dictionary/states/{entity}` | Etats par entite : `resources`, `candidates`, `contacts`, `companies`, `opportunities`, `projects`, `invoices`, `orders`, `positionings`, `deliveries`, `payments`, `purchases`, `provider-invoices`, `products`, `quotations`, `probations` |
|
|
137
|
+
| `boond://dictionary/typeOf/{entity}` | Types par entite : `resources`, `contacts`, `projects`, `contracts`, `deliveries`, `purchases`, `activities` |
|
|
138
|
+
| `boond://dictionary/actions/{entity}` | Types d'action par entite de rattachement : `candidates`, `contacts`, `resources`, `opportunities`, `projects`, `invoices`, `orders` (le `typeOf` de `boond_actions_create`) |
|
|
139
|
+
| `boond://dictionary/{sources,origins}` | Sources de candidature, origines d'opportunite |
|
|
140
|
+
| `boond://dictionary/{paymentMethods,paymentTerms,taxRates,contractEndReasons}` | Parametres finance / RH utilises par les ecritures |
|
|
141
|
+
| `boond://application/current-user/rights` | Niveau, agences / poles / BU, apps et droits par entite de l'utilisateur (vue condensee de `current-user`) |
|
|
130
142
|
| `boond://dictionary/countries` | Liste des pays |
|
|
131
143
|
| `boond://dictionary/currencies` | Liste des devises |
|
|
132
144
|
| `boond://dictionary/languages` | Liste des langues |
|
|
@@ -215,7 +227,7 @@ Exemples d'invocation des prompts ressources / competences / CV :
|
|
|
215
227
|
|
|
216
228
|
### Claude Desktop (one-click)
|
|
217
229
|
|
|
218
|
-
Telechargez le fichier `.mcpb` depuis la [derniere release GitHub](https://github.com/
|
|
230
|
+
Telechargez le fichier `.mcpb` depuis la [derniere release GitHub](https://github.com/silamir/boondmanager-mcp-server/releases/latest), puis dans Claude Desktop : **Fichier > Installer une extension...** et selectionnez le fichier. Les identifiants sont demandes a l'installation et stockes de maniere chiffree (Keychain macOS / Credential Manager Windows).
|
|
219
231
|
|
|
220
232
|
### Claude Code (plugin, recommande)
|
|
221
233
|
|
|
@@ -223,7 +235,7 @@ Meme confort que le one-click Desktop : un formulaire de configuration, aucune
|
|
|
223
235
|
variable d'environnement a poser soi-meme.
|
|
224
236
|
|
|
225
237
|
```
|
|
226
|
-
/plugin marketplace add
|
|
238
|
+
/plugin marketplace add silamir/boondmanager-mcp-server
|
|
227
239
|
/plugin install boondmanager-mcp@boondmanager
|
|
228
240
|
```
|
|
229
241
|
|
|
@@ -386,7 +398,7 @@ boondmanager-mcp-server
|
|
|
386
398
|
### Depuis les sources
|
|
387
399
|
|
|
388
400
|
```bash
|
|
389
|
-
git clone https://github.com/
|
|
401
|
+
git clone https://github.com/silamir/boondmanager-mcp-server.git
|
|
390
402
|
cd boondmanager-mcp-server
|
|
391
403
|
npm install
|
|
392
404
|
npm run build
|
|
@@ -483,7 +495,7 @@ goose session --with-extension "npx -y boondmanager-mcp-server"
|
|
|
483
495
|
Le depot embarque un manifeste d'extension Gemini CLI (`gemini-extension.json`). Installez l'extension directement depuis GitHub :
|
|
484
496
|
|
|
485
497
|
```bash
|
|
486
|
-
gemini extensions install https://github.com/
|
|
498
|
+
gemini extensions install https://github.com/silamir/boondmanager-mcp-server
|
|
487
499
|
```
|
|
488
500
|
|
|
489
501
|
Definissez ensuite l'authentification dans votre environnement (Gemini interpole `${VAR}` au demarrage) :
|
|
@@ -507,6 +519,8 @@ Le serveur utilise [pino](https://getpino.io/) pour des logs structures JSON (ag
|
|
|
507
519
|
|
|
508
520
|
En production (`NODE_ENV=production`), les logs sont en JSON par défaut. En dev, le format pretty (colorisé) est actif sauf si `LOG_FORMAT=json`. Chaque requête HTTP reçoit un `corrId` (8 hex) pour tracer la requête dans les logs.
|
|
509
521
|
|
|
522
|
+
Les logs sont **toujours écrits sur stderr**, quel que soit le transport : en mode stdio, stdout est réservé au flux JSON-RPC et toute autre écriture corrompt la connexion côté client. Claude Desktop capture stderr dans son visualiseur de logs (Developer → Logs), c'est donc là que les avertissements (politique d'accès, mise à jour disponible, dictionnaires) sont visibles.
|
|
523
|
+
|
|
510
524
|
### Authentification
|
|
511
525
|
|
|
512
526
|
**Option 1 : Token API JWT (recommande)**
|
|
@@ -520,6 +534,29 @@ export BOOND_USER="votre_login"
|
|
|
520
534
|
export BOOND_PASSWORD="votre_mot_de_passe"
|
|
521
535
|
```
|
|
522
536
|
|
|
537
|
+
### Transport HTTP en authentification statique (`BOOND_HTTP_STATIC_AUTH`)
|
|
538
|
+
|
|
539
|
+
Par défaut, le transport HTTP (`MCP_TRANSPORT=http`) est une *ressource protégée OAuth2* : chaque requête MCP porte le token BoondManager de **son** utilisateur (voir [`docs/oauth.md`](docs/oauth.md)). `BOOND_HTTP_STATIC_AUTH=true` remplace ce modèle par les credentials d'environnement ci-dessus, partagés par toutes les requêtes — pour un déploiement mono-locataire auto-hébergé, un pipeline CI ou une passerelle interne sans flux OAuth.
|
|
540
|
+
|
|
541
|
+
Dans ce mode, **plus rien n'authentifie le client MCP** : quiconque atteint le port agit avec les droits BoondManager de l'opérateur (lecture *et* écriture selon la politique d'accès). D'où :
|
|
542
|
+
|
|
543
|
+
| Variable | Rôle |
|
|
544
|
+
|----------|------|
|
|
545
|
+
| `MCP_HTTP_API_KEY` | Secret partagé que le client doit présenter, en `Authorization: Bearer <clé>` ou `X-Api-Key: <clé>`. Comparaison en temps constant ; absente ou fausse → `401`. **Obligatoire** dès que le serveur n'écoute pas sur loopback (`0.0.0.0`, image Docker) : sinon il **refuse de démarrer**. |
|
|
546
|
+
| `MCP_HTTP_INSECURE_STATIC_AUTH` | `1` pour accepter explicitement de démarrer sans clé hors loopback (réseau privé faisant office de frontière). Le nom dit ce qu'il fait. |
|
|
547
|
+
|
|
548
|
+
```bash
|
|
549
|
+
export MCP_TRANSPORT=http
|
|
550
|
+
export MCP_HTTP_HOST=0.0.0.0
|
|
551
|
+
export BOOND_HTTP_STATIC_AUTH=true
|
|
552
|
+
export MCP_HTTP_API_KEY="$(openssl rand -hex 32)"
|
|
553
|
+
export BOOND_USER_TOKEN=… BOOND_CLIENT_TOKEN=… BOOND_CLIENT_KEY=…
|
|
554
|
+
npx boondmanager-mcp-server
|
|
555
|
+
# côté client : Authorization: Bearer <MCP_HTTP_API_KEY>
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
`/healthz` reste accessible sans clé. En mode OAuth (défaut), `MCP_HTTP_API_KEY` est ignorée avec un avertissement : le Bearer y est le token BoondManager.
|
|
559
|
+
|
|
523
560
|
### URL personnalisee (si instance dediee)
|
|
524
561
|
|
|
525
562
|
```bash
|
|
@@ -561,6 +598,8 @@ Pour eviter qu'une boucle d'outils emballee n'inonde l'API (et n'enchaine les `4
|
|
|
561
598
|
| `BOOND_HTTP_RATE_LIMIT_RPS` | `10` | Debit soutenu (requetes/seconde). `0` desactive completement. |
|
|
562
599
|
| `BOOND_HTTP_RATE_LIMIT_BURST` | `20` | Capacite du bucket = taille maximale de rafale immediate. |
|
|
563
600
|
|
|
601
|
+
En transport HTTP OAuth, le bucket est **par utilisateur** (identite derivee du Bearer) : la rafale d'un utilisateur ne ralentit pas les autres. En stdio et en static auth, une seule identite, donc un seul bucket — la limite est par identite, pas par processus.
|
|
602
|
+
|
|
564
603
|
### Cache du dictionnaire
|
|
565
604
|
|
|
566
605
|
L'API BoondManager n'expose qu'un seul endpoint `/application/dictionary` qui renvoie l'intégralité des libellés (états, types, pays…). Le serveur le met en cache en mémoire pour éviter de le re-télécharger à chaque résolution état/type → libellé.
|
|
@@ -675,6 +714,7 @@ npx boondmanager-mcp-server
|
|
|
675
714
|
| `MCP_HTTP_SESSION_SWEEP_INTERVAL_MS` | `300000` (5 min) | Frequence de balayage des sessions inactives. |
|
|
676
715
|
| `MCP_HTTP_ALLOWED_HOSTS` | _(auto)_ | Liste blanche du header `Host` (anti DNS rebinding, CVE-2025-66414). `*` pour desactiver explicitement. |
|
|
677
716
|
| `MCP_HTTP_ALLOWED_ORIGINS` | _(auto)_ | Liste blanche du header `Origin` (scheme + host + port) pour les clients navigateur ; un `Origin` hors liste recoit un `403` (exigence spec 2025-11-25). Defaut quand le serveur ecoute en loopback = **toute origine loopback, quel que soit le port** (`http`/`https` sur `localhost` / `127.0.0.1` / `[::1]`) plus l'origine de `MCP_HTTP_PUBLIC_URL` si elle est definie — MCP Inspector (`:6274`) ou un serveur de dev (`:5173`) fonctionnent sans configuration, et une origine distante recoit toujours un `403`. Validation desactivee sinon. Une liste explicite est en revanche comparee a l'identique (port compris). **Une requete sans `Origin` est toujours acceptee** (curl, gateways, clients MCP non-navigateur), et le document de decouverte `/.well-known/oauth-protected-resource` est exempte. `*` pour desactiver explicitement ; une valeur vide n'est pas une desactivation. |
|
|
717
|
+
| `MCP_HTTP_VALIDATE_TOKEN` | `false` | Mode OAuth : valide chaque Bearer aupres de BoondManager (`GET /application/current-user`, mis en cache par token pendant `MCP_HTTP_TOKEN_VALIDATION_TTL_MS`, 60 s par defaut) **avant** de traiter la requete. Un token expire ou revoque recoit un `401` + `WWW-Authenticate: … error="invalid_token"`, ce que les clients MCP conformes transforment en nouvelle autorisation — sans l'option, le 401 n'apparait que dans le resultat d'un appel d'outil, d'ou aucun client ne relance l'OAuth. BoondManager injoignable → la requete passe (fail open). |
|
|
678
718
|
|
|
679
719
|
**Variables OAuth2 — discovery (toutes optionnelles)**
|
|
680
720
|
|
|
@@ -722,7 +762,7 @@ Une image Docker prete a l'emploi est publiee a chaque release sur deux registre
|
|
|
722
762
|
|
|
723
763
|
| Registre | Image | Page |
|
|
724
764
|
|---|---|---|
|
|
725
|
-
| GitHub Container Registry | `ghcr.io/
|
|
765
|
+
| GitHub Container Registry | `ghcr.io/silamir/boondmanager-mcp-server` | [github.com/silamir/boondmanager-mcp-server/pkgs/container/boondmanager-mcp-server](https://github.com/silamir/boondmanager-mcp-server/pkgs/container/boondmanager-mcp-server) |
|
|
726
766
|
| Docker Hub | `docker.io/fauguste/boondmanager-mcp-server` | [hub.docker.com/r/fauguste/boondmanager-mcp-server](https://hub.docker.com/r/fauguste/boondmanager-mcp-server) |
|
|
727
767
|
|
|
728
768
|
Memes digests, memes tags — choisissez celui qui s'aligne avec votre tooling. L'image demarre par defaut en transport HTTP, sur le port 3000, sur l'interface `0.0.0.0`. **Aucun volume, aucun secret a stocker** — le serveur est stateless par construction.
|
|
@@ -733,7 +773,7 @@ docker run -d --restart unless-stopped \
|
|
|
733
773
|
-p 127.0.0.1:3000:3000 \
|
|
734
774
|
-e MCP_HTTP_PUBLIC_URL=https://mcp.votre-domaine.com/mcp \
|
|
735
775
|
--name boondmanager-mcp \
|
|
736
|
-
ghcr.io/
|
|
776
|
+
ghcr.io/silamir/boondmanager-mcp-server:latest
|
|
737
777
|
|
|
738
778
|
# Ou via Docker Hub (anonyme)
|
|
739
779
|
docker run -d --restart unless-stopped \
|
|
@@ -892,7 +932,7 @@ sur leurs schemas (le SDK MCP convertit les schemas Zod avec `target: 'draft-7'`
|
|
|
892
932
|
qui valide avec un validateur **2020-12 uniquement** refuse de compiler un tel schema.
|
|
893
933
|
|
|
894
934
|
**Correctif : mettre a jour vers >= 2.12.2.** Depuis cette version le serveur n'annonce plus
|
|
895
|
-
aucun dialecte (`src/schema-dialect.ts`), ce que la suite de tests verifie sur les
|
|
935
|
+
aucun dialecte (`src/schema-dialect.ts`), ce que la suite de tests verifie sur les 185 outils
|
|
896
936
|
a travers un vrai client, sous validateur 2020-12 **et** draft-07.
|
|
897
937
|
|
|
898
938
|
**Redemarrer le connecteur ne suffit pas** : un redemarrage relance le binaire installe, il ne le
|
|
@@ -914,7 +954,7 @@ Selon le canal d'installation :
|
|
|
914
954
|
| Extension Claude Desktop (`.mcpb`) | Telecharger le `.mcpb` de la derniere release et le reinstaller -- les extensions tierces ne s'auto-mettent pas a jour |
|
|
915
955
|
| Plugin Claude Code | `/plugin marketplace update boondmanager` puis reinstaller le plugin (le lancement est epingle sur `boondmanager-mcp-server@X.Y.Z`) |
|
|
916
956
|
| `claude mcp add` / config manuelle | Epingler `boondmanager-mcp-server@latest` (ou une version >= 2.12.2) dans la commande `npx` |
|
|
917
|
-
| Docker / GHCR | `docker pull ghcr.io/
|
|
957
|
+
| Docker / GHCR | `docker pull ghcr.io/silamir/boondmanager-mcp-server:latest` |
|
|
918
958
|
|
|
919
959
|
> Verifiez aussi la version de Node : le serveur requiert **Node.js >= 22**. Un poste encore en
|
|
920
960
|
> Node 20 est en general un poste dont l'installation n'a pas ete rafraichie depuis longtemps.
|
|
@@ -970,6 +1010,11 @@ npm run typecheck
|
|
|
970
1010
|
|
|
971
1011
|
## Licence
|
|
972
1012
|
|
|
973
|
-
Apache License 2.0
|
|
1013
|
+
Apache License 2.0 — Copyright (c) 2025-2026 [Silamir](https://www.silamir.com).
|
|
1014
|
+
Créé à l'origine par Frédéric Auguste.
|
|
974
1015
|
|
|
975
1016
|
Voir [LICENSE](./LICENSE) et [NOTICE](./NOTICE) pour les détails.
|
|
1017
|
+
|
|
1018
|
+
BoondManager est une marque de BoondManager SAS. Ce projet est un client
|
|
1019
|
+
indépendant et non officiel de l'API publique BoondManager, sans affiliation
|
|
1020
|
+
avec BoondManager SAS.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"access-policy.d.ts","sourceRoot":"","sources":["../../src/config/access-policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"access-policy.d.ts","sourceRoot":"","sources":["../../src/config/access-policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAMzE;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEhE,eAAO,MAAM,cAAc,EAAE,SAAS,SAAS,EAA2C,CAAC;AAE3F,gFAAgF;AAChF,MAAM,WAAW,eAAe;IAC9B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC3B,gHAAgH;IAChH,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;IACnC,qFAAqF;IACrF,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7B,kDAAkD;IAClD,UAAU,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC;CAC5B;AA0FD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,YAAY,CAyDtF;AAED,oFAAoF;AACpF,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAK7E;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,WAAW,EAAE,eAAe,GAAG,SAAS,GAAG,SAAS,CAK/E;AAED,+EAA+E;AAC/E,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,eAAe,GAAG,SAAS,GAAG,OAAO,CAE1G;AAED;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,GAAG,SAAS,CAwB7E"}
|
|
@@ -1,18 +1,10 @@
|
|
|
1
|
+
import { readBool, readString } from "./env.js";
|
|
1
2
|
import { REGISTERED_DOMAINS } from "../constants.js";
|
|
2
3
|
import { logger } from "../services/logger.js";
|
|
3
4
|
import { PROFILE_NAMES, resolveProfile } from "./profiles.js";
|
|
4
5
|
export const ALL_OPERATIONS = ["read", "create", "update", "delete"];
|
|
5
6
|
// --- Env parsing helpers (mirroring the patterns already used across the
|
|
6
7
|
// codebase: see transports/http.ts, services/oauth.ts, services/update-checker.ts) ---
|
|
7
|
-
function readEnv(env, key) {
|
|
8
|
-
const raw = env[key];
|
|
9
|
-
if (raw === undefined)
|
|
10
|
-
return undefined;
|
|
11
|
-
// Ignore unresolved placeholders like "${SOMETHING}" (same guard as http.ts).
|
|
12
|
-
if (raw.startsWith("${"))
|
|
13
|
-
return undefined;
|
|
14
|
-
return raw;
|
|
15
|
-
}
|
|
16
8
|
/** Split a CSV / whitespace-separated env value into trimmed, non-empty tokens. */
|
|
17
9
|
function parseList(raw) {
|
|
18
10
|
if (!raw)
|
|
@@ -22,10 +14,6 @@ function parseList(raw) {
|
|
|
22
14
|
.map((s) => s.trim())
|
|
23
15
|
.filter((s) => s.length > 0);
|
|
24
16
|
}
|
|
25
|
-
function parseBoolean(raw) {
|
|
26
|
-
const v = (raw ?? "").toLowerCase().trim();
|
|
27
|
-
return v === "1" || v === "true" || v === "yes";
|
|
28
|
-
}
|
|
29
17
|
/** Normalise a user-supplied domain to the canonical (dash, lowercase) form. */
|
|
30
18
|
function normalizeDomain(domain) {
|
|
31
19
|
return domain.toLowerCase().trim().replace(/_/g, "-");
|
|
@@ -96,9 +84,9 @@ export function resolveAccessPolicy(env = process.env) {
|
|
|
96
84
|
const log = logger.child({ component: "access-policy" });
|
|
97
85
|
const known = new Set(REGISTERED_DOMAINS);
|
|
98
86
|
// --- Domains ---
|
|
99
|
-
const allowItems = parseList(
|
|
100
|
-
const profileItems = parseList(
|
|
101
|
-
const excludeItems = parseList(
|
|
87
|
+
const allowItems = parseList(readString("BOOND_MCP_DOMAINS", env));
|
|
88
|
+
const profileItems = parseList(readString("BOOND_MCP_PROFILE", env));
|
|
89
|
+
const excludeItems = parseList(readString("BOOND_MCP_EXCLUDE_DOMAINS", env));
|
|
102
90
|
// Explicit domains win over a profile bundle: the operator who listed
|
|
103
91
|
// domains by hand is the one who knows exactly what they want exposed.
|
|
104
92
|
const profileDomains = resolveProfileDomains(profileItems, log);
|
|
@@ -108,8 +96,8 @@ export function resolveAccessPolicy(env = process.env) {
|
|
|
108
96
|
const allowedDomains = allowItems.length > 0 ? normalizeAndValidateDomains(allowItems, known, "BOOND_MCP_DOMAINS", log) : profileDomains;
|
|
109
97
|
const excludedDomains = normalizeAndValidateDomains(excludeItems, known, "BOOND_MCP_EXCLUDE_DOMAINS", log);
|
|
110
98
|
// --- Operations ---
|
|
111
|
-
const opItems = parseList(
|
|
112
|
-
const readOnlyShortcut =
|
|
99
|
+
const opItems = parseList(readString("BOOND_MCP_OPERATIONS", env));
|
|
100
|
+
const readOnlyShortcut = readBool("BOOND_MCP_READ_ONLY", false, env);
|
|
113
101
|
let operations;
|
|
114
102
|
if (opItems.length > 0) {
|
|
115
103
|
operations = validateOperations(opItems, log);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"access-policy.js","sourceRoot":"","sources":["../../src/config/access-policy.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAgC9D,MAAM,CAAC,MAAM,cAAc,GAAyB,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAmB3F,0EAA0E;AAC1E,uFAAuF;AAEvF,
|
|
1
|
+
{"version":3,"file":"access-policy.js","sourceRoot":"","sources":["../../src/config/access-policy.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dictionary-overrides.d.ts","sourceRoot":"","sources":["../../src/config/dictionary-overrides.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dictionary-overrides.d.ts","sourceRoot":"","sources":["../../src/config/dictionary-overrides.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,2EAA2E;AAC3E,eAAO,MAAM,eAAe,yEAA0E,CAAC;AAEvG,uEAAuE;AACvE,eAAO,MAAM,cAAc,0JAajB,CAAC;AAEX,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEjD,4CAA4C;AAC5C,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAE9C,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC1C,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;CAC1C;AAqCD;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,mBAAmB,GAAG,IAAI,CAuDxG;AASD,wBAAgB,sBAAsB,IAAI,mBAAmB,GAAG,IAAI,CAMnE;AAED,wCAAwC;AACxC,wBAAgB,gCAAgC,IAAI,IAAI,CAGvD;AAaD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAQxG;AAED,6EAA6E;AAC7E,wBAAgB,eAAe,CAAC,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAGlF;AAED,kFAAkF;AAClF,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAM9F;AAED;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAI3G"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { readFileSync } from "node:fs";
|
|
2
|
+
import { readString } from "./env.js";
|
|
2
3
|
import { z } from "zod";
|
|
3
4
|
import { logger } from "../services/logger.js";
|
|
4
5
|
/**
|
|
@@ -51,17 +52,6 @@ const OverridesFileSchema = z
|
|
|
51
52
|
})
|
|
52
53
|
.strict();
|
|
53
54
|
// --- Env parsing helper (mirroring config/access-policy.ts) ---
|
|
54
|
-
function readEnv(env, key) {
|
|
55
|
-
const raw = env[key];
|
|
56
|
-
if (raw === undefined)
|
|
57
|
-
return undefined;
|
|
58
|
-
// Ignore unresolved placeholders like "${SOMETHING}" (same guard as http.ts).
|
|
59
|
-
if (raw.startsWith("${"))
|
|
60
|
-
return undefined;
|
|
61
|
-
if (raw.trim().length === 0)
|
|
62
|
-
return undefined;
|
|
63
|
-
return raw;
|
|
64
|
-
}
|
|
65
55
|
/** Keep only known entity keys; warn-and-ignore the rest (never fatal). */
|
|
66
56
|
function filterKnownEntities(section, raw, known, log) {
|
|
67
57
|
const out = {};
|
|
@@ -82,7 +72,7 @@ function filterKnownEntities(section, raw, known, log) {
|
|
|
82
72
|
*/
|
|
83
73
|
export function loadDictionaryOverrides(env = process.env) {
|
|
84
74
|
const log = logger.child({ component: "dictionary-overrides" });
|
|
85
|
-
const raw =
|
|
75
|
+
const raw = readString("BOOND_DICTIONARY_OVERRIDES", env);
|
|
86
76
|
if (raw === undefined)
|
|
87
77
|
return null;
|
|
88
78
|
// Inline JSON if the value starts with "{", otherwise a file path.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dictionary-overrides.js","sourceRoot":"","sources":["../../src/config/dictionary-overrides.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAE/C;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,2EAA2E;AAC3E,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,CAAU,CAAC;AAEvG,uEAAuE;AACvE,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,WAAW;IACX,UAAU;IACV,SAAS;IACT,SAAS;IACT,aAAa;IACb,SAAS;IACT,aAAa;IACb,WAAW;IACX,SAAS;IACT,SAAS;IACT,OAAO;IACP,SAAS;CACD,CAAC;AAYX,gDAAgD;AAChD,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAE5E,6EAA6E;AAC7E,+CAA+C;AAC/C,MAAM,mBAAmB,GAAG,CAAC;KAC1B,MAAM,CAAC;IACN,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,cAAc,CAAC,CAAC,QAAQ,EAAE;IACvD,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,cAAc,CAAC,CAAC,QAAQ,EAAE;CACvD,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,iEAAiE;AAEjE,
|
|
1
|
+
{"version":3,"file":"dictionary-overrides.js","sourceRoot":"","sources":["../../src/config/dictionary-overrides.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one place configuration is read from the environment.
|
|
3
|
+
*
|
|
4
|
+
* Six readers used to coexist (`index.ts`, `transports/http.ts`,
|
|
5
|
+
* `services/oauth.ts`, `services/boond-client.ts`, `config/access-policy.ts`,
|
|
6
|
+
* `config/dictionary-overrides.ts`) and they disagreed on the one rule that
|
|
7
|
+
* matters for the packaged channels (issue #242): the MCPB manifest and the
|
|
8
|
+
* Claude Code plugin substitute `${user_config.KEY}` into **every** `BOOND_*`
|
|
9
|
+
* variable, so an option the user never filled arrives as `""`, as whitespace,
|
|
10
|
+
* or as the unsubstituted `"${…}"` — and only one of the six rejected the
|
|
11
|
+
* whitespace form. `MCP_HTTP_PATH=" "` became the endpoint path,
|
|
12
|
+
* `BOOND_OAUTH_AUTHORIZATION_SERVER=" "` broke the discovery document.
|
|
13
|
+
*
|
|
14
|
+
* Rule, applied by every reader here: `""`, whitespace-only and an
|
|
15
|
+
* unresolved `${…}` placeholder all mean *not configured*. A blank value must
|
|
16
|
+
* never switch a security control off (`MCP_HTTP_ALLOWED_HOSTS`) nor a
|
|
17
|
+
* restriction on (`BOOND_MCP_DOMAINS`); it falls through to the default.
|
|
18
|
+
*
|
|
19
|
+
* Every reader takes the environment as its last argument so the config
|
|
20
|
+
* modules that already accept an `env` for testing keep doing so.
|
|
21
|
+
*/
|
|
22
|
+
/** True when the raw value is one of the three "not configured" shapes. */
|
|
23
|
+
export declare function isUnset(raw: string | undefined): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* The variable's value, or `undefined` when it is absent / blank / an
|
|
26
|
+
* unresolved placeholder. The value is returned as-is (not trimmed): a
|
|
27
|
+
* password may legitimately end with a space. Callers that want a token
|
|
28
|
+
* trim it themselves.
|
|
29
|
+
*/
|
|
30
|
+
export declare function readString(name: string, env?: NodeJS.ProcessEnv): string | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* A boolean switch. `1/true/yes/on` → `true`, `0/false/no/off` → `false`,
|
|
33
|
+
* anything else (unset, blank, placeholder, garbage) → `fallback`. Both
|
|
34
|
+
* spellings are accepted because the packaged channels send booleans as
|
|
35
|
+
* strings with an explicit `default` — `"false"` must not read as "set,
|
|
36
|
+
* therefore on".
|
|
37
|
+
*/
|
|
38
|
+
export declare function readBool(name: string, fallback?: boolean, env?: NodeJS.ProcessEnv): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* A positive integer (floored), or `fallback` for unset, non-numeric, negative
|
|
41
|
+
* or — unless `allowZero` — zero values.
|
|
42
|
+
*/
|
|
43
|
+
export declare function readPositiveInt(name: string, fallback: number, env?: NodeJS.ProcessEnv, options?: {
|
|
44
|
+
allowZero?: boolean;
|
|
45
|
+
}): number;
|
|
46
|
+
/**
|
|
47
|
+
* A list: comma and/or whitespace separated, trimmed, empties dropped.
|
|
48
|
+
* `undefined` when the variable is not configured **or** yields no token
|
|
49
|
+
* (`" , "`): a list with nothing in it is "unconfigured", never "allow
|
|
50
|
+
* nothing" — the `MCP_HTTP_ALLOWED_HOSTS` rule, applied to every list.
|
|
51
|
+
*/
|
|
52
|
+
export declare function readCsv(name: string, env?: NodeJS.ProcessEnv): string[] | undefined;
|
|
53
|
+
/**
|
|
54
|
+
* An absolute URL, trimmed. Unset / blank / placeholder → `undefined`. A
|
|
55
|
+
* value that is present but not a URL **throws**, naming the variable: the
|
|
56
|
+
* URLs read here (`BOOND_BASE_URL`, `MCP_HTTP_PUBLIC_URL`,
|
|
57
|
+
* `BOOND_OAUTH_AUTHORIZATION_SERVER`) all decide where credentials are sent
|
|
58
|
+
* or where clients are told to go, so a typo must stop the start-up with a
|
|
59
|
+
* readable message rather than surface later as an opaque fetch error or a
|
|
60
|
+
* broken discovery document.
|
|
61
|
+
*/
|
|
62
|
+
export declare function readUrl(name: string, env?: NodeJS.ProcessEnv): string | undefined;
|
|
63
|
+
//# sourceMappingURL=env.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/config/env.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAKH,2EAA2E;AAC3E,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAIxD;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,GAAG,SAAS,CAGjG;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,UAAQ,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAMtG;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAA;CAAO,GACpC,MAAM,CAQR;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,EAAE,GAAG,SAAS,CAQhG;AAED;;;;;;;;GAQG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,GAAG,SAAS,CAa9F"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one place configuration is read from the environment.
|
|
3
|
+
*
|
|
4
|
+
* Six readers used to coexist (`index.ts`, `transports/http.ts`,
|
|
5
|
+
* `services/oauth.ts`, `services/boond-client.ts`, `config/access-policy.ts`,
|
|
6
|
+
* `config/dictionary-overrides.ts`) and they disagreed on the one rule that
|
|
7
|
+
* matters for the packaged channels (issue #242): the MCPB manifest and the
|
|
8
|
+
* Claude Code plugin substitute `${user_config.KEY}` into **every** `BOOND_*`
|
|
9
|
+
* variable, so an option the user never filled arrives as `""`, as whitespace,
|
|
10
|
+
* or as the unsubstituted `"${…}"` — and only one of the six rejected the
|
|
11
|
+
* whitespace form. `MCP_HTTP_PATH=" "` became the endpoint path,
|
|
12
|
+
* `BOOND_OAUTH_AUTHORIZATION_SERVER=" "` broke the discovery document.
|
|
13
|
+
*
|
|
14
|
+
* Rule, applied by every reader here: `""`, whitespace-only and an
|
|
15
|
+
* unresolved `${…}` placeholder all mean *not configured*. A blank value must
|
|
16
|
+
* never switch a security control off (`MCP_HTTP_ALLOWED_HOSTS`) nor a
|
|
17
|
+
* restriction on (`BOOND_MCP_DOMAINS`); it falls through to the default.
|
|
18
|
+
*
|
|
19
|
+
* Every reader takes the environment as its last argument so the config
|
|
20
|
+
* modules that already accept an `env` for testing keep doing so.
|
|
21
|
+
*/
|
|
22
|
+
const TRUE_VALUES = new Set(["1", "true", "yes", "on"]);
|
|
23
|
+
const FALSE_VALUES = new Set(["0", "false", "no", "off"]);
|
|
24
|
+
/** True when the raw value is one of the three "not configured" shapes. */
|
|
25
|
+
export function isUnset(raw) {
|
|
26
|
+
if (raw === undefined)
|
|
27
|
+
return true;
|
|
28
|
+
const trimmed = raw.trim();
|
|
29
|
+
return trimmed.length === 0 || trimmed.startsWith("${");
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* The variable's value, or `undefined` when it is absent / blank / an
|
|
33
|
+
* unresolved placeholder. The value is returned as-is (not trimmed): a
|
|
34
|
+
* password may legitimately end with a space. Callers that want a token
|
|
35
|
+
* trim it themselves.
|
|
36
|
+
*/
|
|
37
|
+
export function readString(name, env = process.env) {
|
|
38
|
+
const raw = env[name];
|
|
39
|
+
return isUnset(raw) ? undefined : raw;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* A boolean switch. `1/true/yes/on` → `true`, `0/false/no/off` → `false`,
|
|
43
|
+
* anything else (unset, blank, placeholder, garbage) → `fallback`. Both
|
|
44
|
+
* spellings are accepted because the packaged channels send booleans as
|
|
45
|
+
* strings with an explicit `default` — `"false"` must not read as "set,
|
|
46
|
+
* therefore on".
|
|
47
|
+
*/
|
|
48
|
+
export function readBool(name, fallback = false, env = process.env) {
|
|
49
|
+
const raw = readString(name, env)?.trim().toLowerCase();
|
|
50
|
+
if (raw === undefined)
|
|
51
|
+
return fallback;
|
|
52
|
+
if (TRUE_VALUES.has(raw))
|
|
53
|
+
return true;
|
|
54
|
+
if (FALSE_VALUES.has(raw))
|
|
55
|
+
return false;
|
|
56
|
+
return fallback;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* A positive integer (floored), or `fallback` for unset, non-numeric, negative
|
|
60
|
+
* or — unless `allowZero` — zero values.
|
|
61
|
+
*/
|
|
62
|
+
export function readPositiveInt(name, fallback, env = process.env, options = {}) {
|
|
63
|
+
const raw = readString(name, env);
|
|
64
|
+
if (raw === undefined)
|
|
65
|
+
return fallback;
|
|
66
|
+
const parsed = Number(raw.trim());
|
|
67
|
+
if (!Number.isFinite(parsed))
|
|
68
|
+
return fallback;
|
|
69
|
+
if (parsed < 0)
|
|
70
|
+
return fallback;
|
|
71
|
+
if (parsed === 0 && !options.allowZero)
|
|
72
|
+
return fallback;
|
|
73
|
+
return Math.floor(parsed);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* A list: comma and/or whitespace separated, trimmed, empties dropped.
|
|
77
|
+
* `undefined` when the variable is not configured **or** yields no token
|
|
78
|
+
* (`" , "`): a list with nothing in it is "unconfigured", never "allow
|
|
79
|
+
* nothing" — the `MCP_HTTP_ALLOWED_HOSTS` rule, applied to every list.
|
|
80
|
+
*/
|
|
81
|
+
export function readCsv(name, env = process.env) {
|
|
82
|
+
const raw = readString(name, env);
|
|
83
|
+
if (raw === undefined)
|
|
84
|
+
return undefined;
|
|
85
|
+
const items = raw
|
|
86
|
+
.split(/[\s,]+/)
|
|
87
|
+
.map((s) => s.trim())
|
|
88
|
+
.filter((s) => s.length > 0);
|
|
89
|
+
return items.length > 0 ? items : undefined;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* An absolute URL, trimmed. Unset / blank / placeholder → `undefined`. A
|
|
93
|
+
* value that is present but not a URL **throws**, naming the variable: the
|
|
94
|
+
* URLs read here (`BOOND_BASE_URL`, `MCP_HTTP_PUBLIC_URL`,
|
|
95
|
+
* `BOOND_OAUTH_AUTHORIZATION_SERVER`) all decide where credentials are sent
|
|
96
|
+
* or where clients are told to go, so a typo must stop the start-up with a
|
|
97
|
+
* readable message rather than surface later as an opaque fetch error or a
|
|
98
|
+
* broken discovery document.
|
|
99
|
+
*/
|
|
100
|
+
export function readUrl(name, env = process.env) {
|
|
101
|
+
const raw = readString(name, env)?.trim();
|
|
102
|
+
if (raw === undefined)
|
|
103
|
+
return undefined;
|
|
104
|
+
let parsed;
|
|
105
|
+
try {
|
|
106
|
+
parsed = new URL(raw);
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
throw new Error(`Invalid ${name}: "${raw}" is not an absolute URL (expected e.g. https://host/path)`);
|
|
110
|
+
}
|
|
111
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
112
|
+
throw new Error(`Invalid ${name}: "${raw}" must use http:// or https://`);
|
|
113
|
+
}
|
|
114
|
+
return raw;
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/config/env.ts"],"names":[],"mappings":"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"}
|