mcp4openapi 0.2.3 → 0.2.4

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.
@@ -0,0 +1,213 @@
1
+ /**
2
+ * Mock Semgrep API server for integration testing
3
+ *
4
+ * Why: Enables end-to-end testing without real Semgrep instance.
5
+ * Tests actual HTTP flow, parameter handling, error scenarios.
6
+ */
7
+ import { http, HttpResponse } from 'msw';
8
+ import { setupServer } from 'msw/node';
9
+ /** Default BASE_URL for Semgrep API (used by MSW interceptor) */
10
+ export const DEFAULT_BASE_URL = 'https://semgrep.dev';
11
+ const DEFAULT_CONFIG = {
12
+ baseUrl: DEFAULT_BASE_URL,
13
+ validToken: 'mock-semgrep-token-12345',
14
+ deploymentSlug: 'test-deployment',
15
+ deploymentId: 123,
16
+ };
17
+ /**
18
+ * Create Semgrep API handlers
19
+ */
20
+ export function createSemgrepHandlers(config = {}) {
21
+ const cfg = { ...DEFAULT_CONFIG, ...config };
22
+ return [
23
+ // GET /api/v1/deployments - List deployments
24
+ http.get(`${cfg.baseUrl}/api/v1/deployments`, ({ request }) => {
25
+ const authHeader = request.headers.get('Authorization');
26
+ if (!authHeader || !authHeader.startsWith('Bearer ')) {
27
+ return HttpResponse.json({ error: 'Unauthorized' }, { status: 401 });
28
+ }
29
+ const token = authHeader.replace('Bearer ', '');
30
+ if (token !== cfg.validToken) {
31
+ return HttpResponse.json({ error: 'Invalid token' }, { status: 401 });
32
+ }
33
+ return HttpResponse.json({
34
+ deployments: [
35
+ {
36
+ id: cfg.deploymentId,
37
+ slug: cfg.deploymentSlug,
38
+ name: 'Test Deployment',
39
+ findings: {
40
+ url: `${cfg.baseUrl}/api/v1/deployments/${cfg.deploymentSlug}/findings`,
41
+ },
42
+ },
43
+ ],
44
+ });
45
+ }),
46
+ // POST /api/v1/deployments/{deploymentSlug}/triage - Bulk triage
47
+ http.post(`${cfg.baseUrl}/api/v1/deployments/:deploymentSlug/triage`, async ({ request, params }) => {
48
+ const authHeader = request.headers.get('Authorization');
49
+ if (!authHeader || !authHeader.startsWith('Bearer ')) {
50
+ return HttpResponse.json({ error: 'Unauthorized' }, { status: 401 });
51
+ }
52
+ const token = authHeader.replace('Bearer ', '');
53
+ if (token !== cfg.validToken) {
54
+ return HttpResponse.json({ error: 'Invalid token' }, { status: 401 });
55
+ }
56
+ const { deploymentSlug } = params;
57
+ if (deploymentSlug !== cfg.deploymentSlug) {
58
+ return HttpResponse.json({ error: 'Deployment not found' }, { status: 404 });
59
+ }
60
+ let body;
61
+ try {
62
+ body = await request.json();
63
+ }
64
+ catch (e) {
65
+ return HttpResponse.json({ error: 'Invalid JSON body' }, { status: 400 });
66
+ }
67
+ // Log the received request for debugging
68
+ console.log('[Mock Semgrep] Received triage request:', {
69
+ url: request.url,
70
+ params,
71
+ body,
72
+ headers: {
73
+ 'Content-Type': request.headers.get('Content-Type'),
74
+ 'Authorization': authHeader ? '***' : undefined,
75
+ },
76
+ });
77
+ // Validate required fields according to OpenAPI spec
78
+ if (!body.issue_type) {
79
+ return HttpResponse.json({
80
+ error: 'Validation error',
81
+ details: 'issue_type is required',
82
+ }, { status: 400 });
83
+ }
84
+ if (!['sast', 'sca', 'secrets'].includes(body.issue_type)) {
85
+ return HttpResponse.json({
86
+ error: 'Validation error',
87
+ details: 'issue_type must be one of: sast, sca, secrets',
88
+ }, { status: 400 });
89
+ }
90
+ // Check deploymentSlug in body (as per OpenAPI spec)
91
+ if (!body.deploymentSlug) {
92
+ return HttpResponse.json({
93
+ error: 'Validation error',
94
+ details: 'deploymentSlug is required in request body',
95
+ }, { status: 400 });
96
+ }
97
+ if (body.deploymentSlug !== cfg.deploymentSlug) {
98
+ return HttpResponse.json({
99
+ error: 'Validation error',
100
+ details: 'deploymentSlug in body does not match URL parameter',
101
+ }, { status: 400 });
102
+ }
103
+ // Validate limit is integer if provided
104
+ if (body.limit !== undefined) {
105
+ if (!Number.isInteger(body.limit)) {
106
+ return HttpResponse.json({
107
+ error: 'Validation error',
108
+ details: 'limit must be an integer',
109
+ }, { status: 400 });
110
+ }
111
+ if (body.limit < 1 || body.limit > 3000) {
112
+ return HttpResponse.json({
113
+ error: 'Validation error',
114
+ details: 'limit must be between 1 and 3000',
115
+ }, { status: 400 });
116
+ }
117
+ }
118
+ // Validate triage state and reason
119
+ if (body.new_triage_state) {
120
+ const validStates = ['ignored', 'reviewing', 'fixing', 'reopened'];
121
+ if (!validStates.includes(body.new_triage_state)) {
122
+ return HttpResponse.json({
123
+ error: 'Validation error',
124
+ details: `new_triage_state must be one of: ${validStates.join(', ')}`,
125
+ }, { status: 400 });
126
+ }
127
+ if (body.new_triage_state === 'ignored' && body.new_triage_reason) {
128
+ const validReasons = ['acceptable_risk', 'false_positive', 'no_time', 'no_triage_reason'];
129
+ if (!validReasons.includes(body.new_triage_reason)) {
130
+ return HttpResponse.json({
131
+ error: 'Validation error',
132
+ details: `new_triage_reason must be one of: ${validReasons.join(', ')}`,
133
+ }, { status: 400 });
134
+ }
135
+ }
136
+ }
137
+ // Mock successful response
138
+ return HttpResponse.json({
139
+ num_triaged: 3,
140
+ triaged_issues: [123, 456, 789],
141
+ });
142
+ }),
143
+ // GET /api/v1/deployments/{deploymentSlug}/projects - List projects
144
+ http.get(`${cfg.baseUrl}/api/v1/deployments/:deploymentSlug/projects`, ({ request, params }) => {
145
+ const authHeader = request.headers.get('Authorization');
146
+ if (!authHeader || !authHeader.startsWith('Bearer ')) {
147
+ return HttpResponse.json({ error: 'Unauthorized' }, { status: 401 });
148
+ }
149
+ const { deploymentSlug } = params;
150
+ if (deploymentSlug !== cfg.deploymentSlug) {
151
+ return HttpResponse.json({ error: 'Deployment not found' }, { status: 404 });
152
+ }
153
+ // Mock projects response
154
+ return HttpResponse.json({
155
+ projects: [
156
+ {
157
+ id: 1,
158
+ name: 'test-org/test-repo',
159
+ url: 'https://github.com/test-org/test-repo',
160
+ default_branch: 'refs/heads/main',
161
+ tags: ['test'],
162
+ latest_scan_at: '2025-12-03T00:00:00Z',
163
+ },
164
+ ],
165
+ });
166
+ }),
167
+ // GET /api/v1/deployments/{deploymentSlug}/findings - List findings
168
+ http.get(`${cfg.baseUrl}/api/v1/deployments/:deploymentSlug/findings`, ({ request, params }) => {
169
+ const authHeader = request.headers.get('Authorization');
170
+ if (!authHeader || !authHeader.startsWith('Bearer ')) {
171
+ return HttpResponse.json({ error: 'Unauthorized' }, { status: 401 });
172
+ }
173
+ const { deploymentSlug } = params;
174
+ if (deploymentSlug !== cfg.deploymentSlug) {
175
+ return HttpResponse.json({ error: 'Deployment not found' }, { status: 404 });
176
+ }
177
+ const url = new URL(request.url);
178
+ const issueType = url.searchParams.get('issue_type') || 'sast';
179
+ const status = url.searchParams.get('status');
180
+ // Mock findings response
181
+ return HttpResponse.json({
182
+ sastFindings: {
183
+ findings: [
184
+ {
185
+ id: 123,
186
+ severity: 'high',
187
+ status: status || 'open',
188
+ rule: {
189
+ name: 'test.rule.1',
190
+ confidence: 'high',
191
+ },
192
+ repository: {
193
+ name: 'test/repo',
194
+ },
195
+ location: {
196
+ filePath: 'src/test.ts',
197
+ line: 10,
198
+ },
199
+ },
200
+ ],
201
+ },
202
+ });
203
+ }),
204
+ ];
205
+ }
206
+ /**
207
+ * Create and start mock Semgrep server
208
+ */
209
+ export function createMockSemgrepServer(config = {}) {
210
+ const handlers = createSemgrepHandlers(config);
211
+ return setupServer(...handlers);
212
+ }
213
+ //# sourceMappingURL=mock-semgrep-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock-semgrep-server.js","sourceRoot":"","sources":["../../../src/testing/mock-semgrep-server.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"validation-utils.d.ts","sourceRoot":"","sources":["../../src/validation-utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAqBH;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAExD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,MAAM,GACjB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAYzB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,SAAS,EAAE,MAAM,GAChB,MAAM,CAaR;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,GAChB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CASzB;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE9C;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAO5C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CAGrE"}
1
+ {"version":3,"file":"validation-utils.d.ts","sourceRoot":"","sources":["../../src/validation-utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAqBH;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAExD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,MAAM,GACjB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAYzB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,SAAS,EAAE,MAAM,GAChB,MAAM,CAiCR;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,GAChB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CASzB;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE9C;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAO5C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CAGrE"}
@@ -55,6 +55,10 @@ export function redactHeader(headers, headerName) {
55
55
  export function redactQueryParam(url, paramName) {
56
56
  if (!url)
57
57
  return '';
58
+ // Enforce safe paramName (alphanumeric, underscore, dash) length <= 64
59
+ if (!/^[A-Za-z0-9_-]{1,64}$/.test(paramName)) {
60
+ return url; // Unsafe param name; return original unmodified
61
+ }
58
62
  try {
59
63
  const urlObj = new URL(url);
60
64
  if (urlObj.searchParams.has(paramName)) {
@@ -63,8 +67,26 @@ export function redactQueryParam(url, paramName) {
63
67
  return urlObj.toString();
64
68
  }
65
69
  catch {
66
- const regex = new RegExp(`([?&]${escapeRegExp(paramName)}=)[^&]+`, 'gi');
67
- return url.replace(regex, `$1[REDACTED]`);
70
+ // Fallback: manual parsing without dynamic RegExp to avoid ReDoS concerns
71
+ // Split on '?' then process query string key-value pairs
72
+ const qIndex = url.indexOf('?');
73
+ if (qIndex === -1)
74
+ return url;
75
+ const base = url.substring(0, qIndex);
76
+ const query = url.substring(qIndex + 1);
77
+ const parts = query.split('&');
78
+ const redactedParts = parts.map(part => {
79
+ const eqIndex = part.indexOf('=');
80
+ if (eqIndex === -1)
81
+ return part; // skip malformed segment
82
+ const key = part.substring(0, eqIndex);
83
+ if (key === paramName) {
84
+ // Encode [REDACTED] for consistency with URLSearchParams behavior
85
+ return key + '=%5BREDACTED%5D';
86
+ }
87
+ return part;
88
+ });
89
+ return base + '?' + redactedParts.join('&');
68
90
  }
69
91
  }
70
92
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"validation-utils.js","sourceRoot":"","sources":["../../src/validation-utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"validation-utils.js","sourceRoot":"","sources":["../../src/validation-utils.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp4openapi",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "description": "Universal MCP server that generates tools from any OpenAPI specification",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",
@@ -56,10 +56,10 @@
56
56
  "url": "https://github.com/davidruzicka/mcp4openapi/issues"
57
57
  },
58
58
  "dependencies": {
59
- "@modelcontextprotocol/sdk": "^1.0.4",
59
+ "@modelcontextprotocol/sdk": "^1.24.0",
60
60
  "dotenv": "^17.2.3",
61
61
  "escape-html": "^1.0.3",
62
- "express": "^5.1.0",
62
+ "express": "^5.2.1",
63
63
  "express-rate-limit": "^8.2.1",
64
64
  "openapi-types": "^12.1.3",
65
65
  "prom-client": "^15.1.3",