Skip to main content
Glama
http.go2.92 kB
/* Copyright © 2025 Ronmi Ren <ronmi.ren@gmail.com */ package cmd import ( "fmt" "net/http" "os" "strings" "github.com/modelcontextprotocol/go-sdk/mcp" "github.com/raohwork/forgejo-mcp/tools" "github.com/spf13/cobra" "github.com/spf13/viper" ) // httpCmd represents the http command var httpCmd = &cobra.Command{ Use: "http", Short: "Run MCP server in SSE mode", Long: `Run the Forgejo MCP server with an HTTP interface. This command starts a web server that allows MCP clients to connect over HTTP. It supports both Server-Sent Events (SSE) on the /sse endpoint and a standard request/response model on the / endpoint. The server can operate in two modes: - Single-user mode: When a --token is provided at startup, all operations are performed using this single token. This is suitable for personal use or dedicated services where one identity is sufficient. - Multi-user mode: If no --token is provided, the server requires clients to authenticate by providing their own token in the 'Authorization' header of each request. This allows the server to act as a gateway for multiple users. This HTTP mode is ideal for: - Web-based clients and services. - Remote access to the Forgejo instance through MCP. - Environments where a central MCP gateway is needed. Example: forgejo-mcp http --address :8080 --server https://git.example.com --token your_token`, Run: func(cmd *cobra.Command, args []string) { base := viper.GetString("server") token := viper.GetString("token") addr := viper.GetString("address") if addr == "" { addr = ":8080" } if base == "" { cmd.Help() os.Exit(1) } singleMode := token != "" var cl *tools.Client if singleMode { c, err := tools.NewClient(base, token, "", nil) if err != nil { fmt.Printf("Error creating SDK client: %v\n", err) os.Exit(1) } cl = c } else { cl, _ = tools.NewClient(base, "", "9", nil) } getServer := func(q *http.Request) *mcp.Server { if singleMode { return createServer(cl) } mycl := cl myToken := q.Header.Get("Authorization") if myToken != "" { if strings.HasPrefix(myToken, "Bearer ") { myToken = myToken[7:] } c, err := tools.NewClient(base, myToken, "", nil) if err == nil { mycl = c } } return createServer(mycl) } mux := http.NewServeMux() mux.Handle("/sse", mcp.NewSSEHandler(getServer)) mux.Handle("/", mcp.NewStreamableHTTPHandler(getServer, nil)) mode := "single" if !singleMode { mode = "multiuser" } fmt.Printf("Starting %s mode MCP server on %s\n", mode, addr) err := http.ListenAndServe(addr, mux) if err != nil { fmt.Printf("Server exited with error: %v\n", err) os.Exit(1) } }, } func init() { rootCmd.AddCommand(httpCmd) f := httpCmd.Flags() f.String("address", ":8080", "Address to listen on for incoming connections") viper.BindPFlags(f) }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/raohwork/forgejo-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server