Skip to main content
Glama

Last9 Observability MCP

Official
main.go4.02 kB
// An MCP server implementation for Last9 that enables AI agents // to query exception and service graph data package main import ( "context" "errors" "flag" "fmt" "log" "os" "last9-mcp/internal/auth" "last9-mcp/internal/models" "last9-mcp/internal/utils" "github.com/joho/godotenv" last9mcp "github.com/last9/mcp-go-sdk/mcp" "github.com/modelcontextprotocol/go-sdk/mcp" "github.com/peterbourgon/ff/v3" ) // Version information var ( Version = "dev" // Set by goreleaser CommitSHA = "unknown" // Set by goreleaser BuildTime = "unknown" // Set by goreleaser ) // setupConfig initializes and parses the configuration func SetupConfig(defaults models.Config) (models.Config, error) { fs := flag.NewFlagSet("last9-mcp", flag.ExitOnError) var cfg models.Config fs.StringVar(&cfg.AuthToken, "auth", os.Getenv("LAST9_AUTH_TOKEN"), "Last9 API auth token") fs.StringVar(&cfg.BaseURL, "url", os.Getenv("LAST9_BASE_URL"), "Last9 API URL") fs.StringVar(&cfg.RefreshToken, "refresh_token", os.Getenv("LAST9_REFRESH_TOKEN"), "Last9 refresh token for authentication") fs.Float64Var(&cfg.RequestRateLimit, "rate", 1, "Requests per second limit") fs.IntVar(&cfg.RequestRateBurst, "burst", 1, "Request burst capacity") fs.BoolVar(&cfg.HTTPMode, "http", false, "Run as HTTP server instead of STDIO") fs.StringVar(&cfg.Port, "port", "8080", "HTTP server port") fs.StringVar(&cfg.Host, "host", "localhost", "HTTP server host") versionFlag := fs.Bool("version", false, "Print version information") var configFile string fs.StringVar(&configFile, "config", "", "config file path") err := ff.Parse(fs, os.Args[1:], ff.WithEnvVarPrefix("LAST9"), ff.WithConfigFileFlag("config"), ff.WithConfigFileParser(ff.JSONParser), ) if err != nil { return cfg, fmt.Errorf("failed to parse configuration: %w", err) } if *versionFlag { fmt.Printf("Version: %s\nCommit: %s\nBuild Time: %s\n", Version, CommitSHA, BuildTime) os.Exit(0) } if cfg.AuthToken == "" { if defaults.AuthToken != "" { cfg.AuthToken = defaults.AuthToken } else { return cfg, errors.New("Last9 auth token must be provided via LAST9_AUTH_TOKEN env var") } } // Set default base URL if not provided if cfg.BaseURL == "" { if defaults.BaseURL != "" { cfg.BaseURL = defaults.BaseURL } else { return cfg, errors.New("Last9 base URL must be provided via LAST9_BASE_URL env var") } } if cfg.RefreshToken == "" { if defaults.RefreshToken != "" { cfg.RefreshToken = defaults.RefreshToken } else { return cfg, errors.New("Last9 refresh token must be provided via LAST9_REFRESH_TOKEN env var") } } return cfg, nil } func main() { log.Printf("Starting Last9 MCP Server v%s", Version) // Load .env file if it exists (ignore errors if file doesn't exist) if err := godotenv.Load(); err != nil { log.Printf("No .env file found or error loading it (this is ok): %v", err) } cfg, err := SetupConfig(models.Config{}) if err != nil { log.Fatalf("config error: %v", err) } log.Printf("Config loaded - BaseURL: %s, HTTPMode: %t", cfg.BaseURL, cfg.HTTPMode) tokenManager, err := auth.NewTokenManager(cfg.RefreshToken) if err != nil { log.Fatalf("failed to create token manager: %v", err) } cfg.TokenManager = tokenManager if err := utils.PopulateAPICfg(&cfg); err != nil { log.Fatalf("failed to refresh access token: %v", err) } // Create MCP server with new SDK server, err := last9mcp.NewServer("last9-mcp", Version) if err != nil { log.Fatalf("failed to create MCP server: %v", err) } // Register all tools if err := registerAllTools(server, cfg); err != nil { log.Fatalf("failed to register tools: %v", err) } if cfg.HTTPMode { // Create HTTP server using NewHTTPServer httpServer := NewHTTPServer(server, cfg) // Start the server if err := httpServer.Start(); err != nil { log.Fatalf("HTTP server error: %v", err) } } else { // Start STDIO server (default) log.Fatal(server.Serve(context.Background(), &mcp.StdioTransport{})) } }

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/last9/last9-mcp-server'

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