diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 8bdeba3..503c4af 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -19,9 +19,6 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true -env: - GO_VERSION: 1.24.1 - defaults: run: shell: bash @@ -35,11 +32,11 @@ jobs: uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: - go-version: ${{ env.GO_VERSION }} + go-version-file: go.mod - name: Run golangci-lint uses: golangci/golangci-lint-action@v7 with: - version: v2.2.2 + version: v2.12.2 args: --timeout=5m test: @@ -50,7 +47,7 @@ jobs: uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: - go-version: ${{ env.GO_VERSION }} + go-version-file: go.mod - name: Run tests run: go test -v -race -coverprofile=coverage.txt -covermode=atomic ./... - name: Upload coverage @@ -67,7 +64,7 @@ jobs: os: - ubuntu-latest #x64 - ubuntu-24.04-arm #arm64 - - macos-13 #x64 + - macos-15-intel #x64 - macos-latest #arm64 runs-on: ${{ matrix.os }} steps: @@ -75,7 +72,7 @@ jobs: uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: - go-version: ${{ env.GO_VERSION }} + go-version-file: go.mod - name: Build run: make build - name: Verify module diff --git a/Makefile b/Makefile index 4830e6b..4b05c6e 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ LD_FLAGS = -s -w \ COMMON_BUILD_ARGS = -ldflags "$(LD_FLAGS)" GOLANGCI_LINT = $(shell pwd)/_output/tools/bin/golangci-lint -GOLANGCI_LINT_VERSION ?= v2.2.2 +GOLANGCI_LINT_VERSION ?= v2.12.2 # NPM version should not append the -dirty flag NPM_VERSION ?= $(shell echo $(shell git describe --tags --always) | sed 's/^v//') diff --git a/cmd/flashduty-mcp-server/main.go b/cmd/flashduty-mcp-server/main.go index a8f1107..ca77f38 100644 --- a/cmd/flashduty-mcp-server/main.go +++ b/cmd/flashduty-mcp-server/main.go @@ -1,3 +1,4 @@ +// Package main starts the FlashDuty MCP server command. package main import ( diff --git a/go.mod b/go.mod index 664caf9..339a993 100644 --- a/go.mod +++ b/go.mod @@ -1,37 +1,34 @@ module github.com/futuretea/flashduty-mcp-server -go 1.24.1 +go 1.25.5 require ( github.com/futuretea/go-http-client v0.0.2 - github.com/mark3labs/mcp-go v0.41.1 + github.com/mark3labs/mcp-go v0.54.0 github.com/rs/zerolog v1.33.0 github.com/spf13/cobra v1.10.1 github.com/spf13/viper v1.18.0 ) require ( - github.com/bahlo/generic-list-go v0.2.0 // indirect - github.com/buger/jsonparser v1.1.1 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/google/jsonschema-go v0.4.2 // indirect github.com/google/uuid v1.6.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/invopop/jsonschema v0.13.0 // indirect github.com/magiconair/properties v1.8.7 // indirect - github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/pelletier/go-toml/v2 v2.1.0 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect + github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.7.1 // indirect github.com/spf13/pflag v1.0.9 // indirect github.com/subosito/gotenv v1.6.0 // indirect - github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect github.com/yosida95/uritemplate/v3 v3.0.2 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.9.0 // indirect diff --git a/go.sum b/go.sum index e13777a..f009a2b 100644 --- a/go.sum +++ b/go.sum @@ -1,13 +1,11 @@ -github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= -github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= -github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= -github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI= +github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= @@ -15,27 +13,24 @@ github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyT github.com/futuretea/go-http-client v0.0.2 h1:MtdYSwj5RzeXoRR+TJbdPfOWwYafrxbKl6FT8T7Vaxw= github.com/futuretea/go-http-client v0.0.2/go.mod h1:QFXWNOvw6xEl1ztfTYSaJDqUCArH9cABQ0CziFmMOqM= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8= +github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/invopop/jsonschema v0.13.0 h1:KvpoAJWEjR3uD9Kbm2HWJmqsEaHt8lBUpd0qHcIi21E= -github.com/invopop/jsonschema v0.13.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mark3labs/mcp-go v0.41.1 h1:w78eWfiQam2i8ICL7AL0WFiq7KHNJQ6UB53ZVtH4KGA= -github.com/mark3labs/mcp-go v0.41.1/go.mod h1:T7tUa2jO6MavG+3P25Oy/jR7iCeJPHImCZHRymCn39g= +github.com/mark3labs/mcp-go v0.54.0 h1:PZhQvd+5xrT43cUoiaKn/hDcvLUhcLc1twSEKYPTcTA= +github.com/mark3labs/mcp-go v0.54.0/go.mod h1:+8WclSK1ZUweCP3hvktSji8n8ABG/95QaEkeVE/Uwas= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= @@ -49,8 +44,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= -github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= @@ -59,6 +54,8 @@ github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6ke github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= +github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 h1:KRzFb2m7YtdldCEkzs6KqmJw4nqEVZGK7IN2kJkjTuQ= +github.com/santhosh-tekuri/jsonschema/v6 v6.0.2/go.mod h1:JXeL+ps8p7/KNMjDQk3TCwPpBy0wYklyWTfbkIzdIFU= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= @@ -78,12 +75,10 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= -github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= -github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4= github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4= go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= @@ -100,8 +95,8 @@ golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/cmd/root.go b/internal/cmd/root.go index 87379f4..07c0324 100644 --- a/internal/cmd/root.go +++ b/internal/cmd/root.go @@ -1,3 +1,4 @@ +// Package cmd contains the FlashDuty MCP server CLI commands. package cmd import ( @@ -60,11 +61,11 @@ network access. Manage incidents, alerts, channels, teams, members, and on-call schedules through the FlashDuty API.`, SilenceUsage: true, SilenceErrors: true, - PersistentPreRunE: func(cmd *cobra.Command, args []string) error { + PersistentPreRunE: func(cmd *cobra.Command, _ []string) error { bindFlags(cmd) return nil }, - RunE: func(cmd *cobra.Command, args []string) error { + RunE: func(_ *cobra.Command, _ []string) error { return runServer(cfgFile, streams) }, } @@ -130,8 +131,12 @@ func runServer(cfgFile string, streams IOStreams) error { // Start server based on port configuration if cfg.Port == 0 { // Stdio mode - use fmt.Fprintf for startup messages as logging is disabled - fmt.Fprintf(streams.ErrOut, "Starting FlashDuty MCP Server in stdio mode\n") - fmt.Fprintf(streams.ErrOut, "Enabled tools: %v\n", server.GetEnabledTools()) + if _, err := fmt.Fprintf(streams.ErrOut, "Starting FlashDuty MCP Server in stdio mode\n"); err != nil { + return fmt.Errorf("failed to write startup message: %w", err) + } + if _, err := fmt.Fprintf(streams.ErrOut, "Enabled tools: %v\n", server.GetEnabledTools()); err != nil { + return fmt.Errorf("failed to write enabled tools: %w", err) + } return server.ServeStdio() } @@ -151,8 +156,9 @@ func newVersionCommand(streams IOStreams) *cobra.Command { cmd := &cobra.Command{ Use: "version", Short: "Print version information", - Run: func(cmd *cobra.Command, args []string) { - fmt.Fprintf(streams.Out, "%s\n", version.GetVersionInfo()) + RunE: func(_ *cobra.Command, _ []string) error { + _, err := fmt.Fprintf(streams.Out, "%s\n", version.GetVersionInfo()) + return err }, } diff --git a/pkg/core/config/config.go b/pkg/core/config/config.go index f1e9ed2..8e195e3 100644 --- a/pkg/core/config/config.go +++ b/pkg/core/config/config.go @@ -1,3 +1,4 @@ +// Package config loads and validates FlashDuty MCP server configuration. package config import ( diff --git a/pkg/core/logging/logging.go b/pkg/core/logging/logging.go index a6307ab..64c06fb 100644 --- a/pkg/core/logging/logging.go +++ b/pkg/core/logging/logging.go @@ -1,3 +1,4 @@ +// Package logging wraps the process-wide structured logger. package logging import ( diff --git a/pkg/core/version/version.go b/pkg/core/version/version.go index 7e3314c..94add2d 100644 --- a/pkg/core/version/version.go +++ b/pkg/core/version/version.go @@ -1,3 +1,4 @@ +// Package version exposes build-time version metadata. package version import ( diff --git a/pkg/server/http/http.go b/pkg/server/http/http.go index 42c4370..6836e58 100644 --- a/pkg/server/http/http.go +++ b/pkg/server/http/http.go @@ -1,3 +1,4 @@ +// Package http serves the FlashDuty MCP server over HTTP, SSE, and health endpoints. package http import ( @@ -21,6 +22,7 @@ const ( sseMessageEndpoint = "/message" ) +// Serve starts the HTTP, SSE, and streamable HTTP endpoints. func Serve(ctx context.Context, mcpServer *mcp.Server, staticConfig *config.StaticConfig) error { mux := http.NewServeMux() @@ -32,17 +34,17 @@ func Serve(ctx context.Context, mcpServer *mcp.Server, staticConfig *config.Stat } sseServer := mcpServer.ServeSse(staticConfig.SSEBaseURL, httpServer) - streamableHttpServer := mcpServer.ServeHTTP(httpServer) + streamableHTTPServer := mcpServer.ServeHTTP(httpServer) mux.Handle(sseEndpoint, sseServer) mux.Handle(sseMessageEndpoint, sseServer) - mux.Handle(mcpEndpoint, streamableHttpServer) - mux.HandleFunc(healthEndpoint, func(w http.ResponseWriter, r *http.Request) { + mux.Handle(mcpEndpoint, streamableHTTPServer) + mux.HandleFunc(healthEndpoint, func(w http.ResponseWriter, _ *http.Request) { if mcpServer.IsHealthy() { w.WriteHeader(http.StatusOK) - w.Write([]byte("healthy")) + _, _ = w.Write([]byte("healthy")) } else { w.WriteHeader(http.StatusServiceUnavailable) - w.Write([]byte("unhealthy: FlashDuty client initialization failed")) + _, _ = w.Write([]byte("unhealthy: FlashDuty client initialization failed")) } }) diff --git a/pkg/server/http/middleware.go b/pkg/server/http/middleware.go index 7cee456..edaa53d 100644 --- a/pkg/server/http/middleware.go +++ b/pkg/server/http/middleware.go @@ -1,3 +1,4 @@ +// Package http serves the FlashDuty MCP server over HTTP, SSE, and health endpoints. package http import ( @@ -9,6 +10,7 @@ import ( "github.com/futuretea/flashduty-mcp-server/pkg/core/logging" ) +// RequestMiddleware logs non-health HTTP requests and response statuses. func RequestMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.URL.Path == healthEndpoint { diff --git a/pkg/server/mcp/mcp.go b/pkg/server/mcp/mcp.go index aa16fd8..3b7ffee 100644 --- a/pkg/server/mcp/mcp.go +++ b/pkg/server/mcp/mcp.go @@ -1,3 +1,4 @@ +// Package mcp configures the FlashDuty MCP server and its tools. package mcp import ( @@ -95,7 +96,7 @@ func (s *Server) shouldEnableTool(toolName string) bool { func (s *Server) registerTool(tool toolset.ServerTool) error { client := s.client - toolHandler := server.ToolHandlerFunc(func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + toolHandler := server.ToolHandlerFunc(func(_ context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { logging.Debug("Tool %s called with params: %v", tool.Tool.Name, request.Params.Arguments) params, _ := request.Params.Arguments.(map[string]any) diff --git a/pkg/toolset/flashduty/aggregation.go b/pkg/toolset/flashduty/aggregation.go index 57096eb..de01628 100644 --- a/pkg/toolset/flashduty/aggregation.go +++ b/pkg/toolset/flashduty/aggregation.go @@ -1,3 +1,4 @@ +// Package flashduty implements FlashDuty MCP tools and API helpers. package flashduty import ( @@ -245,10 +246,10 @@ func fetchIncidentPage(c *Client, body map[string]any) ([]map[string]any, string } // appendIncidentItems appends items to the collection, respecting the max limit. -func appendIncidentItems(all []map[string]any, items []map[string]any, max int) []map[string]any { +func appendIncidentItems(all []map[string]any, items []map[string]any, maxItems int) []map[string]any { for _, item := range items { all = append(all, item) - if len(all) >= max { + if len(all) >= maxItems { break } } diff --git a/pkg/toolset/flashduty/aggregation_test.go b/pkg/toolset/flashduty/aggregation_test.go index 38def86..1347014 100644 --- a/pkg/toolset/flashduty/aggregation_test.go +++ b/pkg/toolset/flashduty/aggregation_test.go @@ -170,7 +170,7 @@ func TestBuildCompositeKey_EmptyValues(t *testing.T) { // single-page response (has_next_page=false) in the standard FlashDuty API envelope. func newMockServer(t *testing.T, incidents []map[string]any) *httptest.Server { t.Helper() - return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { data := map[string]any{ "items": incidents, "has_next_page": false, diff --git a/pkg/toolset/flashduty/enrichment_test.go b/pkg/toolset/flashduty/enrichment_test.go index 6206b05..640de0a 100644 --- a/pkg/toolset/flashduty/enrichment_test.go +++ b/pkg/toolset/flashduty/enrichment_test.go @@ -184,7 +184,7 @@ func TestEnrichResponders(t *testing.T) { } } -func TestEnrichResponders_NoResponders(t *testing.T) { +func TestEnrichResponders_NoResponders(_ *testing.T) { obj := map[string]any{} names := map[int]string{1: "Alice"} // Should not panic @@ -216,7 +216,7 @@ func TestEnrichAssignedTo(t *testing.T) { } } -func TestEnrichAssignedTo_NoAssignedTo(t *testing.T) { +func TestEnrichAssignedTo_NoAssignedTo(_ *testing.T) { obj := map[string]any{} names := map[int]string{1: "Alice"} // Should not panic diff --git a/pkg/toolset/flashduty/timeformat_test.go b/pkg/toolset/flashduty/timeformat_test.go index 0bb50c0..b5d5d5b 100644 --- a/pkg/toolset/flashduty/timeformat_test.go +++ b/pkg/toolset/flashduty/timeformat_test.go @@ -169,7 +169,7 @@ func TestAddTimestampDisplayToList_MultipleItems(t *testing.T) { } } -func TestAddTimestampDisplayToList_EmptyList(t *testing.T) { +func TestAddTimestampDisplayToList_EmptyList(_ *testing.T) { // Should not panic. AddTimestampDisplayToList([]interface{}{}, time.UTC) } diff --git a/pkg/toolset/flashduty/toolset.go b/pkg/toolset/flashduty/toolset.go index a53a91b..57557d2 100644 --- a/pkg/toolset/flashduty/toolset.go +++ b/pkg/toolset/flashduty/toolset.go @@ -1,3 +1,4 @@ +// Package flashduty implements FlashDuty MCP tools and API helpers. package flashduty import ( @@ -17,10 +18,12 @@ var ( itemsString = map[string]any{"type": "string"} ) +// GetName returns the FlashDuty toolset name. func (t *Toolset) GetName() string { return "flashduty" } +// GetDescription returns a human-readable FlashDuty toolset description. func (t *Toolset) GetDescription() string { return "FlashDuty incident management and alert tools" } diff --git a/pkg/toolset/toolset.go b/pkg/toolset/toolset.go index 94e8fc5..fd4344d 100644 --- a/pkg/toolset/toolset.go +++ b/pkg/toolset/toolset.go @@ -1,3 +1,4 @@ +// Package toolset defines shared MCP toolset interfaces. package toolset import (