switch to http mcp

This commit is contained in:
David Blass
2025-11-26 13:51:22 -05:00
parent c8cbda6972
commit 5d88bfce42
12 changed files with 76138 additions and 110389 deletions
+5 -35
View File
@@ -2,48 +2,18 @@
* Simple MCP configuration helper for adding our minimal GitHub comment server
*/
import type { McpStdioServerConfig } from "@anthropic-ai/claude-agent-sdk";
import { fromHere } from "@ark/fs";
import type { Payload } from "../external.ts";
import type { McpHttpServerConfig } from "@anthropic-ai/claude-agent-sdk";
import { ghPullfrogMcpName } from "../external.ts";
import type { Mode } from "../modes.ts";
import { parseRepoContext } from "../utils/github.ts";
export type McpName = typeof ghPullfrogMcpName;
export type McpConfigs = Record<McpName, McpStdioServerConfig>;
export function createMcpConfigs(
githubInstallationToken: string,
modes: Mode[],
payload: Payload
): McpConfigs {
const repoContext = parseRepoContext();
const githubRepository = `${repoContext.owner}/${repoContext.name}`;
// In production (GitHub Actions), mcp-server is in same directory as entry.js (where this is bundled)
// In development, server.ts is in the same directory as this file (config.ts)
const serverPath = process.env.GITHUB_ACTIONS ? fromHere("mcp-server") : fromHere("server.ts");
const env: Record<string, string> = {
GITHUB_INSTALLATION_TOKEN: githubInstallationToken,
GITHUB_REPOSITORY: githubRepository,
PULLFROG_MODES: JSON.stringify(modes),
PULLFROG_PAYLOAD: JSON.stringify(payload),
PULLFROG_TEMP_DIR: process.env.PULLFROG_TEMP_DIR!,
};
// pass through GITHUB_RUN_ID if available (automatically set in GitHub Actions)
// this is used to build the "View workflow run" link in comments
if (process.env.GITHUB_RUN_ID) {
env.GITHUB_RUN_ID = process.env.GITHUB_RUN_ID;
}
export type McpConfigs = Record<McpName, McpHttpServerConfig>;
export function createMcpConfigs(mcpServerUrl: string): McpConfigs {
return {
[ghPullfrogMcpName]: {
command: "node",
args: [serverPath],
env,
type: "http",
url: mcpServerUrl,
},
};
}
+75 -20
View File
@@ -1,5 +1,6 @@
import "./arkConfig.ts";
// this must be imported first
import { createServer } from "node:net";
import { FastMCP } from "fastmcp";
import { ghPullfrogMcpName } from "../external.ts";
import { GetCheckSuiteLogsTool } from "./checkSuite.ts";
@@ -18,25 +19,79 @@ import { GetReviewCommentsTool, ListPullRequestReviewsTool } from "./reviewComme
import { SelectModeTool } from "./selectMode.ts";
import { addTools } from "./shared.ts";
const server = new FastMCP({
name: ghPullfrogMcpName,
version: "0.0.1",
});
/**
* Find an available port starting from the given port
*/
async function findAvailablePort(startPort: number): Promise<number> {
const checkPort = (port: number): Promise<boolean> => {
return new Promise((resolve) => {
const server = createServer();
server.once("error", () => {
server.close();
resolve(false);
});
server.listen(port, () => {
server.close(() => {
resolve(true);
});
});
});
};
addTools(server, [
SelectModeTool,
CreateCommentTool,
EditCommentTool,
CreateWorkingCommentTool,
UpdateWorkingCommentTool,
IssueTool,
PullRequestTool,
ReviewTool,
PullRequestInfoTool,
GetReviewCommentsTool,
ListPullRequestReviewsTool,
GetCheckSuiteLogsTool,
DebugShellCommandTool,
]);
let port = startPort;
while (port < startPort + 100) {
if (await checkPort(port)) {
return port;
}
port++;
}
throw new Error(`Could not find available port starting from ${startPort}`);
}
server.start();
/**
* Start the MCP HTTP server and return the URL and close function
*/
export async function startMcpHttpServer(): Promise<{ url: string; close: () => Promise<void> }> {
const server = new FastMCP({
name: ghPullfrogMcpName,
version: "0.0.1",
});
addTools(server, [
SelectModeTool,
CreateCommentTool,
EditCommentTool,
CreateWorkingCommentTool,
UpdateWorkingCommentTool,
IssueTool,
PullRequestTool,
ReviewTool,
PullRequestInfoTool,
GetReviewCommentsTool,
ListPullRequestReviewsTool,
GetCheckSuiteLogsTool,
DebugShellCommandTool,
]);
const port = await findAvailablePort(3764);
const host = "127.0.0.1";
const endpoint = "/mcp";
await server.start({
transportType: "httpStream",
httpStream: {
port,
host,
endpoint,
},
});
const url = `http://${host}:${port}${endpoint}`;
return {
url,
close: async () => {
await server.stop();
},
};
}