@stratta/mcp 0.12.0 → 0.12.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 +81 -64
- package/dist/tools/catalog.gen.js +20 -10
- package/package.json +1 -1
- package/skills/ingest-norm/SKILL.md +11 -2
package/README.md
CHANGED
|
@@ -9,34 +9,41 @@ mcp-name: ch.stratta/mcp
|
|
|
9
9
|
|
|
10
10
|
# @stratta/mcp
|
|
11
11
|
|
|
12
|
-
MCP server
|
|
12
|
+
The local MCP server for [Stratta](https://stratta.ch): the engineering norms
|
|
13
|
+
your bureau licensed (SIA, Eurocodes), cited to the section and page, inside
|
|
14
|
+
any agent that speaks MCP.
|
|
13
15
|
|
|
14
|
-
> Requires a free Stratta account
|
|
16
|
+
> Requires a free Stratta account: https://stratta.ch/sign-up.
|
|
15
17
|
|
|
16
18
|
> [!IMPORTANT]
|
|
17
19
|
> Your `STRATTA_API_KEY` is a **secret** — it grants read/write access to your
|
|
18
20
|
> Stratta workspace. Never commit it to a repository, paste it into a shared/
|
|
19
21
|
> project-scoped MCP config, or share it in logs. Prefer a user-scoped config or
|
|
20
|
-
> a shell environment variable. If a key leaks, revoke it immediately
|
|
21
|
-
> https://stratta.ch/
|
|
22
|
+
> a shell environment variable. If a key leaks, revoke it immediately under
|
|
23
|
+
> Settings › API keys (https://stratta.ch/settings?tab=keys).
|
|
22
24
|
|
|
23
25
|
## Do you need this package?
|
|
24
26
|
|
|
25
|
-
|
|
26
|
-
sign-in, no key
|
|
27
|
+
Usually not. Stratta also runs as a **remote connector** — one address, a
|
|
28
|
+
browser sign-in, no key, no Node:
|
|
27
29
|
|
|
28
30
|
```
|
|
29
31
|
https://stratta.ch/mcp
|
|
30
32
|
```
|
|
31
33
|
|
|
32
|
-
That is the shorter path,
|
|
33
|
-
|
|
34
|
+
That is the shorter path, the one the dashboard walks you through for Claude,
|
|
35
|
+
ChatGPT, Claude Code, Codex, Cursor, VS Code, Gemini CLI and Windsurf, and the
|
|
36
|
+
only one that works in an agent running in the cloud (claude.ai, ChatGPT). It
|
|
37
|
+
serves 32 of the 33 tools below, **ingestion included**: the pre-pass script is
|
|
38
|
+
downloaded from https://stratta.ch/ingest-prepass.py when it is not on disk.
|
|
39
|
+
See https://stratta.ch/docs/en/guides/connect-remote.
|
|
34
40
|
|
|
35
41
|
This package is what you want when:
|
|
36
42
|
|
|
37
|
-
-
|
|
38
|
-
|
|
39
|
-
-
|
|
43
|
+
- your agent **cannot open a browser** — CI, a scheduled task, a server — and
|
|
44
|
+
authenticates with an API key instead;
|
|
45
|
+
- you want `add_attachment`, the one tool the connector does not serve: it
|
|
46
|
+
uploads a file from your disk to a project dossier;
|
|
40
47
|
- you would simply rather run the server yourself.
|
|
41
48
|
|
|
42
49
|
## Install
|
|
@@ -63,7 +70,7 @@ npx -y @stratta/mcp login
|
|
|
63
70
|
```
|
|
64
71
|
|
|
65
72
|
No browser on this machine — remote server, SSH, CI? `login --paste` asks for a
|
|
66
|
-
key from https://stratta.ch/
|
|
73
|
+
key from https://stratta.ch/settings?tab=keys instead, without echoing it.
|
|
67
74
|
|
|
68
75
|
If you skip the step entirely, Claude Code prompts you for a key on the first
|
|
69
76
|
tool call.
|
|
@@ -169,50 +176,59 @@ named `E2E dossier <timestamp>` and does not delete it.
|
|
|
169
176
|
|
|
170
177
|
## Tools exposed
|
|
171
178
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
|
178
|
-
|
|
|
179
|
-
| `
|
|
180
|
-
| `
|
|
181
|
-
| `
|
|
182
|
-
| `
|
|
183
|
-
| `
|
|
184
|
-
| `
|
|
185
|
-
| `
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
|
193
|
-
|
|
|
194
|
-
| `
|
|
195
|
-
| `
|
|
196
|
-
| `
|
|
197
|
-
| `
|
|
179
|
+
33 tools, generated from one catalogue shared with the remote connector (which
|
|
180
|
+
serves the same 33 minus `add_attachment`).
|
|
181
|
+
|
|
182
|
+
**Read** (10 tools — query the norms of your workspace):
|
|
183
|
+
|
|
184
|
+
| Tool | Purpose |
|
|
185
|
+
| ----------------- | --------------------------------------------------------------------------------------- |
|
|
186
|
+
| `get_methodology` | Behavioural contract: persona, workflow, meta-routing hints, answer rules. Call first. |
|
|
187
|
+
| `whoami` | Which organisation, role and plan this connection reads as, and how many norms it sees. |
|
|
188
|
+
| `list_norms` | List all norms published in your workspace (code, year, title, language, coverage). |
|
|
189
|
+
| `get_toc` | Hierarchical TOC for a norm (default `maxDepth=1` = chapters). |
|
|
190
|
+
| `get_subtree` | Drill into a chapter/section subtree (`path` + `maxDepth`). |
|
|
191
|
+
| `get_section` | Full enriched content of a section (formulas, tables, figures, cross-refs). |
|
|
192
|
+
| `search_in_norm` | Keyword search inside a norm. |
|
|
193
|
+
| `search_corpus` | Keyword search across every norm of the workspace, grouped by norm. |
|
|
194
|
+
| `get_figure` | Retrieve a figure inline (base64 ImageContent). |
|
|
195
|
+
| `get_cross_refs` | Outgoing cross-refs from a section to other norms. |
|
|
196
|
+
|
|
197
|
+
**Dossier** (13 tools — keep what was decided on a project):
|
|
198
|
+
|
|
199
|
+
| Tool | Purpose |
|
|
200
|
+
| ------------------- | ------------------------------------------------------------------------------------------------------ |
|
|
201
|
+
| `list_dossiers` | Your organisation's dossiers, most recently touched first, with open-question counts. |
|
|
202
|
+
| `open_dossier` | Open a project's dossier, creating it if needed. Idempotent on the name. |
|
|
203
|
+
| `open_question` | Open one question to settle, with optional named options. Idempotent on the title. |
|
|
204
|
+
| `save_finding` | Record one piece of evidence: a cited article, a retained value and why, an observation. |
|
|
205
|
+
| `record_decision` | Settle a question with a decision the engineer has confirmed, and the retained option. |
|
|
206
|
+
| `load_dossier` | Reload everything: questions with their evidence and decisions, open ones first. |
|
|
207
|
+
| `resolve_question` | Close a question without a decision, or reopen one. The evidence stays. |
|
|
208
|
+
| `list_attachments` | The project attachments of a dossier: site reports, borehole logs, minutes, data sheets. |
|
|
209
|
+
| `read_attachment` | Read an attachment's text as Markdown, page by page. |
|
|
210
|
+
| `search_in_dossier` | Full-text search over a dossier's attachments, with the page of each hit. |
|
|
211
|
+
| `add_attachment` | Upload a file from the user's machine to a dossier (PDF, DOCX, XLSX, images, text). Local server only. |
|
|
212
|
+
| `list_templates` | The checklists the organisation wrote for its types of structure. |
|
|
213
|
+
| `apply_template` | Open a template's questions in a dossier and file the clauses that resolve in the corpus. |
|
|
198
214
|
|
|
199
215
|
A dossier is read, annotated, reviewed and exported from
|
|
200
216
|
[stratta.ch/dossiers](https://stratta.ch/dossiers).
|
|
201
217
|
|
|
202
|
-
**Ingest** (10 tools — add YOUR licensed norms; driven by the bundled `ingest-norm` skill):
|
|
203
|
-
|
|
204
|
-
| Tool | Purpose
|
|
205
|
-
| ----------------------------- |
|
|
206
|
-
| `ingest_status` | Check if a norm already exists in your workspace.
|
|
207
|
-
| `ingest_create_document` | Create a draft norm document.
|
|
208
|
-
| `ingest_create_sections` | Bulk-insert sections (returns `nodeId → sectionId` map).
|
|
209
|
-
| `ingest_attach_formula` | Attach a LaTeX formula to a section.
|
|
210
|
-
| `ingest_attach_table` | Attach a structured table `{headers, rows}` to a section.
|
|
211
|
-
| `ingest_attach_cross_ref` | Attach an explicit cross-ref to another norm.
|
|
212
|
-
| `ingest_upload_figure` | Upload a figure (base64 PNG/JPEG/WebP, ≤ 8 MB) to a section.
|
|
213
|
-
| `ingest_normalize_cross_refs` | Auto-detect and rebuild cross-refs from section content.
|
|
214
|
-
| `ingest_publish` |
|
|
215
|
-
| `ingest_delete` | Delete a document and all its children.
|
|
218
|
+
**Ingest** (10 tools — add YOUR licensed norms; driven by the bundled `ingest-norm` skill; owner or admin role):
|
|
219
|
+
|
|
220
|
+
| Tool | Purpose |
|
|
221
|
+
| ----------------------------- | -------------------------------------------------------------------------------- |
|
|
222
|
+
| `ingest_status` | Check if a norm already exists in your workspace, and its coverage. |
|
|
223
|
+
| `ingest_create_document` | Create a draft norm document. |
|
|
224
|
+
| `ingest_create_sections` | Bulk-insert sections (returns `nodeId → sectionId` map). |
|
|
225
|
+
| `ingest_attach_formula` | Attach a LaTeX formula to a section. |
|
|
226
|
+
| `ingest_attach_table` | Attach a structured table `{headers, rows}` to a section. |
|
|
227
|
+
| `ingest_attach_cross_ref` | Attach an explicit cross-ref to another norm. |
|
|
228
|
+
| `ingest_upload_figure` | Upload a figure (base64 PNG/JPEG/WebP, ≤ 8 MB) to a section. |
|
|
229
|
+
| `ingest_normalize_cross_refs` | Auto-detect and rebuild cross-refs from section content. |
|
|
230
|
+
| `ingest_publish` | Score the document and flip it to published; refuses below 30/100 unless forced. |
|
|
231
|
+
| `ingest_delete` | Delete a document and all its children. |
|
|
216
232
|
|
|
217
233
|
## How agents should use it
|
|
218
234
|
|
|
@@ -254,7 +270,7 @@ Requires Python ≥ 3.10 with PyMuPDF (`python -m pip install --user pymupdf`).
|
|
|
254
270
|
|
|
255
271
|
### `Authentication failed` / `Invalid API key`
|
|
256
272
|
|
|
257
|
-
- Verify the key starts with `sk_strt_` and is not revoked at https://stratta.ch/
|
|
273
|
+
- Verify the key starts with `sk_strt_` and is not revoked at https://stratta.ch/settings?tab=keys.
|
|
258
274
|
- Check the env var is reaching the process: `echo $STRATTA_API_KEY` (or `$env:STRATTA_API_KEY` on Windows PowerShell).
|
|
259
275
|
- If you copied from the UI, make sure no leading/trailing whitespace was added.
|
|
260
276
|
|
|
@@ -263,7 +279,7 @@ Requires Python ≥ 3.10 with PyMuPDF (`python -m pip install --user pymupdf`).
|
|
|
263
279
|
- Confirm outbound HTTPS to `*.convex.cloud` is allowed by your firewall/VPN.
|
|
264
280
|
- Try `curl -I https://stratta.ch` to verify general internet reachability.
|
|
265
281
|
|
|
266
|
-
### Tools don't appear in
|
|
282
|
+
### Tools don't appear in your agent
|
|
267
283
|
|
|
268
284
|
- Restart your Claude client after editing the config.
|
|
269
285
|
- Check the MCP server logs (Claude Code: `claude mcp logs stratta`; Claude Desktop: `~/Library/Logs/Claude/mcp-server-stratta.log` on macOS).
|
|
@@ -278,16 +294,17 @@ Requires Python ≥ 3.10 with PyMuPDF (`python -m pip install --user pymupdf`).
|
|
|
278
294
|
Your organization reached one of its limits. The error names the dimension, your
|
|
279
295
|
current count and the plan limit. Retrying will fail identically.
|
|
280
296
|
|
|
281
|
-
| Limit | Free
|
|
282
|
-
| --------------- |
|
|
283
|
-
| Norms | 1
|
|
284
|
-
| Sections |
|
|
285
|
-
| Figures | 60
|
|
286
|
-
| Queries / month | 500
|
|
287
|
-
| Members | 1
|
|
288
|
-
|
|
289
|
-
Beyond
|
|
290
|
-
|
|
297
|
+
| Limit | Free | Pro | Max | Team |
|
|
298
|
+
| --------------- | ----- | ------ | ------ | ------ |
|
|
299
|
+
| Norms | 1 | 15 | 60 | 75 |
|
|
300
|
+
| Sections | 1,000 | 15,000 | 60,000 | 75,000 |
|
|
301
|
+
| Figures | 60 | 750 | 3,000 | 3,750 |
|
|
302
|
+
| Queries / month | 500 | 15,000 | 60,000 | 75,000 |
|
|
303
|
+
| Members | 1 | 1 | 1 | 5 |
|
|
304
|
+
|
|
305
|
+
Beyond the included queries, paid plans bill the overage per thousand. An
|
|
306
|
+
Enterprise contract scales seats, norms and queries further; the calculator is
|
|
307
|
+
at https://stratta.ch/tarifs
|
|
291
308
|
|
|
292
309
|
Stock limits free up when you delete a norm (`ingest_delete`). The monthly query
|
|
293
310
|
counter resets on its own. Gauges live on the Workspace page of your dashboard,
|
|
@@ -470,7 +470,8 @@ export const CATALOG = [
|
|
|
470
470
|
"openWorldHint": false
|
|
471
471
|
},
|
|
472
472
|
"transports": [
|
|
473
|
-
"stdio"
|
|
473
|
+
"stdio",
|
|
474
|
+
"remote"
|
|
474
475
|
],
|
|
475
476
|
"params": {
|
|
476
477
|
"code": "Norm code, e.g. \"SIA 261\"."
|
|
@@ -487,7 +488,8 @@ export const CATALOG = [
|
|
|
487
488
|
"openWorldHint": false
|
|
488
489
|
},
|
|
489
490
|
"transports": [
|
|
490
|
-
"stdio"
|
|
491
|
+
"stdio",
|
|
492
|
+
"remote"
|
|
491
493
|
],
|
|
492
494
|
"params": {
|
|
493
495
|
"code": "Norm code as printed on the cover, e.g. \"SIA 118/262\".",
|
|
@@ -510,7 +512,8 @@ export const CATALOG = [
|
|
|
510
512
|
"openWorldHint": false
|
|
511
513
|
},
|
|
512
514
|
"transports": [
|
|
513
|
-
"stdio"
|
|
515
|
+
"stdio",
|
|
516
|
+
"remote"
|
|
514
517
|
],
|
|
515
518
|
"params": {
|
|
516
519
|
"documentId": "Document id from ingest_create_document.",
|
|
@@ -528,7 +531,8 @@ export const CATALOG = [
|
|
|
528
531
|
"openWorldHint": false
|
|
529
532
|
},
|
|
530
533
|
"transports": [
|
|
531
|
-
"stdio"
|
|
534
|
+
"stdio",
|
|
535
|
+
"remote"
|
|
532
536
|
],
|
|
533
537
|
"params": {
|
|
534
538
|
"sectionId": "Section id from ingest_create_sections.",
|
|
@@ -548,7 +552,8 @@ export const CATALOG = [
|
|
|
548
552
|
"openWorldHint": false
|
|
549
553
|
},
|
|
550
554
|
"transports": [
|
|
551
|
-
"stdio"
|
|
555
|
+
"stdio",
|
|
556
|
+
"remote"
|
|
552
557
|
],
|
|
553
558
|
"params": {
|
|
554
559
|
"sectionId": "Section id from ingest_create_sections.",
|
|
@@ -568,7 +573,8 @@ export const CATALOG = [
|
|
|
568
573
|
"openWorldHint": false
|
|
569
574
|
},
|
|
570
575
|
"transports": [
|
|
571
|
-
"stdio"
|
|
576
|
+
"stdio",
|
|
577
|
+
"remote"
|
|
572
578
|
],
|
|
573
579
|
"params": {
|
|
574
580
|
"sourceSectionId": "Section id the reference is made from.",
|
|
@@ -589,7 +595,8 @@ export const CATALOG = [
|
|
|
589
595
|
"openWorldHint": false
|
|
590
596
|
},
|
|
591
597
|
"transports": [
|
|
592
|
-
"stdio"
|
|
598
|
+
"stdio",
|
|
599
|
+
"remote"
|
|
593
600
|
],
|
|
594
601
|
"params": {
|
|
595
602
|
"sectionId": "Section id from ingest_create_sections.",
|
|
@@ -610,7 +617,8 @@ export const CATALOG = [
|
|
|
610
617
|
"openWorldHint": false
|
|
611
618
|
},
|
|
612
619
|
"transports": [
|
|
613
|
-
"stdio"
|
|
620
|
+
"stdio",
|
|
621
|
+
"remote"
|
|
614
622
|
],
|
|
615
623
|
"params": {
|
|
616
624
|
"documentId": "Document id from ingest_create_document."
|
|
@@ -627,7 +635,8 @@ export const CATALOG = [
|
|
|
627
635
|
"openWorldHint": false
|
|
628
636
|
},
|
|
629
637
|
"transports": [
|
|
630
|
-
"stdio"
|
|
638
|
+
"stdio",
|
|
639
|
+
"remote"
|
|
631
640
|
],
|
|
632
641
|
"params": {
|
|
633
642
|
"documentId": "Document id from ingest_create_document.",
|
|
@@ -645,7 +654,8 @@ export const CATALOG = [
|
|
|
645
654
|
"openWorldHint": false
|
|
646
655
|
},
|
|
647
656
|
"transports": [
|
|
648
|
-
"stdio"
|
|
657
|
+
"stdio",
|
|
658
|
+
"remote"
|
|
649
659
|
],
|
|
650
660
|
"params": {
|
|
651
661
|
"documentId": "Document id from ingest_create_document."
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stratta/mcp",
|
|
3
3
|
"mcpName": "ch.stratta/mcp",
|
|
4
|
-
"version": "0.12.
|
|
4
|
+
"version": "0.12.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>",
|
|
@@ -17,8 +17,10 @@ writes go through the Stratta MCP `ingest_*` tools, scoped to your org.
|
|
|
17
17
|
|
|
18
18
|
## Prerequisites
|
|
19
19
|
|
|
20
|
-
-
|
|
21
|
-
(
|
|
20
|
+
- Stratta is connected, either way: the remote connector
|
|
21
|
+
(`https://stratta.ch/mcp`, authorised in the browser, no key) or the local
|
|
22
|
+
package with a key (`npx -y @stratta/mcp login`). Both serve the same
|
|
23
|
+
`ingest_*` tools.
|
|
22
24
|
- **Python ≥ 3.10 with PyMuPDF**. Install once:
|
|
23
25
|
`python -m pip install --user pymupdf` (or `uv pip install pymupdf`).
|
|
24
26
|
- The norm PDF is available locally.
|
|
@@ -57,6 +59,13 @@ node -e "console.log(require.resolve('@stratta/mcp/package.json'))"
|
|
|
57
59
|
If the user is working in the Stratta monorepo, the script also lives at
|
|
58
60
|
`packages/mcp/scripts/ingest-prepass.py`.
|
|
59
61
|
|
|
62
|
+
If neither is on disk (the remote connector installs nothing), download the
|
|
63
|
+
same script from the site and keep it next to the PDF:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
curl -fsSLO https://stratta.ch/ingest-prepass.py
|
|
67
|
+
```
|
|
68
|
+
|
|
60
69
|
### 2. Check for an existing copy
|
|
61
70
|
|
|
62
71
|
`ingest_status { code }` (e.g. `"SIA 261"`). To re-ingest, call
|