@commitsage/mcp-server 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/README.md +434 -0
- package/dist/adapters/sse.d.ts +26 -0
- package/dist/adapters/sse.d.ts.map +1 -0
- package/dist/adapters/sse.js +45 -0
- package/dist/adapters/sse.js.map +1 -0
- package/dist/auth/jwt.d.ts +70 -0
- package/dist/auth/jwt.d.ts.map +1 -0
- package/dist/auth/jwt.js +171 -0
- package/dist/auth/jwt.js.map +1 -0
- package/dist/auth/oauth.d.ts +71 -0
- package/dist/auth/oauth.d.ts.map +1 -0
- package/dist/auth/oauth.js +213 -0
- package/dist/auth/oauth.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/models/errors.d.ts +34 -0
- package/dist/models/errors.d.ts.map +1 -0
- package/dist/models/errors.js +67 -0
- package/dist/models/errors.js.map +1 -0
- package/dist/models/types.d.ts +39 -0
- package/dist/models/types.d.ts.map +1 -0
- package/dist/models/types.js +9 -0
- package/dist/models/types.js.map +1 -0
- package/dist/server/mcpServer.d.ts +11 -0
- package/dist/server/mcpServer.d.ts.map +1 -0
- package/dist/server/mcpServer.js +216 -0
- package/dist/server/mcpServer.js.map +1 -0
- package/dist/server/tools.d.ts +93 -0
- package/dist/server/tools.d.ts.map +1 -0
- package/dist/server/tools.js +272 -0
- package/dist/server/tools.js.map +1 -0
- package/dist/services/aiService.d.ts +12 -0
- package/dist/services/aiService.d.ts.map +1 -0
- package/dist/services/aiService.js +86 -0
- package/dist/services/aiService.js.map +1 -0
- package/dist/services/baseAIService.d.ts +47 -0
- package/dist/services/baseAIService.d.ts.map +1 -0
- package/dist/services/baseAIService.js +153 -0
- package/dist/services/baseAIService.js.map +1 -0
- package/dist/services/codestralService.d.ts +7 -0
- package/dist/services/codestralService.d.ts.map +1 -0
- package/dist/services/codestralService.js +49 -0
- package/dist/services/codestralService.js.map +1 -0
- package/dist/services/geminiService.d.ts +18 -0
- package/dist/services/geminiService.d.ts.map +1 -0
- package/dist/services/geminiService.js +139 -0
- package/dist/services/geminiService.js.map +1 -0
- package/dist/services/gitBlameAnalyzer.d.ts +15 -0
- package/dist/services/gitBlameAnalyzer.d.ts.map +1 -0
- package/dist/services/gitBlameAnalyzer.js +135 -0
- package/dist/services/gitBlameAnalyzer.js.map +1 -0
- package/dist/services/gitService.d.ts +54 -0
- package/dist/services/gitService.d.ts.map +1 -0
- package/dist/services/gitService.js +394 -0
- package/dist/services/gitService.js.map +1 -0
- package/dist/services/ollamaService.d.ts +7 -0
- package/dist/services/ollamaService.d.ts.map +1 -0
- package/dist/services/ollamaService.js +43 -0
- package/dist/services/ollamaService.js.map +1 -0
- package/dist/services/openaiService.d.ts +9 -0
- package/dist/services/openaiService.d.ts.map +1 -0
- package/dist/services/openaiService.js +69 -0
- package/dist/services/openaiService.js.map +1 -0
- package/dist/services/promptService.d.ts +10 -0
- package/dist/services/promptService.d.ts.map +1 -0
- package/dist/services/promptService.js +136 -0
- package/dist/services/promptService.js.map +1 -0
- package/dist/utils/config.d.ts +27 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +80 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/httpUtils.d.ts +33 -0
- package/dist/utils/httpUtils.d.ts.map +1 -0
- package/dist/utils/httpUtils.js +54 -0
- package/dist/utils/httpUtils.js.map +1 -0
- package/dist/utils/logger.d.ts +14 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +59 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/retryUtils.d.ts +29 -0
- package/dist/utils/retryUtils.d.ts.map +1 -0
- package/dist/utils/retryUtils.js +49 -0
- package/dist/utils/retryUtils.js.map +1 -0
- package/dist/utils/textProcessing.d.ts +8 -0
- package/dist/utils/textProcessing.d.ts.map +1 -0
- package/dist/utils/textProcessing.js +10 -0
- package/dist/utils/textProcessing.js.map +1 -0
- package/package.json +47 -0
package/dist/auth/jwt.js
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JWT Token Management for MCP Authentication
|
|
3
|
+
*/
|
|
4
|
+
import { Logger } from '../utils/logger.js';
|
|
5
|
+
/**
|
|
6
|
+
* JWT Service for token generation and validation
|
|
7
|
+
* Note: In production, use a proper JWT library like 'jsonwebtoken'
|
|
8
|
+
* This is a simplified implementation for demonstration
|
|
9
|
+
*/
|
|
10
|
+
export class JWTService {
|
|
11
|
+
secret;
|
|
12
|
+
accessTokenExpiry = 3600; // 1 hour
|
|
13
|
+
refreshTokenExpiry = 604800; // 7 days
|
|
14
|
+
constructor(secret) {
|
|
15
|
+
if (!secret || secret.length < 32) {
|
|
16
|
+
throw new Error('JWT secret must be at least 32 characters long');
|
|
17
|
+
}
|
|
18
|
+
this.secret = secret;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Generate access and refresh tokens
|
|
22
|
+
*/
|
|
23
|
+
generateTokenPair(user) {
|
|
24
|
+
const now = Math.floor(Date.now() / 1000);
|
|
25
|
+
const accessPayload = {
|
|
26
|
+
userId: user.id,
|
|
27
|
+
email: user.email,
|
|
28
|
+
name: user.name,
|
|
29
|
+
provider: user.provider,
|
|
30
|
+
iat: now,
|
|
31
|
+
exp: now + this.accessTokenExpiry,
|
|
32
|
+
};
|
|
33
|
+
const refreshPayload = {
|
|
34
|
+
userId: user.id,
|
|
35
|
+
email: user.email,
|
|
36
|
+
name: user.name,
|
|
37
|
+
provider: user.provider,
|
|
38
|
+
iat: now,
|
|
39
|
+
exp: now + this.refreshTokenExpiry,
|
|
40
|
+
};
|
|
41
|
+
const accessToken = this.encode(accessPayload);
|
|
42
|
+
const refreshToken = this.encode(refreshPayload);
|
|
43
|
+
Logger.log(`Generated token pair for user: ${user.email}`);
|
|
44
|
+
return {
|
|
45
|
+
accessToken,
|
|
46
|
+
refreshToken,
|
|
47
|
+
expiresIn: this.accessTokenExpiry,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Validate and decode token
|
|
52
|
+
*/
|
|
53
|
+
validateToken(token) {
|
|
54
|
+
try {
|
|
55
|
+
const payload = this.decode(token);
|
|
56
|
+
if (!payload) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
// Check expiration
|
|
60
|
+
const now = Math.floor(Date.now() / 1000);
|
|
61
|
+
if (payload.exp < now) {
|
|
62
|
+
Logger.warn('Token expired');
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
return payload;
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
Logger.error('Token validation failed:', error);
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Refresh access token using refresh token
|
|
74
|
+
*/
|
|
75
|
+
refreshAccessToken(refreshToken) {
|
|
76
|
+
const payload = this.validateToken(refreshToken);
|
|
77
|
+
if (!payload) {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
// Generate new access token
|
|
81
|
+
const now = Math.floor(Date.now() / 1000);
|
|
82
|
+
const newPayload = {
|
|
83
|
+
...payload,
|
|
84
|
+
iat: now,
|
|
85
|
+
exp: now + this.accessTokenExpiry,
|
|
86
|
+
};
|
|
87
|
+
return this.encode(newPayload);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Encode payload to JWT token (simplified implementation)
|
|
91
|
+
* In production, use a proper library like 'jsonwebtoken'
|
|
92
|
+
*/
|
|
93
|
+
encode(payload) {
|
|
94
|
+
const header = {
|
|
95
|
+
alg: 'HS256',
|
|
96
|
+
typ: 'JWT',
|
|
97
|
+
};
|
|
98
|
+
const encodedHeader = this.base64UrlEncode(JSON.stringify(header));
|
|
99
|
+
const encodedPayload = this.base64UrlEncode(JSON.stringify(payload));
|
|
100
|
+
const signature = this.sign(`${encodedHeader}.${encodedPayload}`);
|
|
101
|
+
return `${encodedHeader}.${encodedPayload}.${signature}`;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Decode JWT token (simplified implementation)
|
|
105
|
+
*/
|
|
106
|
+
decode(token) {
|
|
107
|
+
const parts = token.split('.');
|
|
108
|
+
if (parts.length !== 3) {
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
const [encodedHeader, encodedPayload, signature] = parts;
|
|
112
|
+
// Verify signature
|
|
113
|
+
const expectedSignature = this.sign(`${encodedHeader}.${encodedPayload}`);
|
|
114
|
+
if (signature !== expectedSignature) {
|
|
115
|
+
Logger.warn('Invalid token signature');
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
// Decode payload
|
|
119
|
+
try {
|
|
120
|
+
const payloadJson = this.base64UrlDecode(encodedPayload);
|
|
121
|
+
return JSON.parse(payloadJson);
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
Logger.error('Failed to decode token payload:', error);
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Create signature for token
|
|
130
|
+
*/
|
|
131
|
+
sign(data) {
|
|
132
|
+
// In production, use crypto.createHmac('sha256', secret)
|
|
133
|
+
// This is a simplified implementation
|
|
134
|
+
const crypto = require('crypto');
|
|
135
|
+
const hmac = crypto.createHmac('sha256', this.secret);
|
|
136
|
+
hmac.update(data);
|
|
137
|
+
return this.base64UrlEncode(hmac.digest('base64'));
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Base64 URL encode
|
|
141
|
+
*/
|
|
142
|
+
base64UrlEncode(str) {
|
|
143
|
+
return Buffer.from(str)
|
|
144
|
+
.toString('base64')
|
|
145
|
+
.replace(/\+/g, '-')
|
|
146
|
+
.replace(/\//g, '_')
|
|
147
|
+
.replace(/=/g, '');
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Base64 URL decode
|
|
151
|
+
*/
|
|
152
|
+
base64UrlDecode(str) {
|
|
153
|
+
let base64 = str.replace(/-/g, '+').replace(/_/g, '/');
|
|
154
|
+
// Add padding
|
|
155
|
+
while (base64.length % 4) {
|
|
156
|
+
base64 += '=';
|
|
157
|
+
}
|
|
158
|
+
return Buffer.from(base64, 'base64').toString('utf-8');
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Create JWT service from environment variables
|
|
163
|
+
*/
|
|
164
|
+
export function createJWTServiceFromEnv() {
|
|
165
|
+
const secret = process.env.JWT_SECRET;
|
|
166
|
+
if (!secret) {
|
|
167
|
+
throw new Error('JWT_SECRET environment variable is required');
|
|
168
|
+
}
|
|
169
|
+
return new JWTService(secret);
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=jwt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jwt.js","sourceRoot":"","sources":["../../src/auth/jwt.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth 2.0 Authentication for remote MCP access
|
|
3
|
+
* Supports GitHub and Google OAuth providers
|
|
4
|
+
*/
|
|
5
|
+
export interface OAuthConfig {
|
|
6
|
+
clientId: string;
|
|
7
|
+
clientSecret: string;
|
|
8
|
+
redirectUri: string;
|
|
9
|
+
provider: "github" | "google";
|
|
10
|
+
}
|
|
11
|
+
export interface OAuthTokenResponse {
|
|
12
|
+
access_token: string;
|
|
13
|
+
token_type: string;
|
|
14
|
+
scope?: string;
|
|
15
|
+
expires_in?: number;
|
|
16
|
+
refresh_token?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface OAuthUser {
|
|
19
|
+
id: string;
|
|
20
|
+
email: string;
|
|
21
|
+
name: string;
|
|
22
|
+
provider: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* OAuth 2.0 Authentication Service
|
|
26
|
+
*/
|
|
27
|
+
export declare class OAuthService {
|
|
28
|
+
private config;
|
|
29
|
+
constructor(config: OAuthConfig);
|
|
30
|
+
/**
|
|
31
|
+
* Get authorization URL for OAuth flow
|
|
32
|
+
*/
|
|
33
|
+
getAuthorizationUrl(state: string): string;
|
|
34
|
+
/**
|
|
35
|
+
* Exchange authorization code for access token
|
|
36
|
+
*/
|
|
37
|
+
exchangeCodeForToken(code: string): Promise<OAuthTokenResponse>;
|
|
38
|
+
/**
|
|
39
|
+
* Get user information using access token
|
|
40
|
+
*/
|
|
41
|
+
getUserInfo(accessToken: string): Promise<OAuthUser>;
|
|
42
|
+
/**
|
|
43
|
+
* Refresh access token using refresh token
|
|
44
|
+
*/
|
|
45
|
+
refreshToken(refreshToken: string): Promise<OAuthTokenResponse>;
|
|
46
|
+
/**
|
|
47
|
+
* Get authorization endpoint based on provider
|
|
48
|
+
*/
|
|
49
|
+
private getAuthorizationEndpoint;
|
|
50
|
+
/**
|
|
51
|
+
* Get token endpoint based on provider
|
|
52
|
+
*/
|
|
53
|
+
private getTokenEndpoint;
|
|
54
|
+
/**
|
|
55
|
+
* Get user info endpoint based on provider
|
|
56
|
+
*/
|
|
57
|
+
private getUserInfoEndpoint;
|
|
58
|
+
/**
|
|
59
|
+
* Get default OAuth scope based on provider
|
|
60
|
+
*/
|
|
61
|
+
private getDefaultScope;
|
|
62
|
+
/**
|
|
63
|
+
* Normalize user info from different providers
|
|
64
|
+
*/
|
|
65
|
+
private normalizeUserInfo;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Create OAuth service from environment variables
|
|
69
|
+
*/
|
|
70
|
+
export declare function createOAuthServiceFromEnv(provider: "github" | "google"): OAuthService;
|
|
71
|
+
//# sourceMappingURL=oauth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../../src/auth/oauth.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,QAAQ,GAAG,QAAQ,CAAC;CAC/B;AAED,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAc;gBAEhB,MAAM,EAAE,WAAW;IAK/B;;OAEG;IACH,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAY1C;;OAEG;IACG,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAmCrE;;OAEG;IACG,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAuB1D;;OAEG;IACG,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAiCrE;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAWhC;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAWxB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAW3B;;OAEG;IACH,OAAO,CAAC,eAAe;IAWvB;;OAEG;IACH,OAAO,CAAC,iBAAiB;CAoB1B;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,QAAQ,GAAG,QAAQ,GAC5B,YAAY,CAuBd"}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth 2.0 Authentication for remote MCP access
|
|
3
|
+
* Supports GitHub and Google OAuth providers
|
|
4
|
+
*/
|
|
5
|
+
import { Logger } from "../utils/logger.js";
|
|
6
|
+
/**
|
|
7
|
+
* OAuth 2.0 Authentication Service
|
|
8
|
+
*/
|
|
9
|
+
export class OAuthService {
|
|
10
|
+
config;
|
|
11
|
+
constructor(config) {
|
|
12
|
+
this.config = config;
|
|
13
|
+
Logger.log(`OAuth service initialized for provider: ${config.provider}`);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Get authorization URL for OAuth flow
|
|
17
|
+
*/
|
|
18
|
+
getAuthorizationUrl(state) {
|
|
19
|
+
const params = new URLSearchParams({
|
|
20
|
+
client_id: this.config.clientId,
|
|
21
|
+
redirect_uri: this.config.redirectUri,
|
|
22
|
+
state,
|
|
23
|
+
scope: this.getDefaultScope(),
|
|
24
|
+
});
|
|
25
|
+
const authUrl = this.getAuthorizationEndpoint();
|
|
26
|
+
return `${authUrl}?${params.toString()}`;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Exchange authorization code for access token
|
|
30
|
+
*/
|
|
31
|
+
async exchangeCodeForToken(code) {
|
|
32
|
+
const tokenUrl = this.getTokenEndpoint();
|
|
33
|
+
const params = new URLSearchParams({
|
|
34
|
+
client_id: this.config.clientId,
|
|
35
|
+
client_secret: this.config.clientSecret,
|
|
36
|
+
code,
|
|
37
|
+
redirect_uri: this.config.redirectUri,
|
|
38
|
+
grant_type: "authorization_code",
|
|
39
|
+
});
|
|
40
|
+
try {
|
|
41
|
+
const response = await fetch(tokenUrl, {
|
|
42
|
+
method: "POST",
|
|
43
|
+
headers: {
|
|
44
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
45
|
+
Accept: "application/json",
|
|
46
|
+
},
|
|
47
|
+
body: params.toString(),
|
|
48
|
+
});
|
|
49
|
+
if (!response.ok) {
|
|
50
|
+
const error = await response.text();
|
|
51
|
+
throw new Error(`Token exchange failed: ${error}`);
|
|
52
|
+
}
|
|
53
|
+
const data = (await response.json());
|
|
54
|
+
Logger.log("Successfully exchanged code for token");
|
|
55
|
+
return data;
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
Logger.error("Failed to exchange code for token:", error);
|
|
59
|
+
throw error;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Get user information using access token
|
|
64
|
+
*/
|
|
65
|
+
async getUserInfo(accessToken) {
|
|
66
|
+
const userInfoUrl = this.getUserInfoEndpoint();
|
|
67
|
+
try {
|
|
68
|
+
const response = await fetch(userInfoUrl, {
|
|
69
|
+
headers: {
|
|
70
|
+
Authorization: `Bearer ${accessToken}`,
|
|
71
|
+
Accept: "application/json",
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
if (!response.ok) {
|
|
75
|
+
throw new Error(`Failed to get user info: ${response.statusText}`);
|
|
76
|
+
}
|
|
77
|
+
const data = await response.json();
|
|
78
|
+
return this.normalizeUserInfo(data);
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
Logger.error("Failed to get user info:", error);
|
|
82
|
+
throw error;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Refresh access token using refresh token
|
|
87
|
+
*/
|
|
88
|
+
async refreshToken(refreshToken) {
|
|
89
|
+
const tokenUrl = this.getTokenEndpoint();
|
|
90
|
+
const params = new URLSearchParams({
|
|
91
|
+
client_id: this.config.clientId,
|
|
92
|
+
client_secret: this.config.clientSecret,
|
|
93
|
+
refresh_token: refreshToken,
|
|
94
|
+
grant_type: "refresh_token",
|
|
95
|
+
});
|
|
96
|
+
try {
|
|
97
|
+
const response = await fetch(tokenUrl, {
|
|
98
|
+
method: "POST",
|
|
99
|
+
headers: {
|
|
100
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
101
|
+
Accept: "application/json",
|
|
102
|
+
},
|
|
103
|
+
body: params.toString(),
|
|
104
|
+
});
|
|
105
|
+
if (!response.ok) {
|
|
106
|
+
throw new Error(`Token refresh failed: ${response.statusText}`);
|
|
107
|
+
}
|
|
108
|
+
const data = (await response.json());
|
|
109
|
+
Logger.log("Successfully refreshed token");
|
|
110
|
+
return data;
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
Logger.error("Failed to refresh token:", error);
|
|
114
|
+
throw error;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Get authorization endpoint based on provider
|
|
119
|
+
*/
|
|
120
|
+
getAuthorizationEndpoint() {
|
|
121
|
+
switch (this.config.provider) {
|
|
122
|
+
case "github":
|
|
123
|
+
return "https://github.com/login/oauth/authorize";
|
|
124
|
+
case "google":
|
|
125
|
+
return "https://accounts.google.com/o/oauth2/v2/auth";
|
|
126
|
+
default:
|
|
127
|
+
throw new Error(`Unknown provider: ${this.config.provider}`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Get token endpoint based on provider
|
|
132
|
+
*/
|
|
133
|
+
getTokenEndpoint() {
|
|
134
|
+
switch (this.config.provider) {
|
|
135
|
+
case "github":
|
|
136
|
+
return "https://github.com/login/oauth/access_token";
|
|
137
|
+
case "google":
|
|
138
|
+
return "https://oauth2.googleapis.com/token";
|
|
139
|
+
default:
|
|
140
|
+
throw new Error(`Unknown provider: ${this.config.provider}`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Get user info endpoint based on provider
|
|
145
|
+
*/
|
|
146
|
+
getUserInfoEndpoint() {
|
|
147
|
+
switch (this.config.provider) {
|
|
148
|
+
case "github":
|
|
149
|
+
return "https://api.github.com/user";
|
|
150
|
+
case "google":
|
|
151
|
+
return "https://www.googleapis.com/oauth2/v2/userinfo";
|
|
152
|
+
default:
|
|
153
|
+
throw new Error(`Unknown provider: ${this.config.provider}`);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Get default OAuth scope based on provider
|
|
158
|
+
*/
|
|
159
|
+
getDefaultScope() {
|
|
160
|
+
switch (this.config.provider) {
|
|
161
|
+
case "github":
|
|
162
|
+
return "read:user user:email";
|
|
163
|
+
case "google":
|
|
164
|
+
return "openid email profile";
|
|
165
|
+
default:
|
|
166
|
+
return "";
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Normalize user info from different providers
|
|
171
|
+
*/
|
|
172
|
+
normalizeUserInfo(data) {
|
|
173
|
+
switch (this.config.provider) {
|
|
174
|
+
case "github":
|
|
175
|
+
return {
|
|
176
|
+
id: String(data.id),
|
|
177
|
+
email: data.email,
|
|
178
|
+
name: data.name || data.login,
|
|
179
|
+
provider: "github",
|
|
180
|
+
};
|
|
181
|
+
case "google":
|
|
182
|
+
return {
|
|
183
|
+
id: data.id,
|
|
184
|
+
email: data.email,
|
|
185
|
+
name: data.name,
|
|
186
|
+
provider: "google",
|
|
187
|
+
};
|
|
188
|
+
default:
|
|
189
|
+
throw new Error(`Unknown provider: ${this.config.provider}`);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Create OAuth service from environment variables
|
|
195
|
+
*/
|
|
196
|
+
export function createOAuthServiceFromEnv(provider) {
|
|
197
|
+
const clientIdKey = provider === "github" ? "GITHUB_CLIENT_ID" : "GOOGLE_CLIENT_ID";
|
|
198
|
+
const clientSecretKey = provider === "github" ? "GITHUB_CLIENT_SECRET" : "GOOGLE_CLIENT_SECRET";
|
|
199
|
+
const redirectUriKey = provider === "github" ? "GITHUB_REDIRECT_URI" : "GOOGLE_REDIRECT_URI";
|
|
200
|
+
const clientId = process.env[clientIdKey];
|
|
201
|
+
const clientSecret = process.env[clientSecretKey];
|
|
202
|
+
const redirectUri = process.env[redirectUriKey] || `${process.env.BASE_URL}/auth/callback`;
|
|
203
|
+
if (!clientId || !clientSecret) {
|
|
204
|
+
throw new Error(`Missing OAuth configuration for ${provider}`);
|
|
205
|
+
}
|
|
206
|
+
return new OAuthService({
|
|
207
|
+
clientId,
|
|
208
|
+
clientSecret,
|
|
209
|
+
redirectUri,
|
|
210
|
+
provider,
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
//# sourceMappingURL=oauth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth.js","sourceRoot":"","sources":["../../src/auth/oauth.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;GAGG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* CommitSage MCP Server
|
|
4
|
+
* Main entry point
|
|
5
|
+
*/
|
|
6
|
+
import { CommitSageMCPServer } from './server/mcpServer.js';
|
|
7
|
+
import { Logger } from './utils/logger.js';
|
|
8
|
+
async function main() {
|
|
9
|
+
try {
|
|
10
|
+
const server = new CommitSageMCPServer();
|
|
11
|
+
await server.start();
|
|
12
|
+
}
|
|
13
|
+
catch (error) {
|
|
14
|
+
Logger.error('Fatal error starting server:', error);
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
main();
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;GAGG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C,KAAK,UAAU,IAAI;IACjB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,mBAAmB,EAAE,CAAC;QACzC,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom error classes for MCP server
|
|
3
|
+
*/
|
|
4
|
+
export declare class GitExtensionNotFoundError extends Error {
|
|
5
|
+
constructor();
|
|
6
|
+
}
|
|
7
|
+
export declare class NoRepositoriesFoundError extends Error {
|
|
8
|
+
constructor();
|
|
9
|
+
}
|
|
10
|
+
export declare class NoChangesDetectedError extends Error {
|
|
11
|
+
constructor();
|
|
12
|
+
}
|
|
13
|
+
export declare class NoRepositorySelectedError extends Error {
|
|
14
|
+
constructor();
|
|
15
|
+
}
|
|
16
|
+
export declare class UserCancelledError extends Error {
|
|
17
|
+
constructor(message?: string);
|
|
18
|
+
}
|
|
19
|
+
export declare class ApiKeyInvalidError extends Error {
|
|
20
|
+
constructor(provider: string);
|
|
21
|
+
}
|
|
22
|
+
export declare class InvalidRepositoryPathError extends Error {
|
|
23
|
+
constructor(path: string, reason?: string);
|
|
24
|
+
}
|
|
25
|
+
export declare class GitCommandError extends Error {
|
|
26
|
+
constructor(command: string, exitCode: number, stderr: string);
|
|
27
|
+
}
|
|
28
|
+
export declare class AIServiceError extends Error {
|
|
29
|
+
constructor(provider: string, message: string);
|
|
30
|
+
}
|
|
31
|
+
export declare class TimeoutError extends Error {
|
|
32
|
+
constructor(operation: string, timeoutMs: number);
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/models/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,qBAAa,yBAA0B,SAAQ,KAAK;;CAKnD;AAED,qBAAa,wBAAyB,SAAQ,KAAK;;CAKlD;AAED,qBAAa,sBAAuB,SAAQ,KAAK;;CAKhD;AAED,qBAAa,yBAA0B,SAAQ,KAAK;;CAKnD;AAED,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,OAAO,GAAE,MAAsC;CAI5D;AAED,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,QAAQ,EAAE,MAAM;CAI7B;AAED,qBAAa,0BAA2B,SAAQ,KAAK;gBACvC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM;CAO1C;AAED,qBAAa,eAAgB,SAAQ,KAAK;gBAC5B,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAM9D;AAED,qBAAa,cAAe,SAAQ,KAAK;gBAC3B,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAI9C;AAED,qBAAa,YAAa,SAAQ,KAAK;gBACzB,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;CAIjD"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom error classes for MCP server
|
|
3
|
+
*/
|
|
4
|
+
export class GitExtensionNotFoundError extends Error {
|
|
5
|
+
constructor() {
|
|
6
|
+
super("Git is not installed or not found in PATH");
|
|
7
|
+
this.name = "GitExtensionNotFoundError";
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export class NoRepositoriesFoundError extends Error {
|
|
11
|
+
constructor() {
|
|
12
|
+
super("No Git repositories found");
|
|
13
|
+
this.name = "NoRepositoriesFoundError";
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export class NoChangesDetectedError extends Error {
|
|
17
|
+
constructor() {
|
|
18
|
+
super("No changes detected in the repository");
|
|
19
|
+
this.name = "NoChangesDetectedError";
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export class NoRepositorySelectedError extends Error {
|
|
23
|
+
constructor() {
|
|
24
|
+
super("No repository selected");
|
|
25
|
+
this.name = "NoRepositorySelectedError";
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export class UserCancelledError extends Error {
|
|
29
|
+
constructor(message = "Operation cancelled by user") {
|
|
30
|
+
super(message);
|
|
31
|
+
this.name = "UserCancelledError";
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export class ApiKeyInvalidError extends Error {
|
|
35
|
+
constructor(provider) {
|
|
36
|
+
super(`Invalid or expired API key for ${provider}`);
|
|
37
|
+
this.name = "ApiKeyInvalidError";
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export class InvalidRepositoryPathError extends Error {
|
|
41
|
+
constructor(path, reason) {
|
|
42
|
+
const message = reason
|
|
43
|
+
? `Invalid repository path: ${path}. Reason: ${reason}`
|
|
44
|
+
: `Invalid repository path: ${path}`;
|
|
45
|
+
super(message);
|
|
46
|
+
this.name = "InvalidRepositoryPathError";
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
export class GitCommandError extends Error {
|
|
50
|
+
constructor(command, exitCode, stderr) {
|
|
51
|
+
super(`Git command failed: ${command}\nExit code: ${exitCode}\nError: ${stderr}`);
|
|
52
|
+
this.name = "GitCommandError";
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
export class AIServiceError extends Error {
|
|
56
|
+
constructor(provider, message) {
|
|
57
|
+
super(`AI Service error (${provider}): ${message}`);
|
|
58
|
+
this.name = "AIServiceError";
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
export class TimeoutError extends Error {
|
|
62
|
+
constructor(operation, timeoutMs) {
|
|
63
|
+
super(`Operation timed out: ${operation} (timeout: ${timeoutMs}ms)`);
|
|
64
|
+
this.name = "TimeoutError";
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/models/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,OAAO,yBAA0B,SAAQ,KAAK;IAClD;QACE,KAAK,CAAC,2CAA2C,CAAC,CAAC;QACnD,IAAI,CAAC,IAAI,GAAG,2BAA2B,CAAC;IAC1C,CAAC;CACF;AAED,MAAM,OAAO,wBAAyB,SAAQ,KAAK;IACjD;QACE,KAAK,CAAC,2BAA2B,CAAC,CAAC;QACnC,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAC;IACzC,CAAC;CACF;AAED,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAC/C;QACE,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAC/C,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACvC,CAAC;CACF;AAED,MAAM,OAAO,yBAA0B,SAAQ,KAAK;IAClD;QACE,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAChC,IAAI,CAAC,IAAI,GAAG,2BAA2B,CAAC;IAC1C,CAAC;CACF;AAED,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAC3C,YAAY,UAAkB,6BAA6B;QACzD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AAED,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAC3C,YAAY,QAAgB;QAC1B,KAAK,CAAC,kCAAkC,QAAQ,EAAE,CAAC,CAAC;QACpD,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AAED,MAAM,OAAO,0BAA2B,SAAQ,KAAK;IACnD,YAAY,IAAY,EAAE,MAAe;QACvC,MAAM,OAAO,GAAG,MAAM;YACpB,CAAC,CAAC,4BAA4B,IAAI,aAAa,MAAM,EAAE;YACvD,CAAC,CAAC,4BAA4B,IAAI,EAAE,CAAC;QACvC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAC;IAC3C,CAAC;CACF;AAED,MAAM,OAAO,eAAgB,SAAQ,KAAK;IACxC,YAAY,OAAe,EAAE,QAAgB,EAAE,MAAc;QAC3D,KAAK,CACH,uBAAuB,OAAO,gBAAgB,QAAQ,YAAY,MAAM,EAAE,CAC3E,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AAED,MAAM,OAAO,cAAe,SAAQ,KAAK;IACvC,YAAY,QAAgB,EAAE,OAAe;QAC3C,KAAK,CAAC,qBAAqB,QAAQ,MAAM,OAAO,EAAE,CAAC,CAAC;QACpD,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AAED,MAAM,OAAO,YAAa,SAAQ,KAAK;IACrC,YAAY,SAAiB,EAAE,SAAiB;QAC9C,KAAK,CAAC,wBAAwB,SAAS,cAAc,SAAS,KAAK,CAAC,CAAC;QACrE,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;IAC7B,CAAC;CACF"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definitions for MCP server
|
|
3
|
+
*/
|
|
4
|
+
export interface CommitMessage {
|
|
5
|
+
message: string;
|
|
6
|
+
model: string;
|
|
7
|
+
}
|
|
8
|
+
export interface ProgressReporter {
|
|
9
|
+
report(value: {
|
|
10
|
+
message?: string;
|
|
11
|
+
increment?: number;
|
|
12
|
+
}): void;
|
|
13
|
+
}
|
|
14
|
+
export interface IAIService {
|
|
15
|
+
generateCommitMessage(prompt: string, progress: ProgressReporter, attempt?: number): Promise<CommitMessage>;
|
|
16
|
+
}
|
|
17
|
+
export interface GitDiffOptions {
|
|
18
|
+
repoPath: string;
|
|
19
|
+
onlyStaged?: boolean;
|
|
20
|
+
}
|
|
21
|
+
export interface CommitMessageOptions {
|
|
22
|
+
repoPath: string;
|
|
23
|
+
provider?: string;
|
|
24
|
+
format?: string;
|
|
25
|
+
language?: string;
|
|
26
|
+
onlyStaged?: boolean;
|
|
27
|
+
customInstructions?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface AnalyzeChangesOptions {
|
|
30
|
+
repoPath: string;
|
|
31
|
+
onlyStaged?: boolean;
|
|
32
|
+
}
|
|
33
|
+
export declare class NoopProgressReporter implements ProgressReporter {
|
|
34
|
+
report(_value: {
|
|
35
|
+
message?: string;
|
|
36
|
+
increment?: number;
|
|
37
|
+
}): void;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/models/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,KAAK,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAC/D;AAED,MAAM,WAAW,UAAU;IACzB,qBAAqB,CACnB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,aAAa,CAAC,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,qBAAa,oBAAqB,YAAW,gBAAgB;IAC3D,MAAM,CAAC,MAAM,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;CAG/D"}
|