cleanup mcp server too

This commit is contained in:
Mateusz Burzyński
2026-01-08 11:21:23 +01:00
parent 2bd12b9553
commit 317ebd3431
3 changed files with 125 additions and 131 deletions
+114 -112
View File
@@ -126416,7 +126416,7 @@ async function startMcpHttpServer(ctx) {
const url2 = `http://${host}:${port}${endpoint2}`;
return {
url: url2,
close: async () => {
[Symbol.asyncDispose]: async () => {
await server.stop();
}
};
@@ -126556,120 +126556,125 @@ var Inputs = type({
...keyInputDefs
});
async function main(inputs) {
var _stack = [];
var _stack2 = [];
try {
const timer = new Timer();
const installationToken = __using(_stack, await setupGitHubInstallationToken(), true);
let mcpServerClose;
const tokenRef = __using(_stack2, await setupGitHubInstallationToken(), true);
let payload;
try {
payload = parsePayload(inputs);
Inputs.assert(inputs);
setupGitConfig();
const [githubSetup, sharedTempDir] = await Promise.all([
initializeGitHub(installationToken.token),
createTempDirectory()
]);
timer.checkpoint("githubSetup");
const agent2 = resolveAgent({
inputs,
payload,
repoSettings: githubSetup.repoSettings
});
const resolvedPayload = { ...payload, agent: agent2.name };
const apiKeySetup = validateApiKey({
agent: agent2,
inputs,
owner: githubSetup.owner,
name: githubSetup.name
});
if (!apiKeySetup.success) {
await reportErrorToComment({ error: apiKeySetup.error });
return { success: false, error: apiKeySetup.error };
}
const toolState = {};
const [cliPath] = await Promise.all([
installAgentCli({ agent: agent2, token: installationToken.token }),
setupGitAuth({
token: installationToken.token,
var _stack = [];
try {
payload = parsePayload(inputs);
Inputs.assert(inputs);
setupGitConfig();
const [githubSetup, sharedTempDir] = await Promise.all([
initializeGitHub(tokenRef.token),
createTempDirectory()
]);
timer.checkpoint("githubSetup");
const agent2 = resolveAgent({
inputs,
payload,
repoSettings: githubSetup.repoSettings
});
const resolvedPayload = { ...payload, agent: agent2.name };
const apiKeySetup = validateApiKey({
agent: agent2,
inputs,
owner: githubSetup.owner,
name: githubSetup.name
});
if (!apiKeySetup.success) {
await reportErrorToComment({ error: apiKeySetup.error });
return { success: false, error: apiKeySetup.error };
}
const toolState = {};
const [cliPath] = await Promise.all([
installAgentCli({ agent: agent2, token: tokenRef.token }),
setupGitAuth({
token: tokenRef.token,
owner: githubSetup.owner,
name: githubSetup.name,
payload: resolvedPayload,
octokit: githubSetup.octokit,
toolState
})
]);
timer.checkpoint("agentSetup+gitAuth");
const computedModes = [
...getModes({
disableProgressComment: resolvedPayload.disableProgressComment
}),
...resolvedPayload.modes || []
];
const runId = process.env.GITHUB_RUN_ID || "";
if (runId) {
const workflowRunInfo = await fetchWorkflowRunInfo(runId);
if (workflowRunInfo.progressCommentId) {
process.env.PULLFROG_PROGRESS_COMMENT_ID = workflowRunInfo.progressCommentId;
log.info(`\u{1F4DD} Using pre-created progress comment: ${workflowRunInfo.progressCommentId}`);
}
}
let jobId;
const jobName = process.env.GITHUB_JOB;
if (jobName && runId) {
const jobs = await githubSetup.octokit.rest.actions.listJobsForWorkflowRun({
owner: githubSetup.owner,
repo: githubSetup.name,
run_id: parseInt(runId, 10)
});
const matchingJob = jobs.data.jobs.find((job) => job.name === jobName);
if (matchingJob) {
jobId = String(matchingJob.id);
log.info(`\u{1F4CB} Found job ID: ${jobId}`);
}
}
const toolContext = {
owner: githubSetup.owner,
name: githubSetup.name,
payload: resolvedPayload,
githubInstallationToken: tokenRef.token,
octokit: githubSetup.octokit,
toolState
})
]);
timer.checkpoint("agentSetup+gitAuth");
const computedModes = [
...getModes({
disableProgressComment: resolvedPayload.disableProgressComment
}),
...resolvedPayload.modes || []
];
const runId = process.env.GITHUB_RUN_ID || "";
if (runId) {
const workflowRunInfo = await fetchWorkflowRunInfo(runId);
if (workflowRunInfo.progressCommentId) {
process.env.PULLFROG_PROGRESS_COMMENT_ID = workflowRunInfo.progressCommentId;
log.info(`\u{1F4DD} Using pre-created progress comment: ${workflowRunInfo.progressCommentId}`);
}
}
let jobId;
const jobName = process.env.GITHUB_JOB;
if (jobName && runId) {
const jobs = await githubSetup.octokit.rest.actions.listJobsForWorkflowRun({
owner: githubSetup.owner,
repo: githubSetup.name,
run_id: parseInt(runId, 10)
});
const matchingJob = jobs.data.jobs.find((job) => job.name === jobName);
if (matchingJob) {
jobId = String(matchingJob.id);
log.info(`\u{1F4CB} Found job ID: ${jobId}`);
}
}
const toolContext = {
owner: githubSetup.owner,
name: githubSetup.name,
githubInstallationToken: installationToken.token,
octokit: githubSetup.octokit,
payload: resolvedPayload,
repo: githubSetup.repo,
repoSettings: githubSetup.repoSettings,
modes: computedModes,
toolState,
agent: agent2,
sharedTempDir,
runId,
jobId
};
const { url: mcpServerUrl, close: mcpServerCloseFunc } = await startMcpHttpServer(toolContext);
mcpServerClose = mcpServerCloseFunc;
log.info(`\u{1F680} MCP server started at ${mcpServerUrl}`);
const mcpServers = createMcpConfigs(mcpServerUrl);
log.debug(`\u{1F4CB} MCP Config: ${JSON.stringify(mcpServers, null, 2)}`);
timer.checkpoint("mcpServer");
const ctx = {
...toolContext,
inputs,
mcpServerUrl,
mcpServerClose: mcpServerCloseFunc,
mcpServers,
cliPath,
apiKey: apiKeySetup.apiKey,
apiKeys: apiKeySetup.apiKeys
};
if (ctx.payload.event.trigger === "fix_review" && Array.isArray(ctx.payload.event.comment_ids) && ctx.payload.event.comment_ids.length === 0) {
const noThumbsMessage = `\u{1F44D} **No approved comments found**
payload: resolvedPayload,
repo: githubSetup.repo,
repoSettings: githubSetup.repoSettings,
modes: computedModes,
toolState,
agent: agent2,
sharedTempDir,
runId,
jobId
};
const mcpHttpServer = __using(_stack, await startMcpHttpServer(toolContext), true);
log.info(`\u{1F680} MCP server started at ${mcpHttpServer.url}`);
const mcpServers = createMcpConfigs(mcpHttpServer.url);
log.debug(`\u{1F4CB} MCP Config: ${JSON.stringify(mcpServers, null, 2)}`);
timer.checkpoint("mcpServer");
const ctx = {
...toolContext,
inputs,
mcpServerUrl: mcpHttpServer.url,
mcpServers,
cliPath,
apiKey: apiKeySetup.apiKey,
apiKeys: apiKeySetup.apiKeys
};
if (ctx.payload.event.trigger === "fix_review" && Array.isArray(ctx.payload.event.comment_ids) && ctx.payload.event.comment_ids.length === 0) {
const noThumbsMessage = `\u{1F44D} **No approved comments found**
To use "Fix \u{1F44D}s", add a \u{1F44D} reaction to one or more inline review comments you want fixed.`;
log.error(noThumbsMessage);
await reportProgress(ctx, { body: noThumbsMessage });
return { success: true };
log.error(noThumbsMessage);
await reportProgress(ctx, { body: noThumbsMessage });
return { success: true };
}
const result = await runAgent(ctx);
const mainResult = await handleAgentResult(result);
return mainResult;
} catch (_) {
var _error = _, _hasError = true;
} finally {
var _promise2 = __callDispose(_stack, _error, _hasError);
_promise2 && await _promise2;
}
const result = await runAgent(ctx);
const mainResult = await handleAgentResult(result);
return mainResult;
} catch (error41) {
const errorMessage = error41 instanceof Error ? error41.message : "Unknown error occurred";
log.error(errorMessage);
@@ -126687,15 +126692,12 @@ To use "Fix \u{1F44D}s", add a \u{1F44D} reaction to one or more inline review c
await ensureProgressCommentUpdated(payload);
} catch {
}
if (mcpServerClose) {
await mcpServerClose();
}
}
} catch (_) {
var _error = _, _hasError = true;
} catch (_2) {
var _error2 = _2, _hasError2 = true;
} finally {
var _promise2 = __callDispose(_stack, _error, _hasError);
_promise2 && await _promise2;
var _promise3 = __callDispose(_stack2, _error2, _hasError2);
_promise3 && await _promise3;
}
}
function agentHasApiKeys(agent2, inputs) {
+9 -17
View File
@@ -66,8 +66,7 @@ type ApiKeySetup =
export async function main(inputs: Inputs): Promise<MainResult> {
const timer = new Timer();
await using installationToken = await setupGitHubInstallationToken();
let mcpServerClose: (() => Promise<void>) | undefined;
await using tokenRef = await setupGitHubInstallationToken();
let payload: Payload | undefined;
try {
@@ -78,7 +77,7 @@ export async function main(inputs: Inputs): Promise<MainResult> {
// phase 2: fast setup (github + temp dir)
const [githubSetup, sharedTempDir] = await Promise.all([
initializeGitHub(installationToken.token),
initializeGitHub(tokenRef.token),
createTempDirectory(),
]);
timer.checkpoint("githubSetup");
@@ -106,9 +105,9 @@ export async function main(inputs: Inputs): Promise<MainResult> {
// phase 5: parallel long-running operations (agent install + git auth)
const toolState: ToolState = {};
const [cliPath] = await Promise.all([
installAgentCli({ agent, token: installationToken.token }),
installAgentCli({ agent, token: tokenRef.token }),
setupGitAuth({
token: installationToken.token,
token: tokenRef.token,
owner: githubSetup.owner,
name: githubSetup.name,
payload: resolvedPayload,
@@ -155,7 +154,7 @@ export async function main(inputs: Inputs): Promise<MainResult> {
const toolContext: ToolContext = {
owner: githubSetup.owner,
name: githubSetup.name,
githubInstallationToken: installationToken.token,
githubInstallationToken: tokenRef.token,
octokit: githubSetup.octokit,
payload: resolvedPayload,
repo: githubSetup.repo,
@@ -168,11 +167,10 @@ export async function main(inputs: Inputs): Promise<MainResult> {
jobId,
};
const { url: mcpServerUrl, close: mcpServerCloseFunc } = await startMcpHttpServer(toolContext);
mcpServerClose = mcpServerCloseFunc;
log.info(`🚀 MCP server started at ${mcpServerUrl}`);
await using mcpHttpServer = await startMcpHttpServer(toolContext);
log.info(`🚀 MCP server started at ${mcpHttpServer.url}`);
const mcpServers = createMcpConfigs(mcpServerUrl);
const mcpServers = createMcpConfigs(mcpHttpServer.url);
log.debug(`📋 MCP Config: ${JSON.stringify(mcpServers, null, 2)}`);
timer.checkpoint("mcpServer");
@@ -180,8 +178,7 @@ export async function main(inputs: Inputs): Promise<MainResult> {
const ctx: AgentContext = {
...toolContext,
inputs,
mcpServerUrl,
mcpServerClose: mcpServerCloseFunc,
mcpServerUrl: mcpHttpServer.url,
mcpServers,
cliPath,
apiKey: apiKeySetup.apiKey,
@@ -224,10 +221,6 @@ export async function main(inputs: Inputs): Promise<MainResult> {
} catch {
// error updating comment, but don't let it mask the original error
}
if (mcpServerClose) {
await mcpServerClose();
}
}
}
@@ -319,7 +312,6 @@ export interface ToolContext {
export interface AgentContext extends Readonly<ToolContext> {
readonly inputs: Inputs;
readonly mcpServerUrl: string;
readonly mcpServerClose: () => Promise<void>;
readonly mcpServers: ReturnType<typeof createMcpConfigs>;
readonly cliPath: string;
readonly apiKey: string;
+2 -2
View File
@@ -64,7 +64,7 @@ async function findAvailablePort(startPort: number): Promise<number> {
*/
export async function startMcpHttpServer(
ctx: ToolContext
): Promise<{ url: string; close: () => Promise<void> }> {
): Promise<{ url: string; [Symbol.asyncDispose]: () => Promise<void> }> {
const server = new FastMCP({
name: ghPullfrogMcpName,
version: "0.0.1",
@@ -119,7 +119,7 @@ export async function startMcpHttpServer(
return {
url,
close: async () => {
[Symbol.asyncDispose]: async () => {
await server.stop();
},
};