gitlab-mcp-agent-server 0.2.4 → 0.2.6
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.
|
@@ -61,7 +61,7 @@ class GitLabOAuthManager {
|
|
|
61
61
|
return this.waitForTokenFromOtherProcess(lockFilePath);
|
|
62
62
|
}
|
|
63
63
|
async waitForTokenFromOtherProcess(lockFilePath) {
|
|
64
|
-
const maxWaitMs =
|
|
64
|
+
const maxWaitMs = 15 * 1000;
|
|
65
65
|
const pollMs = 1000;
|
|
66
66
|
let elapsed = 0;
|
|
67
67
|
console.error('OAuth flow is already running in another process for this instance. Waiting for token...');
|
|
@@ -86,7 +86,7 @@ class GitLabOAuthManager {
|
|
|
86
86
|
await sleep(pollMs);
|
|
87
87
|
elapsed += pollMs;
|
|
88
88
|
}
|
|
89
|
-
throw new Error(
|
|
89
|
+
throw new Error(`Timed out waiting for OAuth token from another process. Complete OAuth in the first window or remove stale lock: ${lockFilePath}`);
|
|
90
90
|
}
|
|
91
91
|
async refreshToken(refreshToken) {
|
|
92
92
|
this.assertOAuthClientCredentials();
|
|
@@ -124,6 +124,7 @@ class GitLabOAuthManager {
|
|
|
124
124
|
authorizeUrl.searchParams.set('state', state);
|
|
125
125
|
const localEntryUrl = `${redirect.protocol}//${redirect.host}/`;
|
|
126
126
|
const code = await new Promise((resolve, reject) => {
|
|
127
|
+
let settled = false;
|
|
127
128
|
const server = (0, node_http_1.createServer)((req, res) => {
|
|
128
129
|
if (!req.url) {
|
|
129
130
|
return;
|
|
@@ -155,6 +156,7 @@ class GitLabOAuthManager {
|
|
|
155
156
|
actionLabel: 'Start OAuth Again'
|
|
156
157
|
}));
|
|
157
158
|
server.close();
|
|
159
|
+
settled = true;
|
|
158
160
|
reject(new Error(`OAuth authorization failed: ${error}`));
|
|
159
161
|
return;
|
|
160
162
|
}
|
|
@@ -170,6 +172,7 @@ class GitLabOAuthManager {
|
|
|
170
172
|
actionLabel: 'Start OAuth Again'
|
|
171
173
|
}));
|
|
172
174
|
server.close();
|
|
175
|
+
settled = true;
|
|
173
176
|
reject(new Error('Invalid OAuth callback: code/state mismatch.'));
|
|
174
177
|
return;
|
|
175
178
|
}
|
|
@@ -182,9 +185,11 @@ class GitLabOAuthManager {
|
|
|
182
185
|
hint: 'This tab can be closed now.'
|
|
183
186
|
}));
|
|
184
187
|
server.close();
|
|
188
|
+
settled = true;
|
|
185
189
|
resolve(authCode);
|
|
186
190
|
});
|
|
187
191
|
server.on('error', (error) => {
|
|
192
|
+
settled = true;
|
|
188
193
|
reject(new Error(`OAuth callback server failed on ${redirect.hostname}:${resolvePort(redirect)}: ${error.message}`));
|
|
189
194
|
});
|
|
190
195
|
server.listen(resolvePort(redirect), redirect.hostname, () => {
|
|
@@ -196,6 +201,14 @@ class GitLabOAuthManager {
|
|
|
196
201
|
console.error(authorizeUrl.toString());
|
|
197
202
|
}
|
|
198
203
|
});
|
|
204
|
+
const timeoutMs = this.options.callbackTimeoutMs ?? 180_000;
|
|
205
|
+
setTimeout(() => {
|
|
206
|
+
if (settled) {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
server.close();
|
|
210
|
+
reject(new Error(`OAuth was not completed in time. Open ${localEntryUrl} to continue, or use ${authorizeUrl.toString()}`));
|
|
211
|
+
}, timeoutMs);
|
|
199
212
|
});
|
|
200
213
|
const tokenResponse = await fetch(`${this.oauthBaseUrl}/oauth/token`, {
|
|
201
214
|
method: 'POST',
|
|
@@ -28,6 +28,7 @@ function createMcpServer() {
|
|
|
28
28
|
scopes: config.gitlab.oauth.scopes,
|
|
29
29
|
bootstrapAccessToken: config.gitlab.accessToken,
|
|
30
30
|
tokenStorePath: config.gitlab.oauth.tokenStorePath,
|
|
31
|
+
callbackTimeoutMs: config.gitlab.oauth.callbackTimeoutMs,
|
|
31
32
|
autoLogin: config.gitlab.oauth.autoLogin,
|
|
32
33
|
openBrowser: config.gitlab.oauth.openBrowser
|
|
33
34
|
})
|
|
@@ -15,6 +15,7 @@ const EnvSchema = zod_1.z.object({
|
|
|
15
15
|
GITLAB_OAUTH_REDIRECT_URI: zod_1.z.string().optional(),
|
|
16
16
|
GITLAB_OAUTH_SCOPES: zod_1.z.string().default('api'),
|
|
17
17
|
GITLAB_OAUTH_TOKEN_STORE_PATH: zod_1.z.string().optional(),
|
|
18
|
+
GITLAB_OAUTH_CALLBACK_TIMEOUT_MS: zod_1.z.coerce.number().int().positive().optional(),
|
|
18
19
|
GITLAB_OAUTH_AUTO_LOGIN: zod_1.z
|
|
19
20
|
.enum(['true', 'false'])
|
|
20
21
|
.optional()
|
|
@@ -68,6 +69,7 @@ function loadConfig() {
|
|
|
68
69
|
redirectUri: env.GITLAB_OAUTH_REDIRECT_URI,
|
|
69
70
|
scopes: splitCsv(env.GITLAB_OAUTH_SCOPES),
|
|
70
71
|
tokenStorePath: defaultTokenStorePath,
|
|
72
|
+
callbackTimeoutMs: env.GITLAB_OAUTH_CALLBACK_TIMEOUT_MS ?? 180_000,
|
|
71
73
|
autoLogin: env.GITLAB_OAUTH_AUTO_LOGIN,
|
|
72
74
|
openBrowser: env.GITLAB_OAUTH_OPEN_BROWSER
|
|
73
75
|
},
|
package/docs/USER_GUIDE.md
CHANGED
|
@@ -60,6 +60,7 @@ export GITLAB_AUTH_MODE="oauth";
|
|
|
60
60
|
export GITLAB_OAUTH_CLIENT_ID="<GITLAB_COM_APP_ID>";
|
|
61
61
|
export GITLAB_OAUTH_CLIENT_SECRET="<GITLAB_COM_APP_SECRET>";
|
|
62
62
|
export GITLAB_OAUTH_REDIRECT_URI="http://127.0.0.1:8787/oauth/callback";
|
|
63
|
+
export GITLAB_OAUTH_CALLBACK_TIMEOUT_MS="180000";
|
|
63
64
|
export GITLAB_OAUTH_AUTO_LOGIN="true";
|
|
64
65
|
export GITLAB_OAUTH_OPEN_BROWSER="true";
|
|
65
66
|
|
|
@@ -77,6 +78,7 @@ export GITLAB_AUTH_MODE="oauth";
|
|
|
77
78
|
export GITLAB_OAUTH_CLIENT_ID="<WORK_APP_ID>";
|
|
78
79
|
export GITLAB_OAUTH_CLIENT_SECRET="<WORK_APP_SECRET>";
|
|
79
80
|
export GITLAB_OAUTH_REDIRECT_URI="http://127.0.0.1:8788/oauth/callback";
|
|
81
|
+
export GITLAB_OAUTH_CALLBACK_TIMEOUT_MS="180000";
|
|
80
82
|
export GITLAB_OAUTH_AUTO_LOGIN="true";
|
|
81
83
|
export GITLAB_OAUTH_OPEN_BROWSER="true";
|
|
82
84
|
|
|
@@ -121,6 +123,8 @@ npx -y gitlab-mcp-agent-server
|
|
|
121
123
|
2. Ограничь права файла:
|
|
122
124
|
- `chmod 600 /home/<user>/.config/gitlab-mcp/gitlab.com/token.json`
|
|
123
125
|
3. Для headless окружений ставь `GITLAB_OAUTH_OPEN_BROWSER=false`.
|
|
126
|
+
4. При медленном интерактивном flow увеличь окно ожидания callback:
|
|
127
|
+
- `GITLAB_OAUTH_CALLBACK_TIMEOUT_MS=180000` (или выше).
|
|
124
128
|
|
|
125
129
|
## 7. Сценарий пользовательского запроса
|
|
126
130
|
|
|
@@ -168,6 +172,11 @@ npx -y gitlab-mcp-agent-server
|
|
|
168
172
|
3. Если lock застрял после краша, удали stale lock:
|
|
169
173
|
- `<tokenStorePath>.oauth.lock`
|
|
170
174
|
|
|
175
|
+
`gitlab_list_issues`/другой tool уходит в timeout после удаления token:
|
|
176
|
+
1. Проверь stale lock и удали его:
|
|
177
|
+
- `rm -f ~/.config/gitlab-mcp/<gitlab-host>/token.json.oauth.lock`
|
|
178
|
+
2. Повтори запрос и заверши OAuth в браузере в течение окна авторизации.
|
|
179
|
+
|
|
171
180
|
## 10. Advanced (необязательно)
|
|
172
181
|
|
|
173
182
|
Если нужен тонкий контроль, можно использовать:
|