@mhdd_24/api-scenario-mcp 1.0.0
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/LICENSE +15 -0
- package/README.md +103 -0
- package/dist/config/api-scenario.config.js +31 -0
- package/dist/env.js +17 -0
- package/dist/index.js +21 -0
- package/dist/services/api-scenarioService.js +53 -0
- package/dist/tools/generateTool.js +19 -0
- package/dist/tools/index.js +8 -0
- package/dist/tools/statusTool.js +15 -0
- package/dist/tools/toHttpTool.js +18 -0
- package/dist/utils/toolResponse.js +7 -0
- package/docs/WIKI.md +25 -0
- package/package.json +53 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
ISC License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 mhdd_24
|
|
4
|
+
|
|
5
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
+
purpose with or without fee is hereby granted, provided that the above
|
|
7
|
+
copyright notice and this permission notice appear in all copies.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
10
|
+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
11
|
+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
12
|
+
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
13
|
+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
14
|
+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
15
|
+
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# @mhdd_24/api-scenario-mcp
|
|
2
|
+
|
|
3
|
+
Generate complete multi-step API workflows.
|
|
4
|
+
|
|
5
|
+
Same architecture as [@mhdd_24/sublime-mcp](https://github.com/Mhdd-24/Sublime-MCP).
|
|
6
|
+
|
|
7
|
+
**Full documentation:** [docs/WIKI.md](./docs/WIKI.md)
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## How it works (30 seconds)
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
You (chat) → MCP client → api-scenario-mcp → API Scenario APIs / CLIs / local tools
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Prerequisites
|
|
20
|
+
|
|
21
|
+
| Requirement | Notes |
|
|
22
|
+
|-------------|--------|
|
|
23
|
+
| **Node.js 18+** | ESM TypeScript MCP server |
|
|
24
|
+
| **Credentials / CLIs** | See environment variables below |
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Install
|
|
29
|
+
|
|
30
|
+
### Option A — npm (after publish)
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install -g @mhdd_24/api-scenario-mcp
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Option B — npx
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npx @mhdd_24/api-scenario-mcp
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Option C — clone and build
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
git clone https://github.com/Mhdd-24/API-Scenario-MCP.git
|
|
46
|
+
cd API-Scenario-MCP
|
|
47
|
+
npm install
|
|
48
|
+
npm run build
|
|
49
|
+
node dist/index.js
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Configure Cursor
|
|
55
|
+
|
|
56
|
+
Edit `~/.cursor/mcp.json`:
|
|
57
|
+
|
|
58
|
+
```json
|
|
59
|
+
{
|
|
60
|
+
"mcpServers": {
|
|
61
|
+
"apiscen": {
|
|
62
|
+
"command": "npx",
|
|
63
|
+
"args": ["-y", "@mhdd_24/api-scenario-mcp"],
|
|
64
|
+
"env": {
|
|
65
|
+
"PROJECT_ROOT": "..."
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
**Local development:**
|
|
73
|
+
|
|
74
|
+
```json
|
|
75
|
+
{
|
|
76
|
+
"command": "node",
|
|
77
|
+
"args": ["/absolute/path/to/API-Scenario-MCP/dist/index.js"]
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Environment variables
|
|
84
|
+
|
|
85
|
+
| Variable | Description |
|
|
86
|
+
|----------|-------------|
|
|
87
|
+
| `PROJECT_ROOT` | Default project/repository root |
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Tools
|
|
92
|
+
|
|
93
|
+
| Tool | Description |
|
|
94
|
+
|------|-------------|
|
|
95
|
+
| `apiscen_status` | Health check for API Scenario MCP. |
|
|
96
|
+
| `apiscen_generate` | Generate a multi-step API workflow. |
|
|
97
|
+
| `apiscen_to_http` | Convert a scenario outline to HTTP steps. |
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## License
|
|
102
|
+
|
|
103
|
+
ISC
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export const APISCEN = {
|
|
2
|
+
SERVER: {
|
|
3
|
+
NAME: '@mhdd_24/api-scenario-mcp',
|
|
4
|
+
VERSION: '1.0.0',
|
|
5
|
+
STARTUP_MESSAGE: 'API Scenario MCP Server Started',
|
|
6
|
+
FATAL_PREFIX: 'Fatal error:',
|
|
7
|
+
},
|
|
8
|
+
ENV: {
|
|
9
|
+
PROJECT_ROOT_KEYS: ['PROJECT_ROOT', 'projectRoot'],
|
|
10
|
+
},
|
|
11
|
+
MESSAGES: {
|
|
12
|
+
MISSING_CONFIG: 'Required configuration is missing. See .env.example.',
|
|
13
|
+
},
|
|
14
|
+
TOOLS: {
|
|
15
|
+
STATUS: {
|
|
16
|
+
NAME: 'apiscen_status',
|
|
17
|
+
DESCRIPTION: "Health check for API Scenario MCP.",
|
|
18
|
+
},
|
|
19
|
+
GENERATE: {
|
|
20
|
+
NAME: 'apiscen_generate',
|
|
21
|
+
DESCRIPTION: "Generate a multi-step API workflow.",
|
|
22
|
+
GOAL_DESCRIPTION: "Business goal",
|
|
23
|
+
ENDPOINTS_DESCRIPTION: "Known endpoints",
|
|
24
|
+
},
|
|
25
|
+
TO_HTTP: {
|
|
26
|
+
NAME: 'apiscen_to_http',
|
|
27
|
+
DESCRIPTION: "Convert a scenario outline to HTTP steps.",
|
|
28
|
+
SCENARIO_DESCRIPTION: "Scenario text",
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
};
|
package/dist/env.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import dotenv from 'dotenv';
|
|
2
|
+
import { APISCEN } from './config/api-scenario.config.js';
|
|
3
|
+
dotenv.config();
|
|
4
|
+
function readEnv(keys) {
|
|
5
|
+
for (const key of keys) {
|
|
6
|
+
const value = process.env[key];
|
|
7
|
+
if (value)
|
|
8
|
+
return value;
|
|
9
|
+
}
|
|
10
|
+
return undefined;
|
|
11
|
+
}
|
|
12
|
+
export const env = {
|
|
13
|
+
PROJECT_ROOT: readEnv(APISCEN.ENV.PROJECT_ROOT_KEYS),
|
|
14
|
+
};
|
|
15
|
+
export function validateEnv() {
|
|
16
|
+
// Soft validation — tools report concrete errors when credentials/paths are missing.
|
|
17
|
+
}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
|
+
import { APISCEN } from './config/api-scenario.config.js';
|
|
5
|
+
import { validateEnv } from './env.js';
|
|
6
|
+
import { registerTools } from './tools/index.js';
|
|
7
|
+
validateEnv();
|
|
8
|
+
const server = new McpServer({
|
|
9
|
+
name: APISCEN.SERVER.NAME,
|
|
10
|
+
version: APISCEN.SERVER.VERSION,
|
|
11
|
+
});
|
|
12
|
+
registerTools(server);
|
|
13
|
+
async function main() {
|
|
14
|
+
const transport = new StdioServerTransport();
|
|
15
|
+
await server.connect(transport);
|
|
16
|
+
console.error(APISCEN.SERVER.STARTUP_MESSAGE);
|
|
17
|
+
}
|
|
18
|
+
main().catch((error) => {
|
|
19
|
+
console.error(APISCEN.SERVER.FATAL_PREFIX, error);
|
|
20
|
+
process.exit(1);
|
|
21
|
+
});
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { env } from '../env.js';
|
|
2
|
+
function mask(value) {
|
|
3
|
+
if (!value)
|
|
4
|
+
return '(unset)';
|
|
5
|
+
if (value.length <= 8)
|
|
6
|
+
return '***';
|
|
7
|
+
return `${value.slice(0, 4)}…${value.slice(-2)} (len=${value.length})`;
|
|
8
|
+
}
|
|
9
|
+
async function runCapture(cmd, args, input) {
|
|
10
|
+
const { spawn } = await import('node:child_process');
|
|
11
|
+
return new Promise((resolve, reject) => {
|
|
12
|
+
const child = spawn(cmd, args, { env: process.env });
|
|
13
|
+
let stdout = '';
|
|
14
|
+
let stderr = '';
|
|
15
|
+
child.stdout.on('data', (d) => (stdout += d.toString()));
|
|
16
|
+
child.stderr.on('data', (d) => (stderr += d.toString()));
|
|
17
|
+
child.on('error', reject);
|
|
18
|
+
child.on('close', () => resolve({ stdout: stdout.trim(), stderr: stderr.trim() }));
|
|
19
|
+
if (input)
|
|
20
|
+
child.stdin.end(input);
|
|
21
|
+
else
|
|
22
|
+
child.stdin.end();
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
export class ApiScenarioService {
|
|
26
|
+
async status() {
|
|
27
|
+
const lines = [
|
|
28
|
+
'API Scenario MCP status:',
|
|
29
|
+
`- PROJECT_ROOT: ${mask(env.PROJECT_ROOT)}`,
|
|
30
|
+
`- platform: ${process.platform}`,
|
|
31
|
+
];
|
|
32
|
+
return lines.join('\n');
|
|
33
|
+
}
|
|
34
|
+
async generate(goal, endpoints) {
|
|
35
|
+
return JSON.stringify({
|
|
36
|
+
tool: 'GENERATE',
|
|
37
|
+
configured: Boolean(true),
|
|
38
|
+
baseUrl: undefined,
|
|
39
|
+
args: { goal, endpoints },
|
|
40
|
+
note: 'Wire live API calls with credentials in env; status/tools are scaffolded in Sublime-MCP style.',
|
|
41
|
+
}, null, 2);
|
|
42
|
+
}
|
|
43
|
+
async toHttp(scenario) {
|
|
44
|
+
return JSON.stringify({
|
|
45
|
+
tool: 'TO_HTTP',
|
|
46
|
+
configured: Boolean(true),
|
|
47
|
+
baseUrl: undefined,
|
|
48
|
+
args: { scenario },
|
|
49
|
+
note: 'Wire live API calls with credentials in env; status/tools are scaffolded in Sublime-MCP style.',
|
|
50
|
+
}, null, 2);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
export const service = new ApiScenarioService();
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { APISCEN } from '../config/api-scenario.config.js';
|
|
3
|
+
import { service } from '../services/api-scenarioService.js';
|
|
4
|
+
import { toolError, toolText } from '../utils/toolResponse.js';
|
|
5
|
+
export function registerGenerateTool(server) {
|
|
6
|
+
const cfg = APISCEN.TOOLS.GENERATE;
|
|
7
|
+
server.tool(cfg.NAME, cfg.DESCRIPTION, {
|
|
8
|
+
goal: z.string().describe("Business goal"),
|
|
9
|
+
endpoints: z.string().optional().describe("Known endpoints"),
|
|
10
|
+
}, async (args) => {
|
|
11
|
+
try {
|
|
12
|
+
const result = await service.generate(args.goal, args.endpoints);
|
|
13
|
+
return toolText(result);
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
return toolError(error);
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { registerStatusTool } from './statusTool.js';
|
|
2
|
+
import { registerGenerateTool } from './generateTool.js';
|
|
3
|
+
import { registerToHttpTool } from './toHttpTool.js';
|
|
4
|
+
export function registerTools(server) {
|
|
5
|
+
registerStatusTool(server);
|
|
6
|
+
registerGenerateTool(server);
|
|
7
|
+
registerToHttpTool(server);
|
|
8
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { APISCEN } from '../config/api-scenario.config.js';
|
|
2
|
+
import { service } from '../services/api-scenarioService.js';
|
|
3
|
+
import { toolError, toolText } from '../utils/toolResponse.js';
|
|
4
|
+
export function registerStatusTool(server) {
|
|
5
|
+
const cfg = APISCEN.TOOLS.STATUS;
|
|
6
|
+
server.tool(cfg.NAME, cfg.DESCRIPTION, {}, async (_args) => {
|
|
7
|
+
try {
|
|
8
|
+
const result = await service.status();
|
|
9
|
+
return toolText(result);
|
|
10
|
+
}
|
|
11
|
+
catch (error) {
|
|
12
|
+
return toolError(error);
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { APISCEN } from '../config/api-scenario.config.js';
|
|
3
|
+
import { service } from '../services/api-scenarioService.js';
|
|
4
|
+
import { toolError, toolText } from '../utils/toolResponse.js';
|
|
5
|
+
export function registerToHttpTool(server) {
|
|
6
|
+
const cfg = APISCEN.TOOLS.TO_HTTP;
|
|
7
|
+
server.tool(cfg.NAME, cfg.DESCRIPTION, {
|
|
8
|
+
scenario: z.string().describe("Scenario text"),
|
|
9
|
+
}, async (args) => {
|
|
10
|
+
try {
|
|
11
|
+
const result = await service.toHttp(args.scenario);
|
|
12
|
+
return toolText(result);
|
|
13
|
+
}
|
|
14
|
+
catch (error) {
|
|
15
|
+
return toolError(error);
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export function toolText(text, isError = false) {
|
|
2
|
+
return { isError, content: [{ type: 'text', text }] };
|
|
3
|
+
}
|
|
4
|
+
export function toolError(error) {
|
|
5
|
+
const text = error instanceof Error ? error.message : String(error);
|
|
6
|
+
return { isError: true, content: [{ type: 'text', text }] };
|
|
7
|
+
}
|
package/docs/WIKI.md
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# API Scenario MCP Wiki
|
|
2
|
+
|
|
3
|
+
## Architecture
|
|
4
|
+
|
|
5
|
+
Same layered shell as Sublime-MCP / Flyway-MCP:
|
|
6
|
+
|
|
7
|
+
- `src/index.ts` — stdio MCP bootstrap
|
|
8
|
+
- `src/env.ts` — dotenv + env readers
|
|
9
|
+
- `src/config/api-scenario.config.ts` — `APISCEN` constants
|
|
10
|
+
- `src/tools/` — thin Zod tools
|
|
11
|
+
- `src/services/` — domain logic
|
|
12
|
+
- `src/utils/toolResponse.ts` — `toolText` / `toolError`
|
|
13
|
+
|
|
14
|
+
## Tools
|
|
15
|
+
|
|
16
|
+
| `apiscen_status` | Health check for API Scenario MCP. |
|
|
17
|
+
| `apiscen_generate` | Generate a multi-step API workflow. |
|
|
18
|
+
| `apiscen_to_http` | Convert a scenario outline to HTTP steps. |
|
|
19
|
+
|
|
20
|
+
## Troubleshooting
|
|
21
|
+
|
|
22
|
+
- Ensure Node 18+
|
|
23
|
+
- Copy `.env.example` → `.env` and fill credentials
|
|
24
|
+
- Run `npm run build` before `node dist/index.js`
|
|
25
|
+
- Never log protocol traffic to stdout
|
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mhdd_24/api-scenario-mcp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Generate complete multi-step API workflows",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"api-scenario-mcp": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"README.md",
|
|
13
|
+
"docs/WIKI.md"
|
|
14
|
+
],
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"access": "public"
|
|
17
|
+
},
|
|
18
|
+
"scripts": {
|
|
19
|
+
"dev": "tsx src/index.ts",
|
|
20
|
+
"build": "tsc",
|
|
21
|
+
"prepack": "npm run build",
|
|
22
|
+
"start": "node dist/index.js"
|
|
23
|
+
},
|
|
24
|
+
"keywords": [
|
|
25
|
+
"mcp",
|
|
26
|
+
"model-context-protocol",
|
|
27
|
+
"api-scenario",
|
|
28
|
+
"cursor"
|
|
29
|
+
],
|
|
30
|
+
"author": "Mhdd-24",
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "git+https://github.com/Mhdd-24/API-Scenario-MCP.git"
|
|
34
|
+
},
|
|
35
|
+
"bugs": {
|
|
36
|
+
"url": "https://github.com/Mhdd-24/API-Scenario-MCP/issues"
|
|
37
|
+
},
|
|
38
|
+
"homepage": "https://github.com/Mhdd-24/API-Scenario-MCP#readme",
|
|
39
|
+
"license": "ISC",
|
|
40
|
+
"engines": {
|
|
41
|
+
"node": ">=18"
|
|
42
|
+
},
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
45
|
+
"dotenv": "^17.4.2",
|
|
46
|
+
"zod": "^4.4.3"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@types/node": "^26.1.0",
|
|
50
|
+
"tsx": "^4.22.4",
|
|
51
|
+
"typescript": "^6.0.3"
|
|
52
|
+
}
|
|
53
|
+
}
|