@bicon/mcp-composer 0.1.0 → 0.1.7
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 +137 -72
- package/dist/index.mjs +2413 -228
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -23,110 +23,175 @@ via API keys is a separate, security-reviewed phase.
|
|
|
23
23
|
|
|
24
24
|
| Name | What it does |
|
|
25
25
|
|---|---|
|
|
26
|
-
| resource `initiative://schema` / tool `get_initiative_schema` | The field catalog: required fields, enum values, the four dimensions with their named sub-dimensions (EN/DE labels + help text
|
|
27
|
-
| `assemble_initiative` | Compact spec (metadata + named sub-ratings 0–100 + confidence per dimension) → fully-formed initiative validated against the API contract (`CreateInitiativeBody` from `@workspace/api-zod`). Mints id/timestamps, **derives** the four dimension scores (
|
|
28
|
-
| `export_initiative_file` |
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
26
|
+
| resource `initiative://schema` / tool `get_initiative_schema` | The field catalog: required fields, enum values, the four dimensions with their named sub-dimensions (EN/DE labels + help text, plus the wording the app uses in digital / innovation portfolios), the exact shape of every optional section, the EU-AI-Act vocabularies, and the handoff steps. **Read this first.** |
|
|
27
|
+
| `assemble_initiative` | Compact spec (metadata + named sub-ratings 0–100 + confidence per dimension + optional sections) → fully-formed initiative validated against the API contract (`CreateInitiativeBody` from `@workspace/api-zod`). Mints id/timestamps, **derives** the four dimension scores (the app's own scoring function), returns `{ok, initiative, derivedScores, warnings, errors}`. |
|
|
28
|
+
| `export_initiative_file` | Takes the **same compact spec**, assembles it and wraps the result in the app's single-initiative JSON envelope; returns `{ok, filename, json, importInstructions, derivedScores, warnings}`. There is one pipeline — a hand-edited initiative object is not an input, so client-supplied scores or unknown keys can never bypass assembly. |
|
|
29
|
+
| `composer_version` | Returns `{composerVersion, capabilities}`. Every *successful* tool result also carries `composerVersion`. |
|
|
30
|
+
|
|
31
|
+
### How validation works (and why it lives at the wire)
|
|
32
|
+
|
|
33
|
+
The MCP SDK validates every call with the registered schema **and hands the
|
|
34
|
+
handler the parsed value** — whatever the schema strips, the server never sees.
|
|
35
|
+
So the spec schema is registered as a full **strict** object, with every
|
|
36
|
+
optional section a **deep-strict copy of the API contract**: an unknown key
|
|
37
|
+
anywhere is rejected by the SDK with its exact path
|
|
38
|
+
(`Unrecognized key(s) in object: 'literacy' at aiAct`), enum values, date
|
|
39
|
+
formats (`YYYY-MM-DD`, real calendar dates), blank names and non-UUID ids are
|
|
40
|
+
caught with field paths, and the advertised JSON Schema
|
|
41
|
+
(`additionalProperties: false`, no `$ref` pointers) means what it says. A
|
|
42
|
+
section may also be sent as a **JSON string** (clients working from a stale
|
|
43
|
+
tool descriptor did that); it is parsed and validated identically. What a JSON
|
|
44
|
+
Schema cannot express — the 30 named ratings, the AI-Act controlled
|
|
45
|
+
vocabularies (`aiActVocabularies` in the descriptor; the app drops unknown
|
|
46
|
+
obligation keys and never shows unknown artifact keys), the score derivation —
|
|
47
|
+
is checked in the assembler, which reports **all** problems of a call at once
|
|
48
|
+
with the allowed values in the message.
|
|
49
|
+
|
|
50
|
+
Errors the SDK raises before a handler runs (`Input validation error: …`) carry
|
|
51
|
+
no `composerVersion` — that is normal. A *successful* result without it means an
|
|
52
|
+
old build is answering (see next section).
|
|
53
|
+
|
|
54
|
+
### Stale instances (reinstall is not enough — quit the app)
|
|
55
|
+
|
|
56
|
+
Claude Desktop runs an extension in **two** places: a chat-UI instance, which
|
|
57
|
+
every reinstall restarts, and a session-facing instance
|
|
58
|
+
(`LocalMcpServerManager` in Desktop's `main.log`) that serves Claude Code,
|
|
59
|
+
Cowork and remote claude.ai chats reaching the device. The session-facing
|
|
60
|
+
instance is started once at app launch and is only replaced on a **full app
|
|
61
|
+
quit** — reinstalling or disabling/enabling the extension leaves it running
|
|
62
|
+
the old code. Observed on 2026-08-18: five reinstalls, the chat-UI copy was
|
|
63
|
+
current every time, and every session still got the original build.
|
|
64
|
+
|
|
65
|
+
Tell: a successful tool result without `composerVersion`, or
|
|
66
|
+
`composer_version` missing from the tool list. Fix: install the new `.mcpb`,
|
|
67
|
+
then **quit Claude Desktop completely** (tray icon → Quit — closing the window
|
|
68
|
+
is not enough), reopen, and check with `composer_version`.
|
|
69
|
+
|
|
70
|
+
### One source for the domain
|
|
71
|
+
|
|
72
|
+
The Composer imports the app's own domain leaf, `@workspace/initiative-model`
|
|
73
|
+
(types and value lists incl. the AI-Act vocabularies, the score derivation, the
|
|
74
|
+
portfolio-mode wording overlays, the backup-format version) — the same package
|
|
75
|
+
the web app renders and validates with — and derives its enum lists from the
|
|
76
|
+
generated API contract. The only hand-listed part is the 30 sub-dimension keys
|
|
77
|
+
with the app's base wording; `catalog-drift.test.ts` pins them to the
|
|
78
|
+
contract in both directions. `server.test.ts` drives the real server through
|
|
79
|
+
the real SDK client over an in-memory transport, so what is asserted is what a
|
|
80
|
+
client sees.
|
|
81
|
+
|
|
82
|
+
## Install for users
|
|
83
|
+
|
|
84
|
+
### Claude Desktop — the extension (recommended, no Node needed)
|
|
85
|
+
|
|
86
|
+
Download **`bicon-composer.mcpb`** from the BICon app (Import/Export → *Set
|
|
87
|
+
up initiatives with an AI assistant*, or directly at
|
|
88
|
+
`https://www.bicon.digital/downloads/bicon-composer.mcpb`) and open it —
|
|
89
|
+
double-click, or Claude Desktop → Settings → Extensions → Install. Claude
|
|
90
|
+
Desktop runs the server on its own built-in Node runtime, so there is nothing
|
|
91
|
+
else to install and no configuration file to edit. Then **quit Claude Desktop
|
|
92
|
+
completely and reopen** (see *Stale instances*), start a **new chat** and ask:
|
|
93
|
+
*"Use the BICon Initiative Composer to help me set up a new initiative."*
|
|
94
|
+
|
|
95
|
+
Why the extension is primary: current Claude Desktop builds manage local MCP
|
|
96
|
+
servers as Desktop Extensions and treat `claude_desktop_config.json` as their
|
|
97
|
+
own preferences store — a hand-pasted `mcpServers` block there is silently
|
|
98
|
+
overwritten. There is no supported config-file route for Claude Desktop.
|
|
99
|
+
|
|
100
|
+
### Other MCP clients — the npm package
|
|
101
|
+
|
|
102
|
+
`@bicon/mcp-composer` on npm is a single self-contained bundle whose only
|
|
103
|
+
runtime dependency is the MCP SDK. Any MCP-capable client with Node ≥ 20 can
|
|
104
|
+
run it; for a client that reads a `mcpServers` config, add this and restart
|
|
105
|
+
the client:
|
|
41
106
|
|
|
42
107
|
```json
|
|
43
108
|
{
|
|
44
109
|
"mcpServers": {
|
|
45
110
|
"bicon-composer": {
|
|
46
111
|
"command": "npx",
|
|
47
|
-
"args": ["-y", "@bicon/mcp-composer"]
|
|
112
|
+
"args": ["-y", "@bicon/mcp-composer@latest"]
|
|
48
113
|
}
|
|
49
114
|
}
|
|
50
115
|
}
|
|
51
116
|
```
|
|
52
117
|
|
|
53
|
-
|
|
54
|
-
|
|
118
|
+
`@latest` matters: an unpinned `npx` spec keeps serving whatever it cached
|
|
119
|
+
first. Check what you got with the `composer_version` tool — the registry
|
|
120
|
+
version and the extension version are released together (see *Publishing*);
|
|
121
|
+
if npm is behind, use the extension.
|
|
122
|
+
|
|
123
|
+
**Prerequisite:** Node.js ≥ 20 on the **same operating system as the client**.
|
|
124
|
+
On Windows with Node only inside WSL, launch the server *through* WSL:
|
|
125
|
+
`"command": "wsl.exe", "args": ["-d", "Ubuntu", "--", "/path/to/npx", "-y",
|
|
126
|
+
"@bicon/mcp-composer@latest"]` (replace `/path/to/npx` with the output of
|
|
127
|
+
`which npx` in WSL). Restart the client afterwards.
|
|
55
128
|
|
|
56
129
|
## Build & run from source (contributors)
|
|
57
130
|
|
|
58
131
|
```bash
|
|
59
|
-
pnpm --filter @bicon/mcp-composer run build
|
|
60
|
-
pnpm --filter @bicon/mcp-composer run test
|
|
61
|
-
|
|
132
|
+
pnpm --filter @bicon/mcp-composer run build # → dist/index.mjs (npm bundle) + dist/mcpb/composer-<v>.mjs (extension bundle)
|
|
133
|
+
pnpm --filter @bicon/mcp-composer run test # vitest, incl. the SDK-boundary suite (builds the bundles itself)
|
|
134
|
+
pnpm --filter @bicon/mcp-composer run build:mcpb # → dist/bicon-composer.mcpb, copied to the web app's public/downloads
|
|
135
|
+
node lib/integrations/mcp/dist/index.mjs # stdio server (used by a client, not by hand)
|
|
62
136
|
```
|
|
63
137
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
```json
|
|
81
|
-
{
|
|
82
|
-
"mcpServers": {
|
|
83
|
-
"bicon-composer": {
|
|
84
|
-
"command": "wsl.exe",
|
|
85
|
-
"args": ["-d", "Ubuntu", "--", "/home/<user>/.nvm/versions/node/<version>/bin/node",
|
|
86
|
-
"/home/<user>/projects/ai-portfolio-steering/lib/integrations/mcp/dist/index.mjs"]
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
Restart Claude Desktop; the tools appear under the tools menu.
|
|
138
|
+
For a client that reads a `mcpServers` config, point it at the local build
|
|
139
|
+
with an absolute path (`"command": "node", "args": ["/ABSOLUTE/PATH/TO/lib/integrations/mcp/dist/index.mjs"]`;
|
|
140
|
+
on Windows with the repo in WSL, run through `wsl.exe` with the WSL `node`).
|
|
141
|
+
For Claude Desktop, build and install the extension instead.
|
|
142
|
+
|
|
143
|
+
`build:mcpb` stages the manifest (version, entry point and launch args written
|
|
144
|
+
from `package.json` — the checked-in `mcpb/manifest.json` carries
|
|
145
|
+
placeholders), adds the single self-contained bundle, and — before zipping —
|
|
146
|
+
boots the staged server and drives it through the protocol: `initialize`
|
|
147
|
+
(version), `tools/list` (four tools, no `$ref`), `composer_version`,
|
|
148
|
+
`resources/list`, and an `assemble_initiative` call with an unknown AI-Act key
|
|
149
|
+
that must be rejected by name. It then copies the `.mcpb` to
|
|
150
|
+
`artifacts/bicon-portfolio/public/downloads/` and writes
|
|
151
|
+
`src/lib/composer-extension.json` (version + path), which the Import/Export
|
|
152
|
+
card imports. Requires `python3` for the zip container.
|
|
93
153
|
|
|
94
154
|
## Using it (the interview → import flow)
|
|
95
155
|
|
|
96
156
|
1. Ask Claude: *"Help me set up a new initiative in BICon."* It reads
|
|
97
157
|
`initiative://schema` and interviews you — metadata first, then the 30
|
|
98
|
-
sub-dimensions with the app's own help text
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
158
|
+
sub-dimensions with the app's own help text (ask which portfolio mode you
|
|
159
|
+
work in; digital and innovation portfolios use different wording for some
|
|
160
|
+
of them), then a confidence per dimension.
|
|
161
|
+
2. Claude calls `assemble_initiative` and shows you the **derived scores** and
|
|
162
|
+
any warnings as a sanity check (fix and re-run if anything looks off).
|
|
163
|
+
3. Claude calls `export_initiative_file` with the same spec → save the returned
|
|
164
|
+
JSON under the suggested filename (`initiative-<name>-<date>.json`).
|
|
165
|
+
4. In the app (signed in to the target organisation): if the initiative carries
|
|
166
|
+
EU-AI-Act data, make sure the portfolio is in **AI mode** (the app strips
|
|
167
|
+
AI-Act fields on import when it is not — the file's `sourceMode` is
|
|
168
|
+
informational and cannot override that). Then **Import/Export → Single
|
|
169
|
+
initiative** card → drop the file → the preview should show **0 warnings**
|
|
170
|
+
→ **Add as new** → **Confirm**.
|
|
106
171
|
5. The initiative appears in the Inventory with exactly the scores Claude
|
|
107
172
|
reported.
|
|
108
173
|
|
|
109
|
-
`sourceMode` (default `ai`) must match the target portfolio's mode, otherwise the
|
|
110
|
-
importer strips the AI-Act fields.
|
|
111
|
-
|
|
112
174
|
## Publishing (maintainers)
|
|
113
175
|
|
|
114
|
-
|
|
115
|
-
devDependency the registry cannot resolve), so what ships is
|
|
116
|
-
`dist/index.mjs` + this README with `@modelcontextprotocol/sdk` as the sole
|
|
117
|
-
runtime dependency — `publish-shape.test.ts` guards exactly that. Publish under
|
|
118
|
-
the BICon npm account (business identity, 2FA on):
|
|
176
|
+
Release = extension + npm together, from one version:
|
|
119
177
|
|
|
120
178
|
```bash
|
|
121
179
|
cd lib/integrations/mcp
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
npm
|
|
180
|
+
npm version patch|minor # bumps package.json — the ONLY place the version is written
|
|
181
|
+
pnpm run test # incl. the SDK-boundary suite
|
|
182
|
+
pnpm run build:mcpb # bundles, ship-gate smoke, copies the .mcpb + version JSON into the web app
|
|
183
|
+
npm login # once, as the BICon npm account (business identity, 2FA on)
|
|
184
|
+
npm publish # prepack builds; publishConfig.access is public
|
|
126
185
|
```
|
|
127
186
|
|
|
128
|
-
Then
|
|
129
|
-
|
|
187
|
+
Then commit (the `.mcpb` and `composer-extension.json` are part of the
|
|
188
|
+
release commit) and verify from a clean machine:
|
|
189
|
+
`npx -y @bicon/mcp-composer@latest` starts and `composer_version` reports the
|
|
190
|
+
new version. The bundle inlines `zod`, `@workspace/api-zod` and
|
|
191
|
+
`@workspace/initiative-model` (workspace-only packages the registry cannot
|
|
192
|
+
resolve), so what ships is `dist/index.mjs` + this README with
|
|
193
|
+
`@modelcontextprotocol/sdk` as the sole runtime dependency —
|
|
194
|
+
`publish-shape.test.ts` guards exactly that.
|
|
130
195
|
|
|
131
196
|
## Not in scope (Phase 2)
|
|
132
197
|
|