@perfai/mcp 1.0.24

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.
Files changed (108) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +352 -0
  3. package/dist/auth/authManager.d.ts +83 -0
  4. package/dist/auth/authManager.d.ts.map +1 -0
  5. package/dist/auth/authManager.js +555 -0
  6. package/dist/auth/sessionCache.d.ts +5 -0
  7. package/dist/auth/sessionCache.d.ts.map +1 -0
  8. package/dist/auth/sessionCache.js +29 -0
  9. package/dist/auth/sessionStorage.d.ts +53 -0
  10. package/dist/auth/sessionStorage.d.ts.map +1 -0
  11. package/dist/auth/sessionStorage.js +234 -0
  12. package/dist/auth/types.d.ts +28 -0
  13. package/dist/auth/types.d.ts.map +1 -0
  14. package/dist/auth/types.js +1 -0
  15. package/dist/config.d.ts +65 -0
  16. package/dist/config.d.ts.map +1 -0
  17. package/dist/config.js +74 -0
  18. package/dist/server.d.ts +3 -0
  19. package/dist/server.d.ts.map +1 -0
  20. package/dist/server.js +144 -0
  21. package/dist/setup-config.d.ts +4 -0
  22. package/dist/setup-config.d.ts.map +1 -0
  23. package/dist/setup-config.js +69 -0
  24. package/dist/tools/index.d.ts +361 -0
  25. package/dist/tools/index.d.ts.map +1 -0
  26. package/dist/tools/index.js +275 -0
  27. package/dist/tools/protected/aiFixDesignIssue.d.ts +17 -0
  28. package/dist/tools/protected/aiFixDesignIssue.d.ts.map +1 -0
  29. package/dist/tools/protected/aiFixDesignIssue.js +205 -0
  30. package/dist/tools/protected/aiFixQualityIssue.d.ts +17 -0
  31. package/dist/tools/protected/aiFixQualityIssue.d.ts.map +1 -0
  32. package/dist/tools/protected/aiFixQualityIssue.js +188 -0
  33. package/dist/tools/protected/aiFixSecurityIssue.d.ts +17 -0
  34. package/dist/tools/protected/aiFixSecurityIssue.d.ts.map +1 -0
  35. package/dist/tools/protected/aiFixSecurityIssue.js +205 -0
  36. package/dist/tools/protected/checkDesignFixes.d.ts +17 -0
  37. package/dist/tools/protected/checkDesignFixes.d.ts.map +1 -0
  38. package/dist/tools/protected/checkDesignFixes.js +199 -0
  39. package/dist/tools/protected/checkQualityFixes.d.ts +17 -0
  40. package/dist/tools/protected/checkQualityFixes.d.ts.map +1 -0
  41. package/dist/tools/protected/checkQualityFixes.js +199 -0
  42. package/dist/tools/protected/checkSecurityFixes.d.ts +17 -0
  43. package/dist/tools/protected/checkSecurityFixes.d.ts.map +1 -0
  44. package/dist/tools/protected/checkSecurityFixes.js +177 -0
  45. package/dist/tools/protected/listApis.d.ts +28 -0
  46. package/dist/tools/protected/listApis.d.ts.map +1 -0
  47. package/dist/tools/protected/listApis.js +102 -0
  48. package/dist/tools/protected/logout.d.ts +11 -0
  49. package/dist/tools/protected/logout.d.ts.map +1 -0
  50. package/dist/tools/protected/logout.js +22 -0
  51. package/dist/tools/protected/manageOrganizations.d.ts +26 -0
  52. package/dist/tools/protected/manageOrganizations.d.ts.map +1 -0
  53. package/dist/tools/protected/manageOrganizations.js +147 -0
  54. package/dist/tools/protected/runDesignTest.d.ts +21 -0
  55. package/dist/tools/protected/runDesignTest.d.ts.map +1 -0
  56. package/dist/tools/protected/runDesignTest.js +132 -0
  57. package/dist/tools/protected/runQualityTest.d.ts +21 -0
  58. package/dist/tools/protected/runQualityTest.d.ts.map +1 -0
  59. package/dist/tools/protected/runQualityTest.js +150 -0
  60. package/dist/tools/protected/runSecurityTest.d.ts +21 -0
  61. package/dist/tools/protected/runSecurityTest.d.ts.map +1 -0
  62. package/dist/tools/protected/runSecurityTest.js +107 -0
  63. package/dist/tools/protected/selectApi.d.ts +24 -0
  64. package/dist/tools/protected/selectApi.d.ts.map +1 -0
  65. package/dist/tools/protected/selectApi.js +172 -0
  66. package/dist/tools/protected/setup.d.ts +11 -0
  67. package/dist/tools/protected/setup.d.ts.map +1 -0
  68. package/dist/tools/protected/setup.js +151 -0
  69. package/dist/tools/protected/showDesignIssues.d.ts +38 -0
  70. package/dist/tools/protected/showDesignIssues.d.ts.map +1 -0
  71. package/dist/tools/protected/showDesignIssues.js +201 -0
  72. package/dist/tools/protected/showFixedIssues.d.ts +11 -0
  73. package/dist/tools/protected/showFixedIssues.d.ts.map +1 -0
  74. package/dist/tools/protected/showFixedIssues.js +36 -0
  75. package/dist/tools/protected/showQualityIssues.d.ts +33 -0
  76. package/dist/tools/protected/showQualityIssues.d.ts.map +1 -0
  77. package/dist/tools/protected/showQualityIssues.js +225 -0
  78. package/dist/tools/protected/showSecurityIssues.d.ts +47 -0
  79. package/dist/tools/protected/showSecurityIssues.d.ts.map +1 -0
  80. package/dist/tools/protected/showSecurityIssues.js +212 -0
  81. package/dist/tools/protected/summarizeIssues.d.ts +11 -0
  82. package/dist/tools/protected/summarizeIssues.d.ts.map +1 -0
  83. package/dist/tools/protected/summarizeIssues.js +161 -0
  84. package/dist/tools/protected/userInfo.d.ts +11 -0
  85. package/dist/tools/protected/userInfo.d.ts.map +1 -0
  86. package/dist/tools/protected/userInfo.js +21 -0
  87. package/dist/tools/protected/visionAiAppLearning.d.ts +37 -0
  88. package/dist/tools/protected/visionAiAppLearning.d.ts.map +1 -0
  89. package/dist/tools/protected/visionAiAppLearning.js +122 -0
  90. package/dist/tools/public/authStatus.d.ts +11 -0
  91. package/dist/tools/public/authStatus.d.ts.map +1 -0
  92. package/dist/tools/public/authStatus.js +78 -0
  93. package/dist/tools/public/login.d.ts +12 -0
  94. package/dist/tools/public/login.d.ts.map +1 -0
  95. package/dist/tools/public/login.js +230 -0
  96. package/dist/types/api.d.ts +12 -0
  97. package/dist/types/api.d.ts.map +1 -0
  98. package/dist/types/api.js +1 -0
  99. package/dist/utils/dockerRunner.d.ts +44 -0
  100. package/dist/utils/dockerRunner.d.ts.map +1 -0
  101. package/dist/utils/dockerRunner.js +300 -0
  102. package/dist/utils/formatters.d.ts +14 -0
  103. package/dist/utils/formatters.d.ts.map +1 -0
  104. package/dist/utils/formatters.js +510 -0
  105. package/dist/utils/promptBuilder.d.ts +4 -0
  106. package/dist/utils/promptBuilder.d.ts.map +1 -0
  107. package/dist/utils/promptBuilder.js +132 -0
  108. package/package.json +67 -0
@@ -0,0 +1,234 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import * as os from 'os';
4
+ import { createHash, createCipheriv, createDecipheriv, randomBytes } from 'crypto';
5
+ /**
6
+ * Secure session storage for MCP PerfAI server
7
+ * Handles persistent storage of authentication sessions with encryption
8
+ */
9
+ export class SessionStorage {
10
+ storageDir;
11
+ sessionFile;
12
+ keyFile;
13
+ encryptionKey = null;
14
+ constructor(appName = 'mcp-perfai') {
15
+ // Use OS-specific config directory for npm package compatibility
16
+ this.storageDir = this.getConfigDirectory(appName);
17
+ this.sessionFile = path.join(this.storageDir, 'session.enc');
18
+ this.keyFile = path.join(this.storageDir, 'session.key');
19
+ this.ensureStorageDirectory();
20
+ this.initializeEncryptionKey();
21
+ }
22
+ /**
23
+ * Get OS-specific configuration directory
24
+ */
25
+ getConfigDirectory(appName) {
26
+ const platform = os.platform();
27
+ let configDir;
28
+ switch (platform) {
29
+ case 'win32':
30
+ configDir = path.join(os.homedir(), 'AppData', 'Local', appName);
31
+ break;
32
+ case 'darwin':
33
+ configDir = path.join(os.homedir(), 'Library', 'Application Support', appName);
34
+ break;
35
+ default: // linux and others
36
+ configDir = path.join(os.homedir(), '.config', appName);
37
+ break;
38
+ }
39
+ return configDir;
40
+ }
41
+ /**
42
+ * Ensure storage directory exists
43
+ */
44
+ ensureStorageDirectory() {
45
+ try {
46
+ if (!fs.existsSync(this.storageDir)) {
47
+ fs.mkdirSync(this.storageDir, { recursive: true, mode: 0o700 });
48
+ }
49
+ }
50
+ catch (error) {
51
+ console.error('Failed to create storage directory:', error);
52
+ throw new Error('Cannot initialize session storage');
53
+ }
54
+ }
55
+ /**
56
+ * Initialize or load encryption key
57
+ */
58
+ initializeEncryptionKey() {
59
+ try {
60
+ if (fs.existsSync(this.keyFile)) {
61
+ // Load existing key
62
+ this.encryptionKey = fs.readFileSync(this.keyFile, 'utf8').trim();
63
+ }
64
+ else {
65
+ // Generate new key
66
+ this.encryptionKey = randomBytes(32).toString('hex');
67
+ fs.writeFileSync(this.keyFile, this.encryptionKey, { mode: 0o600 });
68
+ }
69
+ }
70
+ catch (error) {
71
+ console.error('Failed to initialize encryption key:', error);
72
+ // Fall back to in-memory key (less secure but functional)
73
+ this.encryptionKey = randomBytes(32).toString('hex');
74
+ }
75
+ }
76
+ /**
77
+ * Encrypt data using AES-256-CBC
78
+ */
79
+ encrypt(data) {
80
+ try {
81
+ if (!this.encryptionKey) {
82
+ throw new Error('Encryption key not available');
83
+ }
84
+ const algorithm = 'aes-256-cbc';
85
+ const iv = randomBytes(16);
86
+ const key = createHash('sha256').update(this.encryptionKey).digest();
87
+ const cipher = createCipheriv(algorithm, key, iv);
88
+ let encrypted = cipher.update(data, 'utf8', 'hex');
89
+ encrypted += cipher.final('hex');
90
+ return iv.toString('hex') + ':' + encrypted;
91
+ }
92
+ catch (error) {
93
+ console.error('Encryption failed:', error);
94
+ throw new Error('Failed to encrypt session data');
95
+ }
96
+ }
97
+ /**
98
+ * Decrypt data using AES-256-CBC
99
+ */
100
+ decrypt(encryptedData) {
101
+ try {
102
+ if (!this.encryptionKey) {
103
+ throw new Error('Encryption key not available');
104
+ }
105
+ const algorithm = 'aes-256-cbc';
106
+ const parts = encryptedData.split(':');
107
+ if (parts.length !== 2) {
108
+ throw new Error('Invalid encrypted data format');
109
+ }
110
+ const iv = Buffer.from(parts[0], 'hex');
111
+ const encrypted = parts[1];
112
+ const key = createHash('sha256').update(this.encryptionKey).digest();
113
+ const decipher = createDecipheriv(algorithm, key, iv);
114
+ let decrypted = decipher.update(encrypted, 'hex', 'utf8');
115
+ decrypted += decipher.final('utf8');
116
+ return decrypted;
117
+ }
118
+ catch (error) {
119
+ console.error('Decryption failed:', error);
120
+ throw new Error('Failed to decrypt session data');
121
+ }
122
+ }
123
+ /**
124
+ * Save session to persistent storage
125
+ */
126
+ async saveSession(session) {
127
+ try {
128
+ // Add metadata for validation
129
+ const sessionData = {
130
+ version: '1.0.0',
131
+ savedAt: Date.now(),
132
+ session: {
133
+ ...session,
134
+ // Convert Date objects to timestamps for JSON serialization
135
+ fixedIssues: session.fixedIssues?.map(issue => ({
136
+ ...issue,
137
+ fixedAt: issue.fixedAt instanceof Date ? issue.fixedAt.getTime() : issue.fixedAt
138
+ }))
139
+ }
140
+ };
141
+ const jsonData = JSON.stringify(sessionData, null, 2);
142
+ const encryptedData = this.encrypt(jsonData);
143
+ fs.writeFileSync(this.sessionFile, encryptedData, { mode: 0o600 });
144
+ console.error('💾 Session saved successfully');
145
+ }
146
+ catch (error) {
147
+ console.error('❌ Failed to save session:', error);
148
+ // Don't throw - allow app to continue without persistence
149
+ }
150
+ }
151
+ /**
152
+ * Load session from persistent storage
153
+ */
154
+ async loadSession() {
155
+ try {
156
+ if (!fs.existsSync(this.sessionFile)) {
157
+ console.error('📂 No saved session found');
158
+ return null;
159
+ }
160
+ const encryptedData = fs.readFileSync(this.sessionFile, 'utf8');
161
+ const jsonData = this.decrypt(encryptedData);
162
+ const sessionData = JSON.parse(jsonData);
163
+ // Validate session format and version
164
+ if (!sessionData.version || !sessionData.session) {
165
+ console.error('⚠️ Invalid session format, clearing storage');
166
+ this.clearSession();
167
+ return null;
168
+ }
169
+ const session = sessionData.session;
170
+ // Check if session is expired
171
+ if (Date.now() >= session.expiresAt) {
172
+ console.error('⏰ Saved session has expired, clearing storage');
173
+ this.clearSession();
174
+ return null;
175
+ }
176
+ // Restore Date objects
177
+ if (session.fixedIssues) {
178
+ session.fixedIssues = session.fixedIssues.map(issue => ({
179
+ ...issue,
180
+ fixedAt: new Date(issue.fixedAt)
181
+ }));
182
+ }
183
+ const timeLeft = Math.round((session.expiresAt - Date.now()) / (1000 * 60 * 60));
184
+ console.error(`✅ Session loaded successfully, expires in ${timeLeft} hours`);
185
+ return session;
186
+ }
187
+ catch (error) {
188
+ console.error('❌ Failed to load session:', error);
189
+ // Clear corrupted session
190
+ this.clearSession();
191
+ return null;
192
+ }
193
+ }
194
+ /**
195
+ * Clear stored session
196
+ */
197
+ clearSession() {
198
+ try {
199
+ if (fs.existsSync(this.sessionFile)) {
200
+ fs.unlinkSync(this.sessionFile);
201
+ console.error('🗑️ Session storage cleared');
202
+ }
203
+ }
204
+ catch (error) {
205
+ console.error('❌ Failed to clear session storage:', error);
206
+ }
207
+ }
208
+ /**
209
+ * Check if session exists and is valid
210
+ */
211
+ hasValidSession() {
212
+ try {
213
+ if (!fs.existsSync(this.sessionFile)) {
214
+ return false;
215
+ }
216
+ const encryptedData = fs.readFileSync(this.sessionFile, 'utf8');
217
+ const jsonData = this.decrypt(encryptedData);
218
+ const sessionData = JSON.parse(jsonData);
219
+ if (!sessionData.session?.expiresAt) {
220
+ return false;
221
+ }
222
+ return Date.now() < sessionData.session.expiresAt;
223
+ }
224
+ catch (error) {
225
+ return false;
226
+ }
227
+ }
228
+ /**
229
+ * Get session storage location (for debugging)
230
+ */
231
+ getStorageLocation() {
232
+ return this.storageDir;
233
+ }
234
+ }
@@ -0,0 +1,28 @@
1
+ import { ApiCatalog, ApiSelection } from '../types/api.js';
2
+ export interface FixedIssue {
3
+ issueId: string;
4
+ issue: any;
5
+ fixedAt: Date;
6
+ prompt: string;
7
+ status: "ai-fixed" | "pending-validation";
8
+ }
9
+ export interface UserSession {
10
+ accessToken: string;
11
+ idToken: string;
12
+ tokenType: string;
13
+ userInfo: any;
14
+ expiresAt: number;
15
+ organizations?: any[];
16
+ selectedOrgId?: string;
17
+ selectedApiId?: string;
18
+ selectedApiData?: ApiCatalog;
19
+ selectedApiIdentifier?: ApiSelection;
20
+ selectedSecurityAppId?: string;
21
+ selectedDesignAppId?: string;
22
+ selectedQualityAppId?: string;
23
+ fixedIssues?: FixedIssue[];
24
+ fixedDesignIssues?: FixedIssue[];
25
+ fixedQualityIssues?: FixedIssue[];
26
+ appSequenceMap?: Map<number, string>;
27
+ }
28
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/auth/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAG3D,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,GAAG,CAAC;IACX,OAAO,EAAE,IAAI,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,UAAU,GAAG,oBAAoB,CAAC;CAC3C;AAGD,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,GAAG,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,GAAG,EAAE,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,UAAU,CAAC;IAC7B,qBAAqB,CAAC,EAAE,YAAY,CAAC;IACrC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B,iBAAiB,CAAC,EAAE,UAAU,EAAE,CAAC;IACjC,kBAAkB,CAAC,EAAE,UAAU,EAAE,CAAC;IAClC,cAAc,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACtC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,65 @@
1
+ export declare const SERVER_INFO: {
2
+ name: string;
3
+ version: string;
4
+ };
5
+ export declare const AUTH0_DOMAIN: string;
6
+ export declare const CLIENT_ID: string;
7
+ export declare const CLIENT_SECRET: string;
8
+ export declare const REDIRECT_URI: string;
9
+ export declare const API_ENDPOINTS: {
10
+ readonly TOKEN: `https://${string}/oauth/token`;
11
+ readonly USERINFO: `https://${string}/userinfo`;
12
+ readonly ORGANIZATIONS: "https://api.perfai.ai/api/v1/org-users/get_users_orgs";
13
+ readonly SECURITY_ISSUES: "https://api.perfai.ai/api/v1/sensitive-data-service/apps/issues/all-by-org";
14
+ readonly SECURITY_ISSUES_BY_APP: "https://api.perfai.ai/api/v1/sensitive-data-service/apps/issues/by-app";
15
+ readonly DESIGN_ISSUES_BY_APP: "https://api.perfai.ai/api/v1/design-analysis-service/apps/org/issues";
16
+ readonly APP_SUMMARY: "https://api.perfai.ai/api/v1/api-catalog/apps/summary";
17
+ readonly QUALITY_ISSUES_BY_APP: "https://api.perfai.ai/api/v1/spec-validation/tests";
18
+ readonly API_CATALOG: "https://api.perfai.ai/api/v1/api-catalog/apps/catalog_id_name_label";
19
+ readonly API_CATALOG_SERVICE_IDS: "https://api.perfai.ai/api/v1/api-catalog/apps/service-ids";
20
+ readonly WEBAPP_API: "https://api.perfai.ai/api/v1";
21
+ readonly DASHBOARD_API: "https://lm.perfai.ai/api/v1";
22
+ readonly DASHBOARD_API_AUTH: string;
23
+ readonly LLM_API: "https://llmservice.dev.perfai.ai/api/tokens";
24
+ readonly LLM_GENERATE_API: "http://localhost:4000/api/generate";
25
+ };
26
+ export declare const DOCKER_HUB: {
27
+ readonly USERNAME: string;
28
+ readonly PAT: string;
29
+ };
30
+ export declare const DOCKER_CONFIG: {
31
+ readonly IMAGE: "mohdrashid1/perfai-agent";
32
+ readonly TIMEOUT: number;
33
+ readonly ENV_VARS: {
34
+ readonly MODE: "LOCAL";
35
+ readonly TASK_TYPE: "PRIVACY";
36
+ readonly AGENT_ID: "MCP_LOCAL_DOCKER_PERFAI_AGENT";
37
+ readonly PERF_CATEGORY_FILE: "perf_categories.csv";
38
+ readonly TEST_CATEGORY_FILE: "test_categories.csv";
39
+ readonly PRIVACY_CATEGORY_FILE: "privacy_categories.csv";
40
+ readonly SPEC_VALIDATION_CATEGORY_FILE: "spec_validation_categories.csv";
41
+ };
42
+ };
43
+ export declare const DOCKER_CONFIG_VISION_AI_APP_LEARNING: {
44
+ readonly IMAGE: "mohdrashid1/vision-ai-agent";
45
+ readonly TIMEOUT: number;
46
+ };
47
+ export declare const DESIGN_DOCKER_CONFIG: {
48
+ readonly IMAGE: "mohdrashid1/perfai-agent";
49
+ readonly TIMEOUT: number;
50
+ readonly ENV_VARS: {
51
+ readonly MODE: "LOCAL";
52
+ readonly TASK_TYPE: "GOVERNANCE";
53
+ readonly AGENT_ID: "MCP_LOCAL_DOCKER_PERFAI_AGENT_DESIGN";
54
+ };
55
+ };
56
+ export declare const QUALITY_DOCKER_CONFIG: {
57
+ readonly IMAGE: "mohdrashid1/perfai-agent";
58
+ readonly TIMEOUT: number;
59
+ readonly ENV_VARS: {
60
+ readonly MODE: "LOCAL";
61
+ readonly TASK_TYPE: "SPEC_VALIDATION";
62
+ readonly AGENT_ID: "MCP_LOCAL_DOCKER_PERFAI_AGENT_QUALITY";
63
+ };
64
+ };
65
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,WAAW;;;CAGvB,CAAC;AAGF,eAAO,MAAM,YAAY,QAAsD,CAAC;AAChF,eAAO,MAAM,SAAS,QAA2E,CAAC;AAElG,eAAO,MAAM,aAAa,QAA+C,CAAC;AAE1E,eAAO,MAAM,YAAY,QAA6D,CAAC;AAGvF,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;CAiBhB,CAAC;AAGX,eAAO,MAAM,UAAU;;;CAGb,CAAC;AAGX,eAAO,MAAM,aAAa;;;;;;;;;;;;CAYhB,CAAC;AAGX,eAAO,MAAM,oCAAoC;;;CAGvC,CAAC;AAGX,eAAO,MAAM,oBAAoB;;;;;;;;CAQvB,CAAC;AAGX,eAAO,MAAM,qBAAqB;;;;;;;;CAQxB,CAAC"}
package/dist/config.js ADDED
@@ -0,0 +1,74 @@
1
+ // Server configuration
2
+ export const SERVER_INFO = {
3
+ name: "mcp-typescript-server",
4
+ version: "1.0.0",
5
+ };
6
+ // Auth0 / PerfAI configuration (override via env / K8s Secret)
7
+ export const AUTH0_DOMAIN = process.env.PERFAI_AUTH0_DOMAIN || "auth.perfai.ai";
8
+ export const CLIENT_ID = process.env.PERFAI_AUTH0_CLIENT_ID || "OxipoJS8EIdpN3KzhVQ280zkKxwzGLfI";
9
+ // Leave empty by default to avoid bundling secrets in source.
10
+ export const CLIENT_SECRET = process.env.PERFAI_AUTH0_CLIENT_SECRET || "";
11
+ export const REDIRECT_URI = process.env.PERFAI_REDIRECT_URI || "http://localhost:5173";
12
+ // API endpoints
13
+ export const API_ENDPOINTS = {
14
+ TOKEN: `https://${AUTH0_DOMAIN}/oauth/token`,
15
+ USERINFO: `https://${AUTH0_DOMAIN}/userinfo`,
16
+ ORGANIZATIONS: 'https://api.perfai.ai/api/v1/org-users/get_users_orgs',
17
+ SECURITY_ISSUES: 'https://api.perfai.ai/api/v1/sensitive-data-service/apps/issues/all-by-org',
18
+ SECURITY_ISSUES_BY_APP: 'https://api.perfai.ai/api/v1/sensitive-data-service/apps/issues/by-app',
19
+ DESIGN_ISSUES_BY_APP: 'https://api.perfai.ai/api/v1/design-analysis-service/apps/org/issues',
20
+ APP_SUMMARY: 'https://api.perfai.ai/api/v1/api-catalog/apps/summary',
21
+ QUALITY_ISSUES_BY_APP: 'https://api.perfai.ai/api/v1/spec-validation/tests',
22
+ API_CATALOG: 'https://api.perfai.ai/api/v1/api-catalog/apps/catalog_id_name_label',
23
+ API_CATALOG_SERVICE_IDS: 'https://api.perfai.ai/api/v1/api-catalog/apps/service-ids',
24
+ WEBAPP_API: 'https://api.perfai.ai/api/v1',
25
+ DASHBOARD_API: 'https://lm.perfai.ai/api/v1',
26
+ // Provide full header value (e.g. "Authorization: Basic <base64>") via env / K8s Secret.
27
+ DASHBOARD_API_AUTH: process.env.PERFAI_DASHBOARD_API_AUTH || '',
28
+ LLM_API: 'https://llmservice.dev.perfai.ai/api/tokens',
29
+ LLM_GENERATE_API: 'http://localhost:4000/api/generate',
30
+ };
31
+ // Docker Hub credentials for pulling private images
32
+ export const DOCKER_HUB = {
33
+ USERNAME: process.env.DOCKER_HUB_USERNAME || 'mohdrashid1',
34
+ PAT: process.env.DOCKER_HUB_PAT || 'dckr_pat_g3sj9rLa0sYrlzT5BmgZS_24vl8',
35
+ };
36
+ // Docker configuration
37
+ export const DOCKER_CONFIG = {
38
+ IMAGE: 'mohdrashid1/perfai-agent',
39
+ TIMEOUT: 30 * 60 * 1000, // 30 minutes
40
+ ENV_VARS: {
41
+ MODE: 'LOCAL',
42
+ TASK_TYPE: 'PRIVACY',
43
+ AGENT_ID: 'MCP_LOCAL_DOCKER_PERFAI_AGENT',
44
+ PERF_CATEGORY_FILE: 'perf_categories.csv',
45
+ TEST_CATEGORY_FILE: 'test_categories.csv',
46
+ PRIVACY_CATEGORY_FILE: 'privacy_categories.csv',
47
+ SPEC_VALIDATION_CATEGORY_FILE: 'spec_validation_categories.csv',
48
+ }
49
+ };
50
+ // Docker configuration for Vision AI App Learning (GENERATE_SPEC / OAS generation)
51
+ export const DOCKER_CONFIG_VISION_AI_APP_LEARNING = {
52
+ IMAGE: 'mohdrashid1/vision-ai-agent',
53
+ TIMEOUT: 45 * 60 * 1000, // 45 minutes (OAS generation can be long)
54
+ };
55
+ // Design-specific Docker configuration (matches extension implementation)
56
+ export const DESIGN_DOCKER_CONFIG = {
57
+ IMAGE: 'mohdrashid1/perfai-agent',
58
+ TIMEOUT: 30 * 60 * 1000, // 30 minutes
59
+ ENV_VARS: {
60
+ MODE: 'LOCAL',
61
+ TASK_TYPE: 'GOVERNANCE', // Design testing uses GOVERNANCE task type
62
+ AGENT_ID: 'MCP_LOCAL_DOCKER_PERFAI_AGENT_DESIGN',
63
+ }
64
+ };
65
+ // Quality-specific Docker configuration (matches extension implementation)
66
+ export const QUALITY_DOCKER_CONFIG = {
67
+ IMAGE: 'mohdrashid1/perfai-agent',
68
+ TIMEOUT: 30 * 60 * 1000, // 30 minutes
69
+ ENV_VARS: {
70
+ MODE: 'LOCAL',
71
+ TASK_TYPE: 'SPEC_VALIDATION', // Quality testing uses SPEC_VALIDATION task type
72
+ AGENT_ID: 'MCP_LOCAL_DOCKER_PERFAI_AGENT_QUALITY',
73
+ }
74
+ };
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":""}
package/dist/server.js ADDED
@@ -0,0 +1,144 @@
1
+ #!/usr/bin/env node
2
+ import dotenv from "dotenv";
3
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
4
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
5
+ import { CallToolRequestSchema, ErrorCode, ListToolsRequestSchema, McpError, } from "@modelcontextprotocol/sdk/types.js";
6
+ dotenv.config();
7
+ // Import configuration and types
8
+ import { SERVER_INFO } from './config.js';
9
+ import { AuthenticationManager } from './auth/authManager.js';
10
+ // Import tool definitions and handlers
11
+ import { PUBLIC_TOOLS, PROTECTED_TOOLS, handleLogin, handleAuthStatus, handleUserInfo, handleLogout, handleSetup, handleShowSecurityIssues, handleShowDesignIssues, handleShowQualityIssues, handleManageOrganizations, handleListApis, handleSelectApi, handleAiFixSecurityIssue, handleAiFixDesignIssue, handleAiFixQualityIssue, handleShowFixedIssues, handleCheckSecurityFixes, handleCheckDesignFixes, handleCheckQualityFixes, handleSummarizeIssues } from './tools/index.js';
12
+ const authManager = new AuthenticationManager();
13
+ // Create the server instance
14
+ const server = new Server(SERVER_INFO, {
15
+ capabilities: {
16
+ tools: { listChanged: true }, // 👈 Enable dynamic tool list updates
17
+ },
18
+ });
19
+ // List tools handler - returns different tools based on authentication status
20
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
21
+ const isAuthenticated = await authManager.isAuthenticated();
22
+ console.error(`🔍 ListTools called - Authenticated: ${isAuthenticated}`);
23
+ // ALWAYS show all tools - authentication is enforced in CallToolRequestSchema
24
+ console.error(`🛠️ Always returning all ${Object.keys(PUBLIC_TOOLS).length + Object.keys(PROTECTED_TOOLS).length} tools`);
25
+ return {
26
+ tools: [...Object.values(PUBLIC_TOOLS), ...Object.values(PROTECTED_TOOLS)],
27
+ };
28
+ });
29
+ // Call tool handler with authentication logic
30
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
31
+ const { name, arguments: args } = request.params;
32
+ try {
33
+ // Handle public tools (authentication tools)
34
+ switch (name) {
35
+ case "login": {
36
+ return await handleLogin(authManager);
37
+ }
38
+ case "auth_status": {
39
+ return await handleAuthStatus(authManager);
40
+ }
41
+ }
42
+ // Check authentication for protected tools
43
+ if (!(await authManager.isAuthenticated())) {
44
+ throw new McpError(ErrorCode.InvalidRequest, `🔐 Authentication required. Please run the 'login' tool first to access '${name}'.`);
45
+ }
46
+ // Handle protected tools (require authentication)
47
+ switch (name) {
48
+ case "user_info": {
49
+ return await handleUserInfo(authManager);
50
+ }
51
+ case "logout": {
52
+ return await handleLogout(authManager);
53
+ }
54
+ case "setup": {
55
+ return await handleSetup(authManager, args);
56
+ }
57
+ case "show_security_issues": {
58
+ return await handleShowSecurityIssues(authManager, args);
59
+ }
60
+ case "show_design_issues": {
61
+ return await handleShowDesignIssues(authManager, args);
62
+ }
63
+ case "show_quality_issues": {
64
+ return await handleShowQualityIssues(authManager, args);
65
+ }
66
+ case "manage_organizations": {
67
+ return await handleManageOrganizations(authManager, args);
68
+ }
69
+ case "list_apps": {
70
+ return await handleListApis(authManager);
71
+ }
72
+ case "select_app": {
73
+ return await handleSelectApi(authManager, args);
74
+ }
75
+ case "ai_fix_security_issue": {
76
+ return await handleAiFixSecurityIssue(authManager, args);
77
+ }
78
+ case "ai_fix_design_issue": {
79
+ return await handleAiFixDesignIssue(authManager, args);
80
+ }
81
+ case "ai_fix_quality_issue": {
82
+ return await handleAiFixQualityIssue(authManager, args);
83
+ }
84
+ case "show_fixed_issues": {
85
+ return await handleShowFixedIssues(authManager);
86
+ }
87
+ case "check_security_fixes": {
88
+ return await handleCheckSecurityFixes(authManager, args);
89
+ }
90
+ case "check_design_fixes": {
91
+ return await handleCheckDesignFixes(authManager, args);
92
+ }
93
+ case "check_quality_fixes": {
94
+ return await handleCheckQualityFixes(authManager, args);
95
+ }
96
+ case "summarize_issues": {
97
+ return await handleSummarizeIssues(authManager);
98
+ }
99
+ default:
100
+ throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
101
+ }
102
+ }
103
+ catch (error) {
104
+ if (error instanceof McpError) {
105
+ throw error;
106
+ }
107
+ throw new McpError(ErrorCode.InternalError, `Tool execution failed: ${error}`);
108
+ }
109
+ });
110
+ // Error handling
111
+ server.onerror = (error) => {
112
+ // Log errors to stderr to avoid interfering with STDIO transport
113
+ console.error("[MCP Error]", error);
114
+ };
115
+ process.on("SIGINT", async () => {
116
+ await server.close();
117
+ process.exit(0);
118
+ });
119
+ // Start the server
120
+ async function main() {
121
+ // Only log to stderr for STDIO transport compatibility
122
+ console.error("🚀 Starting PerfAI MCP TypeScript Server with Authentication...");
123
+ console.error(`🔧 Server: ${SERVER_INFO.name} v${SERVER_INFO.version}`);
124
+ console.error("📋 Public tools:", Object.keys(PUBLIC_TOOLS).join(", "));
125
+ console.error("🔒 Protected tools:", Object.keys(PROTECTED_TOOLS).join(", "));
126
+ console.error("⚠️ Note: Protected tools require authentication via 'login' tool");
127
+ const transport = new StdioServerTransport();
128
+ await server.connect(transport);
129
+ console.error("✅ PerfAI MCP Server is running and ready to accept connections!");
130
+ console.error("🔑 Run 'login' tool to authenticate and access all features");
131
+ }
132
+ // Handle uncaught exceptions
133
+ process.on("uncaughtException", (error) => {
134
+ console.error("Uncaught Exception:", error);
135
+ process.exit(1);
136
+ });
137
+ process.on("unhandledRejection", (reason, promise) => {
138
+ console.error("Unhandled Rejection at:", promise, "reason:", reason);
139
+ process.exit(1);
140
+ });
141
+ main().catch((error) => {
142
+ console.error("Failed to start server:", error);
143
+ process.exit(1);
144
+ });
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ declare function generateConfigFiles(): void;
3
+ export { generateConfigFiles };
4
+ //# sourceMappingURL=setup-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-config.d.ts","sourceRoot":"","sources":["../src/setup-config.ts"],"names":[],"mappings":";AAOA,iBAAS,mBAAmB,SA2D3B;AAUD,OAAO,EAAE,mBAAmB,EAAE,CAAC"}
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env node
2
+ import * as fs from 'fs';
3
+ import * as path from 'path';
4
+ // Generate MCP configuration files
5
+ function generateConfigFiles() {
6
+ const configs = {
7
+ cursor: {
8
+ mcpServers: {
9
+ "perfai-mcp": {
10
+ type: "stdio",
11
+ command: "npx",
12
+ args: ["perfai-mcp-server"],
13
+ env: {
14
+ PERFAI_USERNAME: "your-username-here",
15
+ PERFAI_PASSWORD: "your-password-here"
16
+ }
17
+ }
18
+ }
19
+ },
20
+ vscode: {
21
+ mcpServers: {
22
+ "perfai-mcp": {
23
+ type: "stdio",
24
+ command: "npx",
25
+ args: ["perfai-mcp-server"],
26
+ env: {
27
+ PERFAI_USERNAME: "your-username-here",
28
+ PERFAI_PASSWORD: "your-password-here"
29
+ }
30
+ }
31
+ }
32
+ }
33
+ };
34
+ // Get current working directory
35
+ const currentDir = process.cwd();
36
+ // Generate Cursor config
37
+ const cursorConfigPath = path.join(currentDir, 'cursor_mcp_config.json');
38
+ fs.writeFileSync(cursorConfigPath, JSON.stringify(configs.cursor, null, 2));
39
+ // Generate VS Code config
40
+ const vscodeConfigPath = path.join(currentDir, 'vscode_mcp_config.json');
41
+ fs.writeFileSync(vscodeConfigPath, JSON.stringify(configs.vscode, null, 2));
42
+ console.log('🎉 MCP Configuration files generated successfully!');
43
+ console.log('');
44
+ console.log('📁 Files created:');
45
+ console.log(` • ${cursorConfigPath}`);
46
+ console.log(` • ${vscodeConfigPath}`);
47
+ console.log('');
48
+ console.log('📝 Next steps:');
49
+ console.log('1. Edit the config files and replace the placeholder credentials:');
50
+ console.log(' - Replace "your-username-here" with your PerfAI username');
51
+ console.log(' - Replace "your-password-here" with your PerfAI password');
52
+ console.log('');
53
+ console.log('2. Copy the config to your MCP client:');
54
+ console.log(' • For Cursor: Copy cursor_mcp_config.json to your Cursor config directory');
55
+ console.log(' • For VS Code: Copy vscode_mcp_config.json to your VS Code config directory');
56
+ console.log('');
57
+ console.log('3. Restart your MCP client to load the new configuration');
58
+ console.log('');
59
+ console.log('🔗 Package URL: https://www.npmjs.com/package/perfai-mcp-server');
60
+ }
61
+ // Main execution
62
+ try {
63
+ generateConfigFiles();
64
+ }
65
+ catch (error) {
66
+ console.error('❌ Error generating config files:', error);
67
+ process.exit(1);
68
+ }
69
+ export { generateConfigFiles };