@eventmodelers/cli 1.0.3 → 1.0.4
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/cli.js +33 -22
- package/package.json +1 -1
- package/shared/skills/connect/SKILL.md +10 -4
package/cli.js
CHANGED
|
@@ -1161,39 +1161,50 @@ function ensureMcpRegistered(projectDir, baseUrl) {
|
|
|
1161
1161
|
// process spawns `claude` (true for `run --modeling`'s own spawn). It is NOT true
|
|
1162
1162
|
// for an interactive session opened directly in the project right after
|
|
1163
1163
|
// `init`/`init-config` — that `claude` process inherits the user's shell env,
|
|
1164
|
-
// which never had a reason to already have this var set.
|
|
1165
|
-
//
|
|
1166
|
-
//
|
|
1167
|
-
//
|
|
1168
|
-
//
|
|
1169
|
-
//
|
|
1164
|
+
// which never had a reason to already have this var set.
|
|
1165
|
+
//
|
|
1166
|
+
// A plain `.env` file does NOT fix this — Claude Code never sources one; per its
|
|
1167
|
+
// own docs, an unresolved `.mcp.json` placeholder is left as the literal
|
|
1168
|
+
// `${EVENTMODELERS_TOKEN}` text, which fails auth and falls back to an OAuth
|
|
1169
|
+
// flow the eventmodelers server can't actually satisfy for this client. The
|
|
1170
|
+
// only things Claude Code itself resolves `.mcp.json` placeholders against are
|
|
1171
|
+
// the inherited shell env and its own settings files' `env` block. `.claude/
|
|
1172
|
+
// settings.local.json` is the documented per-user, gitignored-by-convention
|
|
1173
|
+
// scope for exactly this — same idea as `.eventmodelers/config.json` already
|
|
1174
|
+
// holding the raw token, just in the one file Claude Code's own process env
|
|
1175
|
+
// actually consults before expanding `.mcp.json`.
|
|
1170
1176
|
function ensureEnvToken(targetDir, token) {
|
|
1171
1177
|
if (!token) return;
|
|
1172
|
-
const
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
}
|
|
1181
|
-
|
|
1178
|
+
const claudeDir = join(targetDir, '.claude');
|
|
1179
|
+
mkdirSync(claudeDir, { recursive: true });
|
|
1180
|
+
const settingsPath = join(claudeDir, 'settings.local.json');
|
|
1181
|
+
|
|
1182
|
+
let settings = {};
|
|
1183
|
+
if (existsSync(settingsPath)) {
|
|
1184
|
+
try {
|
|
1185
|
+
settings = JSON.parse(readFileSync(settingsPath, 'utf-8'));
|
|
1186
|
+
} catch {
|
|
1187
|
+
settings = {};
|
|
1182
1188
|
}
|
|
1183
|
-
} else {
|
|
1184
|
-
writeFileSync(envPath, `${line}\n`);
|
|
1185
1189
|
}
|
|
1186
1190
|
|
|
1191
|
+
settings.env = settings.env || {};
|
|
1192
|
+
settings.env.EVENTMODELERS_TOKEN = token;
|
|
1193
|
+
writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
1194
|
+
|
|
1195
|
+
// settings.local.json is gitignored by Claude Code's own convention, but make
|
|
1196
|
+
// sure nothing here relies on that silently — it now holds a live secret.
|
|
1187
1197
|
const gitignorePath = join(targetDir, '.gitignore');
|
|
1198
|
+
const entry = '.claude/settings.local.json';
|
|
1188
1199
|
if (existsSync(gitignorePath)) {
|
|
1189
1200
|
const content = readFileSync(gitignorePath, 'utf-8');
|
|
1190
|
-
if (!content.split('\n').map((l) => l.trim()).includes(
|
|
1191
|
-
appendFileSync(gitignorePath, `${content === '' || content.endsWith('\n') ? '' : '\n'}
|
|
1201
|
+
if (!content.split('\n').map((l) => l.trim()).includes(entry)) {
|
|
1202
|
+
appendFileSync(gitignorePath, `${content === '' || content.endsWith('\n') ? '' : '\n'}${entry}\n`);
|
|
1192
1203
|
}
|
|
1193
1204
|
} else {
|
|
1194
|
-
writeFileSync(gitignorePath,
|
|
1205
|
+
writeFileSync(gitignorePath, `${entry}\n`);
|
|
1195
1206
|
}
|
|
1196
|
-
console.log(' ✓ Wrote EVENTMODELERS_TOKEN to .
|
|
1207
|
+
console.log(' ✓ Wrote EVENTMODELERS_TOKEN to .claude/settings.local.json (gitignored)');
|
|
1197
1208
|
}
|
|
1198
1209
|
|
|
1199
1210
|
// `run --modeling`: modeling-kit's one and only runtime mode — there is no
|
package/package.json
CHANGED
|
@@ -150,7 +150,7 @@ Always run this step (not only when Step 3 ran) — it's idempotent and safe to
|
|
|
150
150
|
|
|
151
151
|
The eventmodelers backend exposes the same board capabilities as an MCP server at `<BASE_URL>/mcp`, authenticated with the same `TOKEN` via an `x-token` header. Register it in the project's `.mcp.json` so Claude Code (or any other MCP-aware host) can connect and expose tools as `mcp__eventmodelers__<tool_name>`.
|
|
152
152
|
|
|
153
|
-
**Do not put the raw token in `.mcp.json`** — that file is typically committed to share server config with the team. Instead reference an environment variable and
|
|
153
|
+
**Do not put the raw token in `.mcp.json`** — that file is typically committed to share server config with the team. Instead reference an environment variable and set the actual secret in `.claude/settings.local.json`'s `env` block:
|
|
154
154
|
|
|
155
155
|
1. Read the existing `.mcp.json` at the project root if present (it may already list other MCP servers, e.g. a browser-automation server used by `discover-storyboard` — merge into `mcpServers`, never replace the whole file). If absent, start from `{"mcpServers": {}}`.
|
|
156
156
|
2. Add or update the `eventmodelers` entry:
|
|
@@ -165,8 +165,14 @@ The eventmodelers backend exposes the same board capabilities as an MCP server a
|
|
|
165
165
|
}
|
|
166
166
|
}
|
|
167
167
|
```
|
|
168
|
-
3.
|
|
169
|
-
|
|
168
|
+
3. Read the existing `.claude/settings.local.json` if present and merge in — never clobber `permissions`/`enabledMcpjsonServers` or anything else already there. Ensure it has `EVENTMODELERS_TOKEN` set under `env` (create the file with just this key if it doesn't exist yet):
|
|
169
|
+
```json
|
|
170
|
+
{
|
|
171
|
+
"env": { "EVENTMODELERS_TOKEN": "<TOKEN>" }
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
A plain `.env` file does **not** work here — Claude Code never sources one, so a `${EVENTMODELERS_TOKEN}` placeholder in `.mcp.json` would be left unexpanded (sent as the literal `${EVENTMODELERS_TOKEN}` text), which fails auth and pushes the client into an OAuth flow the eventmodelers server can't satisfy for this client. `.claude/settings.local.json`'s `env` block — alongside the inherited shell environment — is the only thing Claude Code actually resolves `.mcp.json` placeholders against.
|
|
175
|
+
4. Ensure `.claude/settings.local.json` is listed in `.gitignore` (same check-then-append pattern as Step 3 uses for `.eventmodelers/config.json`) — it now holds the same secret and must never be committed. (Gitignored by Claude Code's own convention already, but don't rely on that silently.)
|
|
170
176
|
|
|
171
177
|
MCP tools only become visible to the current agent session after the host (re)connects to the server — a brand-new `.mcp.json` entry written mid-session may need the user to approve the new server or reconnect (e.g. Claude Code's `/mcp` command) before `mcp__eventmodelers__*` tools appear in the tool list. That's expected and not an error: tell the user once, then let every other skill fall back to curl automatically until the tools show up.
|
|
172
178
|
|
|
@@ -226,7 +232,7 @@ The `token` field is a secret. It is never logged or shown after initial confirm
|
|
|
226
232
|
|
|
227
233
|
## Security notes
|
|
228
234
|
|
|
229
|
-
- The config file (`.eventmodelers/config.json`) and
|
|
235
|
+
- The config file (`.eventmodelers/config.json`) and `.claude/settings.local.json` (holding `EVENTMODELERS_TOKEN` under `env`) are both workspace-local and gitignored — never commit either.
|
|
230
236
|
- `.mcp.json` itself is safe to commit — it only ever contains the `${EVENTMODELERS_TOKEN}` placeholder, never the literal token.
|
|
231
237
|
- The token grants write access to all boards in its organization — treat it like a password.
|
|
232
238
|
- If a skill receives a `401`/`403` (curl) or an access-denied tool error (MCP) mid-session, re-invoke this skill to refresh the config before retrying.
|