@kindgi/sdk 0.0.0-bootstrap.0 → 0.1.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.
Files changed (51) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +187 -1
  3. package/dist/build.d.ts +10 -0
  4. package/dist/build.d.ts.map +1 -0
  5. package/dist/build.js +11 -0
  6. package/dist/build.js.map +1 -0
  7. package/dist/client.d.ts +33 -0
  8. package/dist/client.d.ts.map +1 -0
  9. package/dist/client.js +55 -0
  10. package/dist/client.js.map +1 -0
  11. package/dist/define.d.ts +25 -0
  12. package/dist/define.d.ts.map +1 -0
  13. package/dist/define.js +37 -0
  14. package/dist/define.js.map +1 -0
  15. package/dist/index.d.ts +17 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +19 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/runtime-config.d.ts +53 -0
  20. package/dist/runtime-config.d.ts.map +1 -0
  21. package/dist/runtime-config.js +114 -0
  22. package/dist/runtime-config.js.map +1 -0
  23. package/dist/types.d.ts +16 -0
  24. package/dist/types.d.ts.map +1 -0
  25. package/dist/types.js +4 -0
  26. package/dist/types.js.map +1 -0
  27. package/dist/webhooks.d.ts +15 -0
  28. package/dist/webhooks.d.ts.map +1 -0
  29. package/dist/webhooks.js +16 -0
  30. package/dist/webhooks.js.map +1 -0
  31. package/package.json +88 -4
  32. package/skills/kindgi-authoring-agents/SKILL.md +252 -0
  33. package/skills/kindgi-authoring-flows/SKILL.md +302 -0
  34. package/skills/kindgi-authoring-guardrails/SKILL.md +297 -0
  35. package/skills/kindgi-authoring-mcp-servers/SKILL.md +289 -0
  36. package/skills/kindgi-authoring-providers/SKILL.md +705 -0
  37. package/skills/kindgi-authoring-tools/SKILL.md +298 -0
  38. package/skills/kindgi-framework-feedback/SKILL.md +211 -0
  39. package/skills/kindgi-getting-started/SKILL.md +189 -0
  40. package/skills/kindgi-python-authoring-agents/SKILL.md +205 -0
  41. package/skills/kindgi-python-authoring-flows/SKILL.md +325 -0
  42. package/skills/kindgi-python-authoring-guardrails/SKILL.md +176 -0
  43. package/skills/kindgi-python-authoring-tools/SKILL.md +305 -0
  44. package/skills/kindgi-python-getting-started/SKILL.md +242 -0
  45. package/src/build.ts +18 -0
  46. package/src/client.ts +177 -0
  47. package/src/define.ts +75 -0
  48. package/src/index.ts +20 -0
  49. package/src/runtime-config.ts +180 -0
  50. package/src/types.ts +86 -0
  51. package/src/webhooks.ts +34 -0
@@ -0,0 +1,289 @@
1
+ ---
2
+ name: kindgi-authoring-mcp-servers
3
+ description: >
4
+ Wire an MCP server into a Kindgi pack so the coding agent (Claude Code,
5
+ Cursor, VS Code, Windsurf, …) can discover a live external resource
6
+ through tools instead of asking the user to paste schemas or values.
7
+ Uses `kindgi secrets set` for the credential (interactive, no-echo) and
8
+ `kindgi mcp add <preset>` to write `.mcp.json` at the pack root. The
9
+ launcher (`kindgi mcp-launch`) spawns the actual MCP server as a
10
+ subprocess with the secret injected into its env — never onto the
11
+ model's transcript. Load this when the user says "I have a Postgres
12
+ URL, can you look at the schema", "connect to my database", "wire
13
+ MCP", "add a Postgres MCP", "let CC query my DB", "I don't want to
14
+ paste my table shape", or when the model is about to ask the user to
15
+ paste external schema/data that Kindgi could discover through MCP.
16
+ Credential storage is covered by kindgi-authoring-providers's
17
+ `kindgi secrets set` flow.
18
+ type: core
19
+ library: "@kindgi/sdk"
20
+ version: "0.3.0"
21
+ sdk_version: "0.0.0"
22
+ pack_languages: [node, python]
23
+ ---
24
+
25
+ # Wiring an MCP server for a Kindgi pack
26
+
27
+ > **Running `kindgi`:** in a Node project the CLI is a devDependency
28
+ > (`@kindgi/cli`), not a global command. Run it through the project's
29
+ > package manager — `pnpm exec kindgi …`, `npx --no kindgi …` (npm),
30
+ > `yarn kindgi …` or `bun run kindgi …`. A Python pack (`[tool.kindgi]` in
31
+ > `pyproject.toml`) has no Node project: run the `kindgi` on `PATH`.
32
+ > Commands below are written `kindgi …` for brevity.
33
+
34
+ If the user has an external resource (Postgres DB, GitHub org, Notion
35
+ workspace, …) that would be useful to a coding agent, **wire an MCP
36
+ server** rather than asking the user to paste values. Kindgi keeps the
37
+ credential out of the model's transcript by injecting it into the
38
+ subprocess's environment; the model only sees the tools the MCP server
39
+ exposes.
40
+
41
+ ## When to reach for this
42
+
43
+ Reach for MCP when the user hands you a live external resource by
44
+ reference (URL, host + credential, workspace id). Signals from the
45
+ user:
46
+ - "I have a Postgres database at $URL"
47
+ - "Connect to my Notion workspace at $TOKEN"
48
+ - "Let CC look at the schema of my DB"
49
+ - "Don't paste it, just query it"
50
+
51
+ **Do NOT reach for MCP when:**
52
+ - The resource is a static file the user has locally (just Read it).
53
+ - The resource is best-inspected once by a human (a one-shot answer, no
54
+ agent tools needed).
55
+ - The user is in a client that hasn't loaded `.mcp.json` yet — they'll
56
+ need to restart their MCP client after `kindgi mcp add` (see gotcha
57
+ #2 below).
58
+
59
+ ## Mental model
60
+
61
+ ```
62
+ Kindgi's SecretBinding .mcp.json (pack root) launcher subprocess MCP server subprocess
63
+ ───────────────────── ──────────────────── ────────────────── ────────────────────
64
+ MY_DB_URL=… → { "command": "pnpm", → reads .env + → spawns child with
65
+ (.env / .env.local, or "args": ["exec","kindgi", .env.local (the DATABASE_URI in env,
66
+ `kindgi secrets set`) "mcp-launch", "--", …] } pack env files), stdio piped to CC
67
+ │ substitutes secret ▲ │
68
+ │ into child env │ ▼
69
+ ▼ │ MCP protocol (stdio)
70
+ Claude Code / Cursor spawns │ ▲ │
71
+ `kindgi mcp-launch …` at │ │ ▼
72
+ startup ─────────────────────────────┘ ┌─────────────────┐
73
+ │ Claude Code │
74
+ │ (or Cursor…) │
75
+ └─────────────────┘
76
+ ```
77
+
78
+ Three moving parts:
79
+
80
+ 1. **The secret on disk** — for `local`, the project's env files at the
81
+ pack root (`.env`, then `.env.local`; `dev.envFiles` to change);
82
+ other environments use `.env.<envName>`. Add it by hand or with
83
+ `kindgi secrets set` (interactive no-echo prompt; never the value on
84
+ argv), which writes `.env.local`. See `kindgi-authoring-providers`
85
+ for the same flow used for LLM API keys.
86
+ 2. **`.mcp.json` at the pack root** — Kindgi writes this via
87
+ `kindgi mcp add`. Every entry runs the project's own `kindgi
88
+ mcp-launch -- <launcher-flags>...` through its package manager
89
+ (`"command": "pnpm", "args": ["exec", "kindgi", "mcp-launch", …]`;
90
+ npm: `npx --no kindgi …`) — never a global `kindgi`, never a
91
+ download. A Python pack has no Node project, so its entries run the
92
+ `kindgi` on `PATH` (`"command": "kindgi", "args": ["mcp-launch", …]`).
93
+ The file is safe to commit — it references secrets by NAME, not
94
+ value.
95
+ 3. **The launcher** — `kindgi mcp-launch` is what the coding agent
96
+ actually spawns. It reads the referenced secret from the pack env files,
97
+ injects it into the child MCP server's env, and pipes stdio through.
98
+
99
+ ## Path A — Postgres
100
+
101
+ Best-worn path. Uses `crystaldba/postgres-mcp` via Docker with
102
+ read-only access mode by default.
103
+
104
+ **Step 1 — set the DB URL** (interactive, no-echo):
105
+
106
+ ```sh
107
+ kindgi secrets set MY_DB_URL --env=local --scope=tenant
108
+ # paste postgres://user:pass@host:port/db, press enter
109
+ ```
110
+
111
+ For pipelines/CI: `pbpaste | kindgi secrets set … --from-stdin`, or
112
+ `--from-file=<path>` on a mode-0600 file. Never pass the value on argv.
113
+
114
+ **Step 2 — wire the MCP server:**
115
+
116
+ ```sh
117
+ kindgi mcp add postgres --secret=MY_DB_URL
118
+ ```
119
+
120
+ Writes `.mcp.json` at the pack root (or merges into an existing one).
121
+ The server name defaults to `my_db` (derived from the secret
122
+ name — see "Server naming" below). Override with `--server-name=<label>`.
123
+
124
+ **Step 3 — restart your MCP client.** MCP servers are loaded at client
125
+ startup — a fresh `.mcp.json` doesn't take effect mid-session:
126
+ - **Claude Code:** exit + `claude` again in the same pack dir
127
+ - **Cursor:** ⌘⇧P → "Restart Extension Host" (or restart the app)
128
+ - **Claude Desktop:** quit + reopen
129
+ - **Windsurf:** Command Palette → "Restart Windsurf"
130
+
131
+ **Step 4 — use it.** Tools like `execute_sql`, `list_tables`,
132
+ `analyze_index_health` now appear. Ask the agent things like "what
133
+ tables are in this schema?" or "what's the shape of the customers
134
+ table?" or "how many rows are in orders where created_at > 2024?".
135
+
136
+ ## Path B — Multiple servers in the same pack
137
+
138
+ Two connections against different DBs? Two `mcp add` invocations,
139
+ each with its own `--secret` and `--server-name`:
140
+
141
+ ```sh
142
+ kindgi secrets set MY_DB_URL --env=local --scope=tenant
143
+ kindgi secrets set ANALYTICS_DB_URL --env=local --scope=tenant
144
+
145
+ kindgi mcp add postgres --secret=MY_DB_URL --server-name=my_db
146
+ kindgi mcp add postgres --secret=ANALYTICS_DB_URL --server-name=analytics_db
147
+ ```
148
+
149
+ `.mcp.json` gets two entries. The agent picks the right one by name
150
+ when it invokes a tool (e.g. `my_db.execute_sql`).
151
+
152
+ ## Server naming
153
+
154
+ `--server-name` defaults are derived from the secret name:
155
+
156
+ | Secret name | Default server name |
157
+ |---|---|
158
+ | `MY_DB_URL` | `my_db` |
159
+ | `ANALYTICS_DB_URL` | `analytics_db` |
160
+ | `ANTHROPIC_API_KEY` | `anthropic_api` |
161
+ | `GITHUB_PAT` | `github` |
162
+ | `DB_PASSWORD` | `db` |
163
+
164
+ The suffix-stripping (`_url` / `_uri` / `_key` / `_token` / `_pat` /
165
+ `_secret` / `_password`) is intentional — the server name should
166
+ describe the *resource*, not the *credential shape*. Override with
167
+ `--server-name=<label>` when the default reads wrong.
168
+
169
+ ## Path C — Non-Claude-Code clients
170
+
171
+ `.mcp.json` at the pack root is what Claude Code reads natively. Other
172
+ clients read from their own paths (`.cursor/mcp.json`, `.vscode/mcp.json`,
173
+ Claude Desktop's system-wide config). To bridge:
174
+
175
+ 1. Establish a symlink from the client's expected path to `.mcp.json`:
176
+ ```sh
177
+ mkdir -p .cursor && ln -sfn ../.mcp.json .cursor/mcp.json
178
+ ```
179
+ 2. Restart the client.
180
+
181
+ Symlinks work because the FILE CONTENTS are portable across every MCP
182
+ client — the `mcpServers` block has the same shape everywhere. Only
183
+ the file LOCATION differs. Edits to `.mcp.json` flow through
184
+ automatically via the symlink; no re-sync needed.
185
+
186
+ Windows users without dev-drive symlinks: `cp .mcp.json .cursor/mcp.json`,
187
+ and re-copy after every `kindgi mcp` edit.
188
+
189
+ ## Verifying end-to-end
190
+
191
+ ```sh
192
+ # 1. Check the secret exists
193
+ kindgi secrets list --env=local --scope=tenant
194
+
195
+ # 2. Check .mcp.json
196
+ kindgi mcp list
197
+
198
+ # 3. Check available presets
199
+ kindgi mcp presets
200
+ ```
201
+
202
+ `kindgi mcp list` prints the configured servers with their launcher
203
+ argv shape. `kindgi mcp presets` shows what presets are available and
204
+ their audit status. If the postgres preset audit says
205
+ `urlLeakInErrors: "pending"`, that's a known unresolved item — see
206
+ gotcha #4.
207
+
208
+ ## Common mistakes
209
+
210
+ 1. **Reading `.mcp.json` mid-session and asking about it.** `.mcp.json`
211
+ references secrets by NAME (e.g. `secret:MY_DB_URL@local:tenant`),
212
+ not by value. Safe to Read + describe to the user. **Do NOT** run
213
+ `cat .env`, `env | grep`, or Read `.env` / `.env.local` — those return
214
+ the raw URL, which enters your transcript, gets sent to the model
215
+ provider on every subsequent turn, and can be exfiltrated via
216
+ prompt injection. Once a secret is in a model's context, it's a
217
+ rotation event, not a "clean up the log" event.
218
+
219
+ 2. **Expecting the new server to activate without a restart.** MCP
220
+ servers are loaded at client startup. `kindgi mcp add` writes the
221
+ config file; the CLIENT doesn't re-scan it until a restart. Tell
222
+ the user to restart their client after `mcp add`, and don't call
223
+ MCP tools before that restart happens in your current session.
224
+
225
+ 3. **`--env` / `--scope` mismatch between `secrets set` and `mcp add`.**
226
+ Both flags need to agree — the launcher looks up the secret using
227
+ whatever `--env` + `--scope` you passed to `mcp add`. Default is
228
+ `--env=local --scope=tenant`; match this on both commands.
229
+
230
+ 4. **Trusting a preset's audit metadata that says `pending`.** Every
231
+ preset carries `audit.urlLeakInErrors`. Only `"verified-safe"` means
232
+ someone has confirmed the wrapped MCP server doesn't echo the
233
+ secret in its error/debug output. `"pending"` means the audit
234
+ hasn't run — the server may or may not leak. When you see a
235
+ `pending` preset in a session that handles real credentials, tell
236
+ the user: "this preset works but its URL-echo safety isn't
237
+ verified for this version; watch tool error messages for the raw
238
+ URL, and file feedback if you see one."
239
+
240
+ 5. **Trying to use MCP against a `localhost` DB from Docker on Mac
241
+ without the host-remap.** Docker containers on Mac can't reach the
242
+ host's `localhost`. The `postgres` preset carries `hostRemap:
243
+ "docker-desktop"`, which the launcher applies automatically — it
244
+ rewrites `@localhost` / `@127.0.0.1` in the resolved URL to
245
+ `@host.docker.internal` before injecting into the container's env.
246
+ If you author a preset with a Docker runtime + a localhost
247
+ consumer, include `"hostRemap": "docker-desktop"` in the preset JSON.
248
+
249
+ 6. **`kindgi mcp add` fails with "Secret X not in .env, .env.local".** The
250
+ secret hasn't been stored yet. Run `kindgi secrets set X --env=local
251
+ --scope=tenant` first. The error message includes this fix pointer.
252
+
253
+ ## Security discipline
254
+
255
+ The invariants this skill inherits — every bullet here is enforced by
256
+ you, the coding agent, in the session where MCP is wired:
257
+
258
+ - **Never Read `.env`, `.env.local` or `.env.<envName>` files.** Their contents are the raw
259
+ secret values. Reading them puts the secret in your tool result and
260
+ from there in every subsequent turn's context sent to the model
261
+ provider.
262
+ - **Never run `env | grep SECRET_NAME`, `printenv SECRET_NAME`, or
263
+ equivalent** in a bash tool. Same failure — the value returns in the
264
+ tool result.
265
+ - **When a tool errors, check the error message before summarizing.**
266
+ Some MCP servers echo the connection string in `connection refused`
267
+ errors. If you see the URL in a tool error, redact when
268
+ summarizing to the user, and file the incident via the
269
+ `kindgi-framework-feedback` skill so the preset's audit gets updated.
270
+ - **Prefer `kindgi mcp list` over Reading `.mcp.json`** when the user
271
+ asks "what's configured?" — the list output has the same info in a
272
+ cleaner shape and is safe to include in your reply.
273
+ - **Never repeat the resolved URL back to the user** — even in a
274
+ "here's what I wired up" summary. Refer to the secret by NAME and
275
+ to the server by its `.mcp.json` label. The point of MCP is that
276
+ the value stays out of every layer that a model can see; repeating
277
+ it in your reply defeats the invariant.
278
+
279
+ ## When the framework itself is the problem
280
+
281
+ If you diagnose that the bug lives in Kindgi/`@kindgi/cli` itself
282
+ (`kindgi mcp add` writes malformed JSON, `mcp-launch` hangs, a preset
283
+ has bad `defaultArgs`, launcher can't resolve a secret that clearly
284
+ exists in the pack env files, an MCP server echoes the URL in its
285
+ error tool result) — not in your pack's `.mcp.json` or secret setup —
286
+ load the `kindgi-framework-feedback` skill and file a structured
287
+ report with `kindgi feedback write`. That diagnostic is high-signal
288
+ input the maintainers can act on; don't let it disappear into the
289
+ transcript.