@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 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
+ }