Skip to content

Commit 966e931

Browse files
shivasuryaclaude
andcommitted
feat(mcp): add HTTP transport for network access
Add HTTP server transport as alternative to stdio: - HTTPServer wraps MCP server with HTTP/JSON-RPC interface - Health endpoint at /health for monitoring - CORS support with configurable allowed origins - Graceful shutdown with signal handling - Streaming support via SSE and line-delimited JSON Usage: pathfinder serve --http --address :8080 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 78c5531 commit 966e931

File tree

3 files changed

+848
-3
lines changed

3 files changed

+848
-3
lines changed

sast-engine/cmd/serve.go

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package cmd
22

33
import (
4+
"context"
45
"fmt"
56
"os"
7+
"os/signal"
8+
"syscall"
69
"time"
710

811
"github.com/shivasurya/code-pathfinder/sast-engine/graph"
@@ -16,25 +19,33 @@ import (
1619
var serveCmd = &cobra.Command{
1720
Use: "serve",
1821
Short: "Start MCP server for AI coding assistants",
19-
Long: `Builds code index and starts MCP server on stdio.
22+
Long: `Builds code index and starts MCP server.
2023
2124
Designed for integration with Claude Code, Codex CLI, and other AI assistants
2225
that support the Model Context Protocol (MCP).
2326
2427
The server indexes the codebase once at startup, then responds to queries
25-
about symbols, call graphs, and code relationships.`,
28+
about symbols, call graphs, and code relationships.
29+
30+
Transport modes:
31+
- stdio (default): Standard input/output for direct integration
32+
- http: HTTP server for network access`,
2633
RunE: runServe,
2734
}
2835

2936
func init() {
3037
rootCmd.AddCommand(serveCmd)
3138
serveCmd.Flags().StringP("project", "p", ".", "Project path to index")
3239
serveCmd.Flags().String("python-version", "3.11", "Python version for stdlib resolution")
40+
serveCmd.Flags().Bool("http", false, "Use HTTP transport instead of stdio")
41+
serveCmd.Flags().String("address", ":8080", "HTTP server address (only with --http)")
3342
}
3443

3544
func runServe(cmd *cobra.Command, _ []string) error {
3645
projectPath, _ := cmd.Flags().GetString("project")
3746
pythonVersion, _ := cmd.Flags().GetString("python-version")
47+
useHTTP, _ := cmd.Flags().GetBool("http")
48+
address, _ := cmd.Flags().GetString("address")
3849

3950
fmt.Fprintln(os.Stderr, "Building index...")
4051
start := time.Now()
@@ -66,9 +77,45 @@ func runServe(cmd *cobra.Command, _ []string) error {
6677
fmt.Fprintf(os.Stderr, " Call edges: %d\n", len(callGraph.Edges))
6778
fmt.Fprintf(os.Stderr, " Modules: %d\n", len(moduleRegistry.Modules))
6879

69-
// 4. Create and run MCP server
80+
// 4. Create MCP server
7081
server := mcp.NewServer(projectPath, pythonVersion, callGraph, moduleRegistry, codeGraph, buildTime)
7182

83+
// 5. Start appropriate transport
84+
if useHTTP {
85+
return runHTTPServer(server, address)
86+
}
87+
7288
fmt.Fprintln(os.Stderr, "Starting MCP server on stdio...")
7389
return server.ServeStdio()
7490
}
91+
92+
func runHTTPServer(mcpServer *mcp.Server, address string) error {
93+
config := &mcp.HTTPConfig{
94+
Address: address,
95+
ReadTimeout: 30 * time.Second,
96+
WriteTimeout: 30 * time.Second,
97+
ShutdownTimeout: 5 * time.Second,
98+
AllowedOrigins: []string{"*"},
99+
}
100+
101+
httpServer := mcp.NewHTTPServer(mcpServer, config)
102+
103+
// Handle graceful shutdown.
104+
sigChan := make(chan os.Signal, 1)
105+
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
106+
107+
errChan := make(chan error, 1)
108+
go func() {
109+
errChan <- httpServer.Start()
110+
}()
111+
112+
select {
113+
case err := <-errChan:
114+
return err
115+
case sig := <-sigChan:
116+
fmt.Fprintf(os.Stderr, "\nReceived %v, shutting down...\n", sig)
117+
ctx, cancel := context.WithTimeout(context.Background(), config.ShutdownTimeout)
118+
defer cancel()
119+
return httpServer.Shutdown(ctx)
120+
}
121+
}

0 commit comments

Comments
 (0)