@stratta/mcp 0.7.0 → 0.7.1

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/README.md CHANGED
@@ -162,21 +162,24 @@ Requires Python ≥ 3.10 with PyMuPDF (`python -m pip install --user pymupdf`).
162
162
  Your organization reached one of its limits. The error names the dimension, your
163
163
  current count and the plan limit. Retrying will fail identically.
164
164
 
165
- | Limit | Free | Pro | Team |
165
+ | Limit | Free | Pro | Max |
166
166
  |---|---|---|---|
167
- | Norms | 2 | 15 | 60 |
168
- | Sections | 500 | 5,000 | 20,000 |
167
+ | Norms | 1 | 15 | 60 |
168
+ | Sections | 500 | 5,000 | 21,000 |
169
169
  | Figures | 60 | 750 | 3,000 |
170
- | Queries / month | 500 | 15,000 | 75,000 |
171
- | Members | 1 | 3 | 15 |
170
+ | Queries / month | 500 | 15,000 | 100,000 |
171
+ | Members | 1 | 1 | 5 |
172
+
173
+ Beyond Max, an Enterprise plan scales to 100 members, 300 norms and a million
174
+ monthly queries; the calculator is at https://stratta.ch/tarifs
172
175
 
173
176
  Stock limits free up when you delete a norm (`ingest_delete`). The monthly query
174
177
  counter resets on its own. Gauges live on the Workspace page of your dashboard,
175
178
  and an org admin can also set caps below the plan. Full details:
176
- https://docs.stratta.ch/en/account/plans
179
+ https://stratta.ch/docs/en/account/plans
177
180
 
178
181
  ## License
179
182
 
180
- Proprietary — © SmartFlow, Lausanne. All rights reserved. This package is the
183
+ Proprietary — © Stratta, Lausanne. All rights reserved. This package is the
181
184
  official Stratta MCP client; redistribution, modification, or reuse of the source
182
185
  is not permitted without prior written consent.
package/dist/errors.js CHANGED
@@ -41,6 +41,10 @@ export function formatToolError(err) {
41
41
  return "Cette norme n'existe pas dans votre organisation, ou elle appartient à une autre.";
42
42
  case 'SECTION_NOT_FOUND':
43
43
  return "Cette section n'existe pas dans votre organisation.";
44
+ case 'INSUFFICIENT_ROLE':
45
+ return "Cette action modifie le corpus de normes et demande un rôle propriétaire ou administrateur de l'organisation. Demandez à un administrateur de votre espace de l'exécuter (ou de vous accorder ce rôle).";
46
+ case 'RATE_LIMITED':
47
+ return 'Trop de tentatives en peu de temps. Patientez une minute avant de réessayer.';
44
48
  default:
45
49
  return data;
46
50
  }
@@ -174,7 +174,7 @@ export const getCrossRefs = defineTool({
174
174
  export const getFigure = defineTool({
175
175
  name: 'get_figure',
176
176
  title: 'Get figure',
177
- description: 'Retrieve a figure (image) referenced in a section. Returns the image inline (base64) so you can see and reason about it, plus a public `url` for full-size viewing. Use the `id` returned by get_section in its `figures` array.',
177
+ description: 'Retrieve a figure (image) referenced in a section. Returns the image inline (base64) so you can see and reason about it. Use the `id` returned by get_section in its `figures` array.',
178
178
  inputSchema: {
179
179
  norm,
180
180
  figureId: z
@@ -192,6 +192,12 @@ export const getFigure = defineTool({
192
192
  }));
193
193
  if (!meta)
194
194
  return { error: 'Figure not found.' };
195
+ // The storage URL is used server-side, here, only to download the bytes —
196
+ // it is never returned to the agent. Convex `getUrl` hands back a bare,
197
+ // unsigned, non-expiring public link, and the norm figures are licensed,
198
+ // per-org content: surfacing that link would drop a permanent, tenant-
199
+ // bypassing capability into the model context (and thus the provider's
200
+ // logs). The agent gets the image inline instead.
195
201
  const url = (await client.action(api._mcp.getStorageUrl, {
196
202
  apiKey,
197
203
  code: args.norm,
@@ -207,7 +213,6 @@ export const getFigure = defineTool({
207
213
  return {
208
214
  caption: meta.caption,
209
215
  figureNumber: meta.figureNumber,
210
- url,
211
216
  image: {
212
217
  base64: Buffer.from(buffer).toString('base64'),
213
218
  mimeType: response.headers.get('content-type') ?? 'image/png',
@@ -222,15 +227,10 @@ export const getFigure = defineTool({
222
227
  isError: true,
223
228
  };
224
229
  }
225
- const lines = [`${r.figureNumber} — ${r.caption}`];
226
- if (r.url) {
227
- lines.push(`Image URL: ${r.url}`);
228
- lines.push(`To show this figure to the user, embed it inline in your reply as Markdown: ![${r.figureNumber}](${r.url})`);
229
- }
230
230
  return {
231
231
  content: [
232
232
  { type: 'image', data: r.image.base64, mimeType: r.image.mimeType },
233
- { type: 'text', text: lines.join('\n') },
233
+ { type: 'text', text: `${r.figureNumber} — ${r.caption}` },
234
234
  ],
235
235
  };
236
236
  },
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@stratta/mcp",
3
3
  "mcpName": "io.github.hugogebel-boop/stratta",
4
- "version": "0.7.0",
4
+ "version": "0.7.1",
5
5
  "description": "MCP server exposing the engineering norms your firm is licensed for (SIA / Eurocodes) to any MCP client, via Stratta TreeRAG.",
6
6
  "license": "UNLICENSED",
7
7
  "author": "SmartFlow <hello@stratta.ch>",