testchimp-mcp-client 0.0.1 → 0.0.3
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 +22 -2
- package/dist/index.js +95 -15
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -13,11 +13,28 @@ MCP (Model Context Protocol) server for [TestChimp](https://testchimp.io). Expos
|
|
|
13
13
|
|
|
14
14
|
- **`get_requirement_coverage`** — POST `/api/mcp/list_requirement_coverage` (scenario / requirement coverage scoped by platform-rooted `scope.folderPath` under **`tests/...`** or **`plans/...`**).
|
|
15
15
|
- **`get_execution_history`** — POST `/api/mcp/list_execution_history`.
|
|
16
|
-
- **`
|
|
16
|
+
- **`create_user_story`** — POST `/api/mcp/create_user_story` (`platformFilePath` under `plans/stories/...`, `title`).
|
|
17
|
+
- **`create_test_scenario`** — POST `/api/mcp/create_test_scenario` (`platformFilePath` under `plans/scenarios/...`, `title`, `userStoryOrdinalId`).
|
|
18
|
+
- **`update_user_story`** — POST `/api/mcp/update_user_story` (full markdown `content` with `id: US-...` in frontmatter).
|
|
19
|
+
- **`update_test_scenario`** — POST `/api/mcp/update_test_scenario` (full markdown `content` with `id: TS-...` and `story: US-...` in frontmatter).
|
|
20
|
+
- **`get_eaas_config`** — POST `/api/mcp/get_eaas_config` (BunnyShell YAML path and project name; token excluded; `{}` when unconfigured).
|
|
21
|
+
- **`provision_ephemeral_environment`** — POST `/api/mcp/provision_ephemeral_environment` (optional `branchName`).
|
|
22
|
+
- **`get_ephemeral_environment_status`** — POST `/api/mcp/get_ephemeral_environment_status` (`bnsEnvironmentId`).
|
|
23
|
+
- **`destroy_ephemeral_environment`** — POST `/api/mcp/destroy_ephemeral_environment` (`bnsEnvironmentId`).
|
|
17
24
|
|
|
18
25
|
## Cursor
|
|
19
26
|
|
|
20
|
-
|
|
27
|
+
**Install only at project level.** TestChimp API keys are **scoped to a TestChimp project**; the MCP server must use the key for **the repo you have open**. Do **not** add this server to **IDE-wide** MCP config (`~/.cursor/mcp.json` or global Cursor MCP settings): you risk using the wrong key when switching workspaces, and agents may target the wrong backend project.
|
|
28
|
+
|
|
29
|
+
**For humans and AI agents:** create or edit **`<project-root>/.cursor/mcp.json`** in the repository you are working in (the folder Cursor has open as the workspace root). That path is **`.cursor/mcp.json` relative to the project root**, not under your home directory.
|
|
30
|
+
|
|
31
|
+
The MCP server reads **`TESTCHIMP_API_KEY`** and **`TESTCHIMP_BACKEND_URL`** from **`process.env`** — it does not read `mcp.json` directly. Cursor starts the server as a **child process**; variables must be present in **that** process’s environment.
|
|
32
|
+
|
|
33
|
+
**Why `mcp.json` uses an `env` block:** If you open Cursor from the Dock, Spotlight, or similar, it usually does **not** load your shell profile (`.zshrc`, etc.), so values you only `export` in a terminal may **not** reach the MCP server. The `env` object next to `command` / `args` is the reliable way Cursor injects variables into the MCP process. (Cursor’s `mcp.json` does **not** expand `$VAR` / `${VAR}` from your shell; use literal values in `env`, or a wrapper that loads a `.env` file before starting the server.)
|
|
34
|
+
|
|
35
|
+
### Project `mcp.json` example
|
|
36
|
+
|
|
37
|
+
`<project-root>/.cursor/mcp.json`:
|
|
21
38
|
|
|
22
39
|
```json
|
|
23
40
|
{
|
|
@@ -34,6 +51,9 @@ Add to MCP config (e.g. `~/.cursor/mcp.json`):
|
|
|
34
51
|
}
|
|
35
52
|
```
|
|
36
53
|
|
|
54
|
+
- **Do not commit secrets:** Add `.cursor/mcp.json` to **`.gitignore`** if it contains real keys, or keep only a committed `.cursor/mcp.json.example` with placeholders and document that each developer maintains a local ignored file.
|
|
55
|
+
- **After changing env or config:** Restart the MCP server or reload MCP / restart Cursor so the new environment is picked up.
|
|
56
|
+
|
|
37
57
|
For a published npm package name, adjust `args` to your scope (e.g. `@testchimp/mcp-client`) after publish.
|
|
38
58
|
|
|
39
59
|
## Scope path format
|
package/dist/index.js
CHANGED
|
@@ -16,7 +16,7 @@ function getBackendUrl() {
|
|
|
16
16
|
function requireApiKey() {
|
|
17
17
|
const k = process.env.TESTCHIMP_API_KEY?.trim();
|
|
18
18
|
if (!k) {
|
|
19
|
-
throw new Error("TESTCHIMP_API_KEY is required. Set it in
|
|
19
|
+
throw new Error("TESTCHIMP_API_KEY is required. Set it in <project>/.cursor/mcp.json env (project-level MCP config), not IDE-wide config.");
|
|
20
20
|
}
|
|
21
21
|
return k;
|
|
22
22
|
}
|
|
@@ -59,11 +59,29 @@ const listExecutionInput = z.object({
|
|
|
59
59
|
scope: scopeSchema,
|
|
60
60
|
branchName: z.string().optional(),
|
|
61
61
|
});
|
|
62
|
-
|
|
62
|
+
/** Platform path to the new markdown file, e.g. plans/stories/auth/login-flow.md */
|
|
63
|
+
const createUserStoryInput = z.object({
|
|
64
|
+
platformFilePath: z.string().min(1),
|
|
65
|
+
title: z.string().min(1),
|
|
66
|
+
});
|
|
67
|
+
const createTestScenarioInput = z.object({
|
|
68
|
+
platformFilePath: z.string().min(1),
|
|
69
|
+
title: z.string().min(1),
|
|
70
|
+
/** Parent story ordinal (the number n in US-n). */
|
|
71
|
+
userStoryOrdinalId: z.coerce.number().int().positive(),
|
|
72
|
+
});
|
|
73
|
+
const updatePlanMarkdownInput = z.object({
|
|
74
|
+
/** Full markdown including YAML frontmatter and body (as written under the repo plans root). */
|
|
75
|
+
content: z.string().min(1),
|
|
76
|
+
});
|
|
77
|
+
const emptyInput = z.object({});
|
|
78
|
+
const provisionEphemeralInput = z.object({
|
|
79
|
+
/** Git branch to deploy; omit to use the repo default branch. */
|
|
63
80
|
branchName: z.string().optional(),
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
81
|
+
});
|
|
82
|
+
const bnsEnvironmentIdInput = z.object({
|
|
83
|
+
/** BunnyShell environment id returned from provision_ephemeral_environment. */
|
|
84
|
+
bnsEnvironmentId: z.string().min(1),
|
|
67
85
|
});
|
|
68
86
|
function textResult(json) {
|
|
69
87
|
return {
|
|
@@ -133,21 +151,83 @@ async function main() {
|
|
|
133
151
|
const json = await postMcp("/api/mcp/list_execution_history", body);
|
|
134
152
|
return textResult(json);
|
|
135
153
|
});
|
|
136
|
-
server.registerTool("
|
|
137
|
-
description: "
|
|
138
|
-
|
|
154
|
+
server.registerTool("create_user_story", {
|
|
155
|
+
description: "Create a user story on the TestChimp project and its plan file stub. " +
|
|
156
|
+
"Always call this before writing a new story markdown file; use the returned ordinalId as US-<ordinalId> in frontmatter. " +
|
|
157
|
+
"platformFilePath must be under plans/stories/ and end with .md.",
|
|
158
|
+
inputSchema: createUserStoryInput,
|
|
159
|
+
}, async (args) => {
|
|
160
|
+
const json = await postMcp("/api/mcp/create_user_story", {
|
|
161
|
+
platformFilePath: args.platformFilePath,
|
|
162
|
+
title: args.title,
|
|
163
|
+
});
|
|
164
|
+
return textResult(json);
|
|
165
|
+
});
|
|
166
|
+
server.registerTool("create_test_scenario", {
|
|
167
|
+
description: "Create a test scenario linked to a user story. Call after the parent story exists. " +
|
|
168
|
+
"platformFilePath must be under plans/scenarios/ and end with .md. " +
|
|
169
|
+
"userStoryOrdinalId is the numeric part of the parent US-<n> id.",
|
|
170
|
+
inputSchema: createTestScenarioInput,
|
|
171
|
+
}, async (args) => {
|
|
172
|
+
const json = await postMcp("/api/mcp/create_test_scenario", {
|
|
173
|
+
platformFilePath: args.platformFilePath,
|
|
174
|
+
title: args.title,
|
|
175
|
+
userStoryOrdinalId: args.userStoryOrdinalId,
|
|
176
|
+
});
|
|
177
|
+
return textResult(json);
|
|
178
|
+
});
|
|
179
|
+
server.registerTool("update_user_story", {
|
|
180
|
+
description: "Sync a user story markdown file to the platform after local edits. " +
|
|
181
|
+
"Parses frontmatter (id: US-..., title, priority, status) and updates the linked support file and entity.",
|
|
182
|
+
inputSchema: updatePlanMarkdownInput,
|
|
183
|
+
}, async (args) => {
|
|
184
|
+
const json = await postMcp("/api/mcp/update_user_story", { content: args.content });
|
|
185
|
+
return textResult(json);
|
|
186
|
+
});
|
|
187
|
+
server.registerTool("update_test_scenario", {
|
|
188
|
+
description: "Sync a test scenario markdown file to the platform after local edits. " +
|
|
189
|
+
"Parses frontmatter (id: TS-..., story: US-..., title, priority, status) and updates linking if story changes.",
|
|
190
|
+
inputSchema: updatePlanMarkdownInput,
|
|
191
|
+
}, async (args) => {
|
|
192
|
+
const json = await postMcp("/api/mcp/update_test_scenario", { content: args.content });
|
|
193
|
+
return textResult(json);
|
|
194
|
+
});
|
|
195
|
+
server.registerTool("get_eaas_config", {
|
|
196
|
+
description: "Return the project's BunnyShell (Environment-as-a-Service) settings: ymlRepoPath and bunnyshellProjectName. " +
|
|
197
|
+
"Secrets (API token) are never returned. Response is {} when EaaS is not configured or has no public fields.",
|
|
198
|
+
inputSchema: emptyInput,
|
|
199
|
+
}, async () => {
|
|
200
|
+
const json = await postMcp("/api/mcp/get_eaas_config", {});
|
|
201
|
+
return textResult(json);
|
|
202
|
+
});
|
|
203
|
+
server.registerTool("provision_ephemeral_environment", {
|
|
204
|
+
description: "Create a BunnyShell ephemeral environment for the TestChimp project from the configured Git repo + YAML path. " +
|
|
205
|
+
"Requires BunnyShell + GitHub integration in project settings. Poll with get_ephemeral_environment_status using bnsEnvironmentId.",
|
|
206
|
+
inputSchema: provisionEphemeralInput,
|
|
139
207
|
}, async (args) => {
|
|
140
208
|
const body = {};
|
|
141
209
|
if (args.branchName != null && args.branchName.trim() !== "") {
|
|
142
210
|
body.branchName = args.branchName.trim();
|
|
143
211
|
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
212
|
+
const json = await postMcp("/api/mcp/provision_ephemeral_environment", body);
|
|
213
|
+
return textResult(json);
|
|
214
|
+
});
|
|
215
|
+
server.registerTool("get_ephemeral_environment_status", {
|
|
216
|
+
description: "Poll BunnyShell for environment status and definition. When deployed, environmentSpec may contain URLs/components JSON.",
|
|
217
|
+
inputSchema: bnsEnvironmentIdInput,
|
|
218
|
+
}, async (args) => {
|
|
219
|
+
const json = await postMcp("/api/mcp/get_ephemeral_environment_status", {
|
|
220
|
+
bnsEnvironmentId: args.bnsEnvironmentId,
|
|
221
|
+
});
|
|
222
|
+
return textResult(json);
|
|
223
|
+
});
|
|
224
|
+
server.registerTool("destroy_ephemeral_environment", {
|
|
225
|
+
description: "Delete a BunnyShell environment created for this project (bnsEnvironmentId from provision).",
|
|
226
|
+
inputSchema: bnsEnvironmentIdInput,
|
|
227
|
+
}, async (args) => {
|
|
228
|
+
const json = await postMcp("/api/mcp/destroy_ephemeral_environment", {
|
|
229
|
+
bnsEnvironmentId: args.bnsEnvironmentId,
|
|
230
|
+
});
|
|
151
231
|
return textResult(json);
|
|
152
232
|
});
|
|
153
233
|
const transport = new StdioServerTransport();
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "testchimp-mcp-client",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "MCP server for TestChimp —
|
|
3
|
+
"version": "0.0.3",
|
|
4
|
+
"description": "MCP server for TestChimp — coverage, execution history, and plan authoring",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|