Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/patch-extend-safe-outputs-timeout.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions .changeset/patch-safe-outputs-startup-logging.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions actions/setup/js/mcp_http_transport.cjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
// @ts-check
/// <reference types="@actions/github-script" />

const { createLogger } = require("./mcp_logger.cjs");
const moduleLogger = createLogger("mcp_http_transport");

// Log immediately at module load time
moduleLogger.debug("Module is being loaded");

/**
* MCP HTTP Transport Implementation
*
Expand Down Expand Up @@ -74,9 +80,14 @@ class MCPServer {
* @param {any} transport - Transport instance (must have setServer and start methods)
*/
async connect(transport) {
const logger = createLogger("MCPServer");
logger.debug("Starting connect...");
this.transport = transport;
logger.debug("Set transport");
transport.setServer(this);
logger.debug("Called setServer");
await transport.start();
logger.debug("Transport.start() completed");
}

/**
Expand Down Expand Up @@ -126,10 +137,13 @@ class MCPHTTPTransport {
* Start the transport
*/
async start() {
const logger = createLogger("MCPHTTPTransport");
logger.debug(`Called, started=${this.started}`);
if (this.started) {
throw new Error("Transport already started");
}
this.started = true;
logger.debug("Set started=true");
}

/**
Expand Down
6 changes: 6 additions & 0 deletions actions/setup/js/mcp_server_core.cjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
// @ts-check
/// <reference types="@actions/github-script" />

const { createLogger } = require("./mcp_logger.cjs");
const moduleLogger = createLogger("mcp_server_core");

// Log immediately at module load time
moduleLogger.debug("Module is being loaded");

/**
* MCP Server Core Module
*
Expand Down
15 changes: 14 additions & 1 deletion actions/setup/js/safe-outputs-mcp-server.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,16 @@
// This is the main entry point script for the safe-outputs MCP server
// It starts the HTTP server on the configured port

const { createLogger } = require("./mcp_logger.cjs");
const logger = createLogger("safe-outputs-entry");

// Log immediately to verify Node.js execution starts
logger.debug("Entry point script executing");

const { startHttpServer } = require("./safe_outputs_mcp_server_http.cjs");

logger.debug("Successfully required safe_outputs_mcp_server_http.cjs");

// Start the HTTP server
// The server reads configuration from /opt/gh-aw/safeoutputs/config.json
// Port and API key are configured via environment variables:
Expand All @@ -18,13 +26,18 @@ const { startHttpServer } = require("./safe_outputs_mcp_server_http.cjs");
// the MCP gateway doesn't perform the MCP protocol initialization handshake.
// It directly calls methods like tools/list without the Mcp-Session-Id header.
if (require.main === module) {
logger.debug("In require.main === module block");
const port = parseInt(process.env.GH_AW_SAFE_OUTPUTS_PORT || "3001", 10);
const logDir = process.env.GH_AW_MCP_LOG_DIR;
logger.debug(`Port: ${port}, LogDir: ${logDir}`);
logger.debug("Calling startHttpServer...");

startHttpServer({ port, logDir, stateless: true }).catch(error => {
console.error(`Failed to start safe-outputs HTTP server: ${error.message}`);
logger.debugError("Failed to start safe-outputs HTTP server: ", error);
process.exit(1);
});

logger.debug("startHttpServer call initiated (async)");
}

module.exports = { startHttpServer };
25 changes: 22 additions & 3 deletions actions/setup/js/safe_outputs_mcp_server_http.cjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
// @ts-check
/// <reference types="@actions/github-script" />

const { createLogger } = require("./mcp_logger.cjs");
const moduleLogger = createLogger("safe_outputs_mcp_server_http");

// Log immediately at module load time (before any requires)
moduleLogger.debug("Module is being loaded");

/**
* Safe Outputs MCP Server with HTTP Transport
*
Expand All @@ -19,14 +25,23 @@
*/

const http = require("http");
moduleLogger.debug("Loaded http");
const { randomUUID } = require("crypto");
moduleLogger.debug("Loaded crypto");
const { MCPServer, MCPHTTPTransport } = require("./mcp_http_transport.cjs");
const { createLogger } = require("./mcp_logger.cjs");
moduleLogger.debug("Loaded mcp_http_transport.cjs");
const { createLogger: createMCPLogger } = require("./mcp_logger.cjs");
moduleLogger.debug("Loaded mcp_logger.cjs");
const { bootstrapSafeOutputsServer, cleanupConfigFile } = require("./safe_outputs_bootstrap.cjs");
moduleLogger.debug("Loaded safe_outputs_bootstrap.cjs");
const { createAppendFunction } = require("./safe_outputs_append.cjs");
moduleLogger.debug("Loaded safe_outputs_append.cjs");
const { createHandlers } = require("./safe_outputs_handlers.cjs");
moduleLogger.debug("Loaded safe_outputs_handlers.cjs");
const { attachHandlers, registerPredefinedTools, registerDynamicTools } = require("./safe_outputs_tools_loader.cjs");
moduleLogger.debug("Loaded safe_outputs_tools_loader.cjs");
const { getErrorMessage } = require("./error_helpers.cjs");
moduleLogger.debug("All modules loaded successfully");

/**
* Create and configure the MCP server with tools
Expand All @@ -36,7 +51,7 @@ const { getErrorMessage } = require("./error_helpers.cjs");
*/
function createMCPServer(options = {}) {
// Create logger early
const logger = createLogger("safeoutputs");
const logger = createMCPLogger("safeoutputs");

logger.debug(`=== Creating MCP Server ===`);

Expand Down Expand Up @@ -176,15 +191,17 @@ async function startHttpServer(options = {}) {
const port = options.port || 3000;
const stateless = options.stateless || false;

const logger = createLogger("safe-outputs-startup");
const logger = createMCPLogger("safe-outputs-startup");

logger.debug(`startHttpServer called with port=${port}, stateless=${stateless}`);
logger.debug(`=== Starting Safe Outputs MCP HTTP Server ===`);
logger.debug(`Port: ${port}`);
logger.debug(`Mode: ${stateless ? "stateless" : "stateful"}`);
logger.debug(`Environment: NODE_VERSION=${process.version}, PLATFORM=${process.platform}`);

// Create the MCP server
try {
logger.debug(`About to call createMCPServer...`);
const { server, config, logger: mcpLogger } = createMCPServer({ logDir: options.logDir });

// Use the MCP logger for subsequent messages
Expand All @@ -206,7 +223,9 @@ async function startHttpServer(options = {}) {

// Connect server to transport
logger.debug(`Connecting server to transport...`);
logger.debug(`About to call server.connect(transport)...`);
await server.connect(transport);
logger.debug(`server.connect(transport) completed successfully`);
logger.debug(`Server connected to transport successfully`);

// Create HTTP server
Expand Down
12 changes: 6 additions & 6 deletions actions/setup/sh/start_safe_outputs_server.sh
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,9 @@ node mcp-server.cjs >> /tmp/gh-aw/mcp-logs/safeoutputs/server.log 2>&1 &
SERVER_PID=$!
echo "Started safe-outputs MCP server with PID $SERVER_PID"

# Wait for server to be ready (max 10 seconds)
# Wait for server to be ready (max 60 seconds)
echo "Waiting for server to become ready..."
for i in {1..10}; do
for i in {1..60}; do
# Check if process is still running
if ! kill -0 $SERVER_PID 2>/dev/null; then
echo "ERROR: Server process $SERVER_PID has died"
Expand All @@ -100,12 +100,12 @@ for i in {1..10}; do

# Check if server is responding
if curl -s -f "http://localhost:$GH_AW_SAFE_OUTPUTS_PORT/health" > /dev/null 2>&1; then
echo "Safe Outputs MCP server is ready (attempt $i/10)"
echo "Safe Outputs MCP server is ready (attempt $i/60)"
break
fi

if [ "$i" -eq 10 ]; then
echo "ERROR: Safe Outputs MCP server failed to start after 10 seconds"
if [ "$i" -eq 60 ]; then
echo "ERROR: Safe Outputs MCP server failed to start after 60 seconds"
echo "Process status: $(pgrep -f 'mcp-server.cjs' || echo 'not running')"
echo "Server log contents:"
cat /tmp/gh-aw/mcp-logs/safeoutputs/server.log
Expand All @@ -114,7 +114,7 @@ for i in {1..10}; do
exit 1
fi

echo "Waiting for server... (attempt $i/10)"
echo "Waiting for server... (attempt $i/60)"
sleep 1
done

Expand Down
Loading