mpx-api 1.0.2 → 1.1.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/README.md CHANGED
@@ -182,6 +182,134 @@ mpx-api history -n 50
182
182
 
183
183
  Cookies are automatically saved and sent with subsequent requests. Cookie jar is stored at `~/.mpx-api/cookies.json`.
184
184
 
185
+ ## AI Agent Usage 🤖
186
+
187
+ **mpx-api is AI-native!** Every command supports structured JSON output, schema discovery, and MCP (Model Context Protocol) integration for seamless AI agent automation.
188
+
189
+ ### JSON Output
190
+
191
+ Add `--json` to any command for machine-readable output:
192
+
193
+ ```bash
194
+ # HTTP request with JSON output
195
+ mpx-api get https://api.github.com/users/octocat --json
196
+
197
+ # Output structure
198
+ {
199
+ "request": {
200
+ "method": "GET",
201
+ "url": "https://api.github.com/users/octocat",
202
+ "headers": {},
203
+ "body": null
204
+ },
205
+ "response": {
206
+ "status": 200,
207
+ "statusText": "OK",
208
+ "headers": { "content-type": "application/json" },
209
+ "body": { "login": "octocat", ... },
210
+ "rawBody": "...",
211
+ "responseTime": 145,
212
+ "size": 1234
213
+ }
214
+ }
215
+ ```
216
+
217
+ ### Schema Discovery
218
+
219
+ AI agents can discover all available commands, flags, and output formats:
220
+
221
+ ```bash
222
+ mpx-api --schema
223
+ ```
224
+
225
+ Returns a complete JSON schema describing:
226
+ - All commands and subcommands
227
+ - Available flags and their types
228
+ - Input/output schemas
229
+ - Usage examples
230
+ - Exit codes
231
+
232
+ Perfect for dynamic tool discovery by AI assistants!
233
+
234
+ ### MCP Server Mode
235
+
236
+ Start mpx-api as an MCP (Model Context Protocol) server for AI agent integration:
237
+
238
+ ```bash
239
+ mpx-api mcp
240
+ ```
241
+
242
+ Add to your MCP client configuration (e.g., Claude Desktop, Cline):
243
+
244
+ ```json
245
+ {
246
+ "mcpServers": {
247
+ "mpx-api": {
248
+ "command": "npx",
249
+ "args": ["mpx-api", "mcp"]
250
+ }
251
+ }
252
+ }
253
+ ```
254
+
255
+ **Available MCP tools:**
256
+
257
+ - `http_request` - Send HTTP requests with full control over method, headers, body
258
+ - `get_schema` - Get the complete tool schema for dynamic discovery
259
+
260
+ **Example MCP usage:**
261
+
262
+ AI agents can now make API requests on your behalf:
263
+ - "Make a GET request to https://api.github.com/users/octocat"
264
+ - "POST to https://api.example.com/users with JSON body {name: 'Alice'}"
265
+ - "What commands does mpx-api support?" (via get_schema)
266
+
267
+ ### Quiet Mode
268
+
269
+ Suppress non-essential output with `--quiet` or `-q`:
270
+
271
+ ```bash
272
+ mpx-api get https://api.example.com/data --quiet --json
273
+ ```
274
+
275
+ Perfect for scripting and automation where you only want the result data.
276
+
277
+ ### Composability
278
+
279
+ All commands are designed for Unix-style composition:
280
+
281
+ ```bash
282
+ # Pipe output to jq
283
+ mpx-api get https://api.github.com/users/octocat --json | jq '.response.body.login'
284
+
285
+ # Use in scripts
286
+ STATUS=$(mpx-api get https://api.example.com/health --json | jq -r '.response.status')
287
+ if [ "$STATUS" -eq 200 ]; then
288
+ echo "API is healthy"
289
+ fi
290
+
291
+ # Batch processing
292
+ cat urls.txt | while read url; do
293
+ mpx-api get "$url" --json >> results.jsonl
294
+ done
295
+ ```
296
+
297
+ ### Exit Codes
298
+
299
+ Predictable exit codes for automation:
300
+
301
+ - `0` - Success (2xx or 3xx HTTP status)
302
+ - `1` - Request failed or 4xx/5xx HTTP status
303
+
304
+ ```bash
305
+ # Check if request succeeded
306
+ if mpx-api get https://api.example.com/endpoint --quiet; then
307
+ echo "Success!"
308
+ else
309
+ echo "Request failed"
310
+ fi
311
+ ```
312
+
185
313
  ## Pro Features 💎
186
314
 
187
315
  Upgrade to **mpx-api Pro** ($12/mo) for advanced features:
package/bin/mpx-api.js CHANGED
@@ -15,6 +15,10 @@ import { registerHistoryCommand } from '../src/commands/history.js';
15
15
  import { registerLoadCommand } from '../src/commands/load.js';
16
16
  import { registerDocsCommand } from '../src/commands/docs.js';
17
17
 
18
+ // AI-native features
19
+ import { getSchema } from '../src/schema.js';
20
+ import { startMCPServer } from '../src/mcp.js';
21
+
18
22
  const __filename = fileURLToPath(import.meta.url);
19
23
  const __dirname = dirname(__filename);
20
24
 
@@ -22,10 +26,19 @@ const pkg = JSON.parse(
22
26
  readFileSync(join(__dirname, '../package.json'), 'utf8')
23
27
  );
24
28
 
29
+ // Handle --schema flag early (before commander parsing)
30
+ if (process.argv.includes('--schema')) {
31
+ console.log(JSON.stringify(getSchema(), null, 2));
32
+ process.exit(0);
33
+ }
34
+
25
35
  program
26
36
  .name('mpx-api')
27
37
  .description('Developer-first API testing, mocking, and documentation CLI')
28
- .version(pkg.version);
38
+ .version(pkg.version)
39
+ .option('--json', 'Output structured JSON (machine-readable)')
40
+ .option('--quiet, -q', 'Suppress non-essential output')
41
+ .option('--schema', 'Output JSON schema describing all commands and flags');
29
42
 
30
43
  // Register HTTP method commands (get, post, put, patch, delete, head, options)
31
44
  registerRequestCommands(program);
@@ -49,4 +62,17 @@ registerHistoryCommand(program);
49
62
  registerLoadCommand(program);
50
63
  registerDocsCommand(program);
51
64
 
65
+ // MCP subcommand
66
+ program
67
+ .command('mcp')
68
+ .description('Start MCP (Model Context Protocol) stdio server')
69
+ .action(async () => {
70
+ try {
71
+ await startMCPServer();
72
+ } catch (err) {
73
+ console.error(JSON.stringify({ error: err.message, code: 'ERR_MCP_START' }));
74
+ process.exit(1);
75
+ }
76
+ });
77
+
52
78
  program.parse();
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mpx-api",
3
- "version": "1.0.2",
4
- "description": "Developer-first API testing, mocking, and documentation CLI",
3
+ "version": "1.1.0",
4
+ "description": "Developer-first API testing, mocking, and documentation CLI with AI-native features (JSON output, MCP server)",
5
5
  "main": "src/index.js",
6
6
  "bin": {
7
7
  "mpx-api": "bin/mpx-api.js"
@@ -16,7 +16,11 @@
16
16
  "postman",
17
17
  "httpie",
18
18
  "openapi",
19
- "swagger"
19
+ "swagger",
20
+ "mcp",
21
+ "ai-native",
22
+ "model-context-protocol",
23
+ "automation"
20
24
  ],
21
25
  "author": "Mesaplex <support@mesaplex.com>",
22
26
  "license": "MIT",
@@ -33,12 +37,13 @@
33
37
  },
34
38
  "type": "module",
35
39
  "scripts": {
36
- "test": "node --test test/**/*.test.js",
40
+ "test": "node --test test/*.test.js",
37
41
  "test:watch": "node --test --watch test/**/*.test.js",
38
42
  "lint": "echo 'TODO: Add eslint'",
39
43
  "prepublishOnly": "npm test"
40
44
  },
41
45
  "dependencies": {
46
+ "@modelcontextprotocol/sdk": "^1.26.0",
42
47
  "chalk": "^5.3.0",
43
48
  "commander": "^12.0.0",
44
49
  "yaml": "^2.3.4",
@@ -17,8 +17,13 @@ export function registerRequestCommands(program) {
17
17
  .option('--no-follow', 'Do not follow redirects')
18
18
  .option('--no-verify', 'Skip SSL certificate verification')
19
19
  .option('--timeout <ms>', 'Request timeout in milliseconds', '30000')
20
- .action(async (url, options) => {
20
+ .action(async (url, options, command) => {
21
21
  try {
22
+ // Get global options
23
+ const globalOpts = command.optsWithGlobals();
24
+ const jsonOutput = globalOpts.json || false;
25
+ const quiet = options.quiet || globalOpts.quiet || false;
26
+
22
27
  const client = new HttpClient({
23
28
  followRedirects: options.follow,
24
29
  verifySsl: options.verify,
@@ -34,7 +39,11 @@ export function registerRequestCommands(program) {
34
39
  try {
35
40
  requestOptions.json = JSON.parse(options.json);
36
41
  } catch (err) {
37
- formatError(new Error(`Invalid JSON: ${err.message}`));
42
+ if (jsonOutput) {
43
+ console.log(JSON.stringify({ error: `Invalid JSON: ${err.message}` }));
44
+ } else {
45
+ formatError(new Error(`Invalid JSON: ${err.message}`));
46
+ }
38
47
  process.exit(1);
39
48
  }
40
49
  } else if (options.data) {
@@ -57,7 +66,14 @@ export function registerRequestCommands(program) {
57
66
  // Format and display response
58
67
  formatResponse(response, {
59
68
  verbose: options.verbose,
60
- quiet: options.quiet,
69
+ quiet: quiet,
70
+ jsonOutput: jsonOutput,
71
+ request: {
72
+ method: method.toUpperCase(),
73
+ url,
74
+ headers: requestOptions.headers,
75
+ body: requestOptions.json || requestOptions.body,
76
+ }
61
77
  });
62
78
 
63
79
  // Exit with non-zero code for 4xx/5xx errors
@@ -65,7 +81,12 @@ export function registerRequestCommands(program) {
65
81
  process.exit(1);
66
82
  }
67
83
  } catch (err) {
68
- formatError(err);
84
+ const globalOpts = command.optsWithGlobals();
85
+ if (globalOpts.json) {
86
+ console.log(JSON.stringify({ error: err.message, code: err.code || 'ERR_REQUEST' }));
87
+ } else {
88
+ formatError(err);
89
+ }
69
90
  process.exit(1);
70
91
  }
71
92
  });
package/src/lib/output.js CHANGED
@@ -3,8 +3,34 @@ import { highlight } from 'cli-highlight';
3
3
 
4
4
  const MAX_BODY_SIZE = 50 * 1024; // 50KB max for terminal display
5
5
 
6
+ export function formatResponseJSON(response, request = {}) {
7
+ return JSON.stringify({
8
+ request: {
9
+ method: request.method || response.method,
10
+ url: request.url || response.url,
11
+ headers: request.headers || {},
12
+ body: request.body || null
13
+ },
14
+ response: {
15
+ status: response.status,
16
+ statusText: response.statusText,
17
+ headers: response.headers,
18
+ body: response.body,
19
+ rawBody: response.rawBody,
20
+ responseTime: response.responseTime,
21
+ size: response.size
22
+ }
23
+ }, null, 2);
24
+ }
25
+
6
26
  export function formatResponse(response, options = {}) {
7
- const { verbose = false, quiet = false } = options;
27
+ const { verbose = false, quiet = false, jsonOutput = false } = options;
28
+
29
+ // Handle JSON output mode
30
+ if (jsonOutput) {
31
+ console.log(formatResponseJSON(response, options.request || {}));
32
+ return;
33
+ }
8
34
 
9
35
  if (quiet) {
10
36
  // Only output body
package/src/mcp.js ADDED
@@ -0,0 +1,180 @@
1
+ /**
2
+ * MCP (Model Context Protocol) Server
3
+ *
4
+ * Exposes mpx-api capabilities as MCP tools for AI agent integration.
5
+ * Runs over stdio transport.
6
+ */
7
+
8
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
9
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
10
+ import {
11
+ ListToolsRequestSchema,
12
+ CallToolRequestSchema
13
+ } from '@modelcontextprotocol/sdk/types.js';
14
+
15
+ import { HttpClient } from './lib/http-client.js';
16
+ import { getSchema } from './schema.js';
17
+ import { readFileSync } from 'fs';
18
+ import { fileURLToPath } from 'url';
19
+ import { dirname, join } from 'path';
20
+
21
+ const __filename = fileURLToPath(import.meta.url);
22
+ const __dirname = dirname(__filename);
23
+ const pkg = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf8'));
24
+
25
+ export async function startMCPServer() {
26
+ const server = new Server(
27
+ { name: 'mpx-api', version: pkg.version },
28
+ { capabilities: { tools: {} } }
29
+ );
30
+
31
+ // List available tools
32
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
33
+ return {
34
+ tools: [
35
+ {
36
+ name: 'http_request',
37
+ description: 'Send an HTTP request (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS). Returns structured response with status, headers, body, and timing.',
38
+ inputSchema: {
39
+ type: 'object',
40
+ properties: {
41
+ method: {
42
+ type: 'string',
43
+ enum: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'],
44
+ description: 'HTTP method'
45
+ },
46
+ url: {
47
+ type: 'string',
48
+ description: 'Target URL'
49
+ },
50
+ headers: {
51
+ type: 'object',
52
+ description: 'Request headers as key-value pairs',
53
+ additionalProperties: { type: 'string' }
54
+ },
55
+ json: {
56
+ type: 'object',
57
+ description: 'JSON body (automatically sets Content-Type: application/json)'
58
+ },
59
+ body: {
60
+ type: 'string',
61
+ description: 'Raw request body (use either json or body, not both)'
62
+ },
63
+ followRedirects: {
64
+ type: 'boolean',
65
+ default: true,
66
+ description: 'Follow HTTP redirects'
67
+ },
68
+ verifySsl: {
69
+ type: 'boolean',
70
+ default: true,
71
+ description: 'Verify SSL certificates'
72
+ },
73
+ timeout: {
74
+ type: 'number',
75
+ default: 30000,
76
+ description: 'Request timeout in milliseconds'
77
+ }
78
+ },
79
+ required: ['method', 'url']
80
+ }
81
+ },
82
+ {
83
+ name: 'get_schema',
84
+ description: 'Get the full JSON schema describing all mpx-api commands, flags, and output formats.',
85
+ inputSchema: {
86
+ type: 'object',
87
+ properties: {}
88
+ }
89
+ }
90
+ ]
91
+ };
92
+ });
93
+
94
+ // Handle tool calls
95
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
96
+ const { name, arguments: args } = request.params;
97
+
98
+ try {
99
+ switch (name) {
100
+ case 'http_request': {
101
+ const client = new HttpClient({
102
+ followRedirects: args.followRedirects !== false,
103
+ verifySsl: args.verifySsl !== false,
104
+ timeout: args.timeout || 30000,
105
+ });
106
+
107
+ const requestOptions = {
108
+ headers: args.headers || {},
109
+ };
110
+
111
+ // Handle JSON or raw body
112
+ if (args.json) {
113
+ requestOptions.json = args.json;
114
+ } else if (args.body) {
115
+ requestOptions.body = args.body;
116
+ }
117
+
118
+ const method = (args.method || 'GET').toLowerCase();
119
+ const response = await client.request(method, args.url, requestOptions);
120
+
121
+ // Return structured response
122
+ const result = {
123
+ request: {
124
+ method: method.toUpperCase(),
125
+ url: args.url,
126
+ headers: requestOptions.headers,
127
+ body: args.json || args.body || null
128
+ },
129
+ response: {
130
+ status: response.status,
131
+ statusText: response.statusText,
132
+ headers: response.headers,
133
+ body: response.body,
134
+ rawBody: response.rawBody,
135
+ responseTime: response.responseTime,
136
+ size: response.size
137
+ }
138
+ };
139
+
140
+ return {
141
+ content: [{
142
+ type: 'text',
143
+ text: JSON.stringify(result, null, 2)
144
+ }]
145
+ };
146
+ }
147
+
148
+ case 'get_schema': {
149
+ return {
150
+ content: [{
151
+ type: 'text',
152
+ text: JSON.stringify(getSchema(), null, 2)
153
+ }]
154
+ };
155
+ }
156
+
157
+ default:
158
+ return {
159
+ content: [{ type: 'text', text: `Unknown tool: ${name}` }],
160
+ isError: true
161
+ };
162
+ }
163
+ } catch (err) {
164
+ return {
165
+ content: [{
166
+ type: 'text',
167
+ text: JSON.stringify({
168
+ error: err.message,
169
+ code: err.code || 'ERR_REQUEST',
170
+ stack: err.stack
171
+ }, null, 2)
172
+ }],
173
+ isError: true
174
+ };
175
+ }
176
+ });
177
+
178
+ const transport = new StdioServerTransport();
179
+ await server.connect(transport);
180
+ }
package/src/schema.js ADDED
@@ -0,0 +1,307 @@
1
+ /**
2
+ * Schema Module
3
+ *
4
+ * Returns a machine-readable JSON schema describing all commands,
5
+ * flags, inputs, and outputs for AI agent discovery.
6
+ */
7
+
8
+ import { readFileSync } from 'fs';
9
+ import { fileURLToPath } from 'url';
10
+ import { dirname, join } from 'path';
11
+
12
+ const __filename = fileURLToPath(import.meta.url);
13
+ const __dirname = dirname(__filename);
14
+ const pkg = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf8'));
15
+
16
+ export function getSchema() {
17
+ return {
18
+ tool: 'mpx-api',
19
+ version: pkg.version,
20
+ description: pkg.description,
21
+ homepage: pkg.homepage,
22
+ commands: {
23
+ 'http-methods': {
24
+ description: 'Send HTTP requests (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS)',
25
+ usage: 'mpx-api <method> <url> [options]',
26
+ methods: ['get', 'post', 'put', 'patch', 'delete', 'head', 'options'],
27
+ arguments: {
28
+ url: {
29
+ type: 'string',
30
+ required: true,
31
+ description: 'Target URL for the HTTP request'
32
+ }
33
+ },
34
+ flags: {
35
+ '-H, --header': {
36
+ type: 'array',
37
+ description: 'Add request headers (format: "key:value" or "key: value")',
38
+ repeatable: true
39
+ },
40
+ '-j, --json': {
41
+ type: 'string',
42
+ description: 'Send JSON data (automatically sets Content-Type: application/json)'
43
+ },
44
+ '-d, --data': {
45
+ type: 'string',
46
+ description: 'Send raw request body'
47
+ },
48
+ '-v, --verbose': {
49
+ type: 'boolean',
50
+ default: false,
51
+ description: 'Show response headers in output'
52
+ },
53
+ '-q, --quiet': {
54
+ type: 'boolean',
55
+ default: false,
56
+ description: 'Only output response body (no headers, no formatting)'
57
+ },
58
+ '--no-follow': {
59
+ type: 'boolean',
60
+ default: false,
61
+ description: 'Do not follow HTTP redirects'
62
+ },
63
+ '--no-verify': {
64
+ type: 'boolean',
65
+ default: false,
66
+ description: 'Skip SSL certificate verification'
67
+ },
68
+ '--timeout': {
69
+ type: 'number',
70
+ default: 30000,
71
+ description: 'Request timeout in milliseconds'
72
+ },
73
+ '--json-output': {
74
+ type: 'boolean',
75
+ default: false,
76
+ description: 'Output results as structured JSON'
77
+ }
78
+ },
79
+ output: {
80
+ json: {
81
+ description: 'Structured response data when --json-output is used',
82
+ schema: {
83
+ type: 'object',
84
+ properties: {
85
+ request: {
86
+ type: 'object',
87
+ properties: {
88
+ method: { type: 'string' },
89
+ url: { type: 'string' },
90
+ headers: { type: 'object' },
91
+ body: { type: ['string', 'object', 'null'] }
92
+ }
93
+ },
94
+ response: {
95
+ type: 'object',
96
+ properties: {
97
+ status: { type: 'number' },
98
+ statusText: { type: 'string' },
99
+ headers: { type: 'object' },
100
+ body: { type: ['string', 'object', 'null'] },
101
+ rawBody: { type: 'string' },
102
+ responseTime: { type: 'number', description: 'Response time in milliseconds' },
103
+ size: { type: 'number', description: 'Response size in bytes' }
104
+ }
105
+ }
106
+ }
107
+ }
108
+ },
109
+ error: {
110
+ description: 'Error response when request fails',
111
+ schema: {
112
+ type: 'object',
113
+ properties: {
114
+ error: { type: 'string' },
115
+ message: { type: 'string' },
116
+ code: { type: 'string' }
117
+ }
118
+ }
119
+ }
120
+ },
121
+ exitCodes: {
122
+ 0: 'Success (2xx or 3xx status)',
123
+ 1: 'Request error or 4xx/5xx status'
124
+ },
125
+ examples: [
126
+ { command: 'mpx-api get https://api.example.com/users --json-output', description: 'GET request with JSON output' },
127
+ { command: 'mpx-api post https://api.example.com/users -j \'{"name":"John"}\' --json-output', description: 'POST JSON data with structured output' },
128
+ { command: 'mpx-api get https://api.example.com/data -H "Authorization: Bearer token" --json-output', description: 'GET with custom headers' }
129
+ ]
130
+ },
131
+ collection: {
132
+ description: 'Manage and run request collections',
133
+ subcommands: {
134
+ init: {
135
+ usage: 'mpx-api collection init [options]',
136
+ description: 'Initialize a new collection in current directory',
137
+ flags: {
138
+ '-n, --name': {
139
+ type: 'string',
140
+ default: 'API Collection',
141
+ description: 'Collection name'
142
+ }
143
+ }
144
+ },
145
+ add: {
146
+ usage: 'mpx-api collection add <name> <method> <url> [options]',
147
+ description: 'Add a request to the collection',
148
+ arguments: {
149
+ name: { type: 'string', required: true, description: 'Request name' },
150
+ method: { type: 'string', required: true, description: 'HTTP method' },
151
+ url: { type: 'string', required: true, description: 'Request URL' }
152
+ },
153
+ flags: {
154
+ '-H, --header': { type: 'array', description: 'Request headers' },
155
+ '-j, --json': { type: 'string', description: 'JSON body' },
156
+ '-d, --data': { type: 'string', description: 'Request body' }
157
+ }
158
+ },
159
+ run: {
160
+ usage: 'mpx-api collection run [file] [options]',
161
+ description: 'Run a collection',
162
+ arguments: {
163
+ file: { type: 'string', required: false, description: 'Collection file (default: .mpx-api/collection.yaml)' }
164
+ },
165
+ flags: {
166
+ '-e, --env': { type: 'string', description: 'Environment name to use' },
167
+ '--base-url': { type: 'string', description: 'Override base URL' },
168
+ '--json-output': { type: 'boolean', description: 'Output results as JSON' }
169
+ }
170
+ },
171
+ list: {
172
+ usage: 'mpx-api collection list [file]',
173
+ description: 'List requests in a collection'
174
+ }
175
+ }
176
+ },
177
+ env: {
178
+ description: 'Manage environments',
179
+ subcommands: {
180
+ list: {
181
+ usage: 'mpx-api env list',
182
+ description: 'List all environments',
183
+ flags: {
184
+ '--json-output': { type: 'boolean', description: 'Output as JSON' }
185
+ }
186
+ },
187
+ set: {
188
+ usage: 'mpx-api env set <name> <key> <value>',
189
+ description: 'Set an environment variable',
190
+ arguments: {
191
+ name: { type: 'string', required: true, description: 'Environment name' },
192
+ key: { type: 'string', required: true, description: 'Variable key' },
193
+ value: { type: 'string', required: true, description: 'Variable value' }
194
+ }
195
+ },
196
+ get: {
197
+ usage: 'mpx-api env get <name> <key>',
198
+ description: 'Get an environment variable',
199
+ flags: {
200
+ '--json-output': { type: 'boolean', description: 'Output as JSON' }
201
+ }
202
+ },
203
+ delete: {
204
+ usage: 'mpx-api env delete <name>',
205
+ description: 'Delete an environment'
206
+ }
207
+ }
208
+ },
209
+ mock: {
210
+ description: 'Start a mock API server',
211
+ usage: 'mpx-api mock [file] [options]',
212
+ arguments: {
213
+ file: { type: 'string', required: false, description: 'Mock definition file' }
214
+ },
215
+ flags: {
216
+ '-p, --port': { type: 'number', default: 3000, description: 'Server port' },
217
+ '--watch': { type: 'boolean', description: 'Watch file for changes' }
218
+ }
219
+ },
220
+ test: {
221
+ description: 'Run API tests',
222
+ usage: 'mpx-api test <file> [options]',
223
+ arguments: {
224
+ file: { type: 'string', required: true, description: 'Test file to run' }
225
+ },
226
+ flags: {
227
+ '-e, --env': { type: 'string', description: 'Environment name' },
228
+ '--json-output': { type: 'boolean', description: 'Output results as JSON' }
229
+ }
230
+ },
231
+ history: {
232
+ description: 'View request history',
233
+ usage: 'mpx-api history [options]',
234
+ flags: {
235
+ '-n, --limit': { type: 'number', default: 10, description: 'Number of entries to show' },
236
+ '--json-output': { type: 'boolean', description: 'Output as JSON' }
237
+ }
238
+ },
239
+ load: {
240
+ description: 'Load test API endpoint (Pro)',
241
+ usage: 'mpx-api load <url> [options]',
242
+ arguments: {
243
+ url: { type: 'string', required: true, description: 'Target URL' }
244
+ },
245
+ flags: {
246
+ '-c, --concurrency': { type: 'number', default: 10, description: 'Concurrent requests' },
247
+ '-n, --requests': { type: 'number', default: 100, description: 'Total requests' },
248
+ '--json-output': { type: 'boolean', description: 'Output results as JSON' }
249
+ }
250
+ },
251
+ docs: {
252
+ description: 'Generate API documentation (Pro)',
253
+ usage: 'mpx-api docs <file> [options]',
254
+ arguments: {
255
+ file: { type: 'string', required: true, description: 'Collection or OpenAPI file' }
256
+ },
257
+ flags: {
258
+ '-o, --output': { type: 'string', description: 'Output directory' },
259
+ '--format': { type: 'string', enum: ['html', 'markdown'], default: 'html', description: 'Output format' }
260
+ }
261
+ },
262
+ mcp: {
263
+ description: 'Start MCP (Model Context Protocol) stdio server for AI agent integration',
264
+ usage: 'mpx-api mcp',
265
+ examples: [
266
+ { command: 'mpx-api mcp', description: 'Start MCP stdio server' }
267
+ ]
268
+ }
269
+ },
270
+ globalFlags: {
271
+ '--json-output': {
272
+ type: 'boolean',
273
+ default: false,
274
+ description: 'Output structured JSON for machine consumption'
275
+ },
276
+ '--quiet': {
277
+ type: 'boolean',
278
+ default: false,
279
+ description: 'Suppress non-essential output'
280
+ },
281
+ '--schema': {
282
+ type: 'boolean',
283
+ default: false,
284
+ description: 'Output this schema as JSON'
285
+ },
286
+ '--version': {
287
+ type: 'boolean',
288
+ description: 'Show version number'
289
+ },
290
+ '--help': {
291
+ type: 'boolean',
292
+ description: 'Show help information'
293
+ }
294
+ },
295
+ mcpConfig: {
296
+ description: 'Add to your MCP client configuration to use mpx-api as an AI tool',
297
+ config: {
298
+ mcpServers: {
299
+ 'mpx-api': {
300
+ command: 'npx',
301
+ args: ['mpx-api', 'mcp']
302
+ }
303
+ }
304
+ }
305
+ }
306
+ };
307
+ }