diff --git a/MCP/go/README.md b/MCP/go/README.md new file mode 100644 index 0000000..7efee51 --- /dev/null +++ b/MCP/go/README.md @@ -0,0 +1,208 @@ +# Slack Web API MCP Server + +This MCP (Model Content Protocol) server provides access to Slack Web API API functionality through HTTP, HTTPS, and STDIO transport modes. + +## Features + +- transport mode support (HTTP and STDIO) +- Dynamic configuration through HTTP headers +- Automatic tool generation from API documentation + +## Building the Project + +1. Ensure you have Go 1.24.6 or later installed +2. Clone the repository +3. Build the project: + +```bash +go build -o mcp-server +``` + +## Running the Server + +The server can run in three modes based on the **TRANSPORT** environment variable: + +### HTTP Mode + +To run in HTTP mode, set the transport environment variable to "http" or "HTTP": + +```bash +export TRANSPORT="http" # or "HTTP" or "HTTPS" +export PORT="8181" # required +``` + +Run the server: +```bash +./mcp-server +``` + +#### Required Environment Variables for HTTP Mode: +- `TRANSPORT`: Set to "HTTP" **(Required)** +- `PORT`: Server port **(Required)** + +#### Configuration through HTTP Headers: +In HTTP mode, API configuration is provided via HTTP headers for each request: +- `API_BASE_URL`: **(Required)** Base URL for the API +- `BEARER_TOKEN`: Bearer token for authentication +- `API_KEY`: API key for authentication +- `BASIC_AUTH`: Basic authentication credentials + +Cursor mcp.json settings: + +{ + "mcpServers": { + "your-mcp-server-http": { + "url": "http://:/mcp", + "headers": { + "API_BASE_URL": "https://your-api-base-url", + "BEARER_TOKEN": "your-bearer-token" + } + } + } +} + +The server will start on the configured port with the following endpoints: +- `/mcp`: HTTP endpoint for MCP communication (requires API_BASE_URL header) +- `/`: Health check endpoint + +**Note**: At least one authentication header (BEARER_TOKEN, API_KEY, or BASIC_AUTH) should be provided unless the API explicitly doesn't require authentication. + +### HTTPS Mode + +To run in HTTPS mode, set the transport environment variable to "https" or "HTTPS": + +```bash +export TRANSPORT="https" # or "HTTPS" +export PORT="8443" # required +export CERT_FILE="./certs/cert.pem" # required +export KEY_FILE="./certs/key.pem" # required +``` + +Run the server: +```bash +./mcp-server +``` + +#### Required Environment Variables for HTTPS Mode: +- `TRANSPORT`: Set to "HTTPS" **(Required)** +- `PORT`: Server port **(Required)** +- `CERT_FILE`: Path to SSL certificate file **(Required)** +- `KEY_FILE`: Path to SSL private key file **(Required)** + +#### Configuration through HTTP Headers: +In HTTPS mode, API configuration is provided via HTTP headers for each request: +- `API_BASE_URL`: **(Required)** Base URL for the API +- `BEARER_TOKEN`: Bearer token for authentication +- `API_KEY`: API key for authentication +- `BASIC_AUTH`: Basic authentication credentials + +Cursor mcp.json settings: + +{ + "mcpServers": { + "your-mcp-server-https": { + "url": "https://:/mcp", + "headers": { + "API_BASE_URL": "https://your-api-base-url", + "BEARER_TOKEN": "your-bearer-token" + } + } + } +} + +The server will start on the configured port with the following endpoints: +- `/mcp`: HTTPS endpoint for MCP communication (requires API_BASE_URL header) +- `/`: Health check endpoint + +**Note**: At least one authentication header (BEARER_TOKEN, API_KEY, or BASIC_AUTH) should be provided unless the API explicitly doesn't require authentication. + +``` + +### STDIO Mode + +To run in STDIO mode, either set the transport environment variable to "stdio" or leave it unset (default): + +```bash +export TRANSPORT="stdio" # or leave unset for default +export API_BASE_URL="https://your-api-base-url" +export BEARER_TOKEN="your-bearer-token" +``` + +Run the server: +```bash +./mcp-server +``` + +#### Required Environment Variables for STDIO Mode: +- `TRANSPORT`: Set to "stdio" or leave unset (default) +- `API_BASE_URL`: Base URL for the API **(Required)** +- `BEARER_TOKEN`: Bearer token for authentication +- `API_KEY`: API key for authentication +- `BASIC_AUTH`: Basic authentication credentials + +**Note**: At least one authentication environment variable (BEARER_TOKEN, API_KEY, or BASIC_AUTH) should be provided unless the API explicitly doesn't require authentication. + +Cursor mcp.json settings: + +{ + "mcpServers": { + "your-mcp-server-stdio": { + "command": "/", + "env": { + "API_BASE_URL": "", + "BEARER_TOKEN": "" + } + } + } +} + +## Environment Variable Case Sensitivity + +The server supports both uppercase and lowercase transport environment variables: +- `TRANSPORT` (uppercase) - checked first +- `transport` (lowercase) - fallback if uppercase not set + +Valid values: "http", "HTTP", "https", "HTTPS", "stdio", or unset (defaults to STDIO) + +## Authentication + +### HTTP Mode +Authentication is provided through HTTP headers on each request: +- `BEARER_TOKEN`: Bearer token +- `API_KEY`: API key +- `BASIC_AUTH`: Basic authentication + +### STDIO Mode +Authentication is provided through environment variables: +- `BEARER_TOKEN`: Bearer token +- `API_KEY`: API key +- `BASIC_AUTH`: Basic authentication + +## Health Check + +When running in HTTP mode, you can check server health at the root endpoint (`/`). +Expected response: `{"status":"ok"}` + +## Transport Modes Summary + +### HTTP Mode (TRANSPORT=http or TRANSPORT=HTTP) +- Uses streamable HTTP server +- Configuration provided via HTTP headers for each request +- Requires API_BASE_URL header for each request +- Endpoint: `/mcp` +- Port configured via PORT environment variable (defaults to 8080) + +### HTTPS Mode (TRANSPORT=https or TRANSPORT=HTTPS) +- Uses streamable HTTPS server with SSL/TLS encryption +- Configuration provided via HTTP headers for each request +- Requires API_BASE_URL header for each request +- Endpoint: `/mcp` +- Port configured via PORT environment variable (defaults to 8443) +- **Requires SSL certificate and private key files (CERT_FILE and KEY_FILE)** + +### STDIO Mode (TRANSPORT=stdio or unset) +- Uses standard input/output for communication +- Configuration through environment variables only +- Requires API_BASE_URL environment variable +- Suitable for command-line usage + diff --git a/MCP/go/config/config.go b/MCP/go/config/config.go new file mode 100644 index 0000000..d8fc813 --- /dev/null +++ b/MCP/go/config/config.go @@ -0,0 +1,48 @@ +package config + +import ( + "fmt" + "os" +) + +type APIConfig struct { + BaseURL string + BearerToken string // For OAuth2/Bearer authentication + APIKey string // For API key authentication + BasicAuth string // For basic authentication + Port string // For server port configuration +} + +func LoadAPIConfig() (*APIConfig, error) { + // Check port environment variable (both uppercase and lowercase) + port := os.Getenv("PORT") + if port == "" { + port = os.Getenv("port") + } + + baseURL := os.Getenv("API_BASE_URL") + + // Check transport environment variable (both uppercase and lowercase) + transport := os.Getenv("TRANSPORT") + if transport == "" { + transport = os.Getenv("transport") + } + + // For STDIO mode (transport is not "http"/"HTTP"/"https"/"HTTPS"), API_BASE_URL is required from environment + if transport != "http" && transport != "HTTP" && transport != "https" && transport != "HTTPS" && baseURL == "" { + return nil, fmt.Errorf("API_BASE_URL environment variable not set") + } + + // For HTTP/HTTPS mode (transport is "http"/"HTTP"/"https"/"HTTPS"), API_BASE_URL comes from headers + // so we don't require it from environment variables + + return &APIConfig{ + BaseURL: baseURL, + BearerToken: os.Getenv("BEARER_TOKEN"), + APIKey: os.Getenv("API_KEY"), + BasicAuth: os.Getenv("BASIC_AUTH"), + Port: port, + }, nil +} + + diff --git a/MCP/go/go.mod b/MCP/go/go.mod new file mode 100644 index 0000000..b413626 --- /dev/null +++ b/MCP/go/go.mod @@ -0,0 +1,17 @@ +module github.com/slack-web-api/mcp-server + +go 1.24.4 + +require github.com/mark3labs/mcp-go v0.39.1 + +require ( + github.com/bahlo/generic-list-go v0.2.0 // indirect + github.com/buger/jsonparser v1.1.1 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/invopop/jsonschema v0.13.0 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/spf13/cast v1.7.1 // indirect + github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect + github.com/yosida95/uritemplate/v3 v3.0.2 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/MCP/go/go.sum b/MCP/go/go.sum new file mode 100644 index 0000000..4bdf8a4 --- /dev/null +++ b/MCP/go/go.sum @@ -0,0 +1,39 @@ +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/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +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/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +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/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/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mark3labs/mcp-go v0.39.1 h1:2oPxk7aDbQhouakkYyKl2T4hKFU1c6FDaubWyGyVE1k= +github.com/mark3labs/mcp-go v0.39.1/go.mod h1:T7tUa2jO6MavG+3P25Oy/jR7iCeJPHImCZHRymCn39g= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/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/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y= +github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +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/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= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/MCP/go/main.go b/MCP/go/main.go new file mode 100644 index 0000000..680e8fd --- /dev/null +++ b/MCP/go/main.go @@ -0,0 +1,145 @@ +package main + +import ( + "context" + "log" + "net" + "net/http" + "os" + "os/signal" + "syscall" + "time" + + "github.com/mark3labs/mcp-go/server" + "github.com/slack-web-api/mcp-server/config" +) + +func main() { + cfg, err := config.LoadAPIConfig() + if err != nil { + log.Fatalf("Failed to load config: %v", err) + } + + // Check transport environment variable (both uppercase and lowercase) + transport := os.Getenv("TRANSPORT") + if transport == "" { + transport = os.Getenv("transport") + } + sigChan := make(chan os.Signal, 1) + signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) + + // HTTP/HTTPS Mode - if transport is "http", "HTTP", "https", or "HTTPS" + if transport == "http" || transport == "HTTP" || transport == "https" || transport == "HTTPS" { + port := cfg.Port + if port == "" { + log.Fatalf("PORT environment variable is required for HTTP/HTTPS mode. Please set PORT environment variable.") + } + + // Determine if HTTPS mode and normalize transport + isHTTPS := transport == "https" || transport == "HTTPS" + if isHTTPS { + transport = "HTTPS" + } else { + transport = "HTTP" + } + + log.Printf("Running in %s mode on port %s", transport, port) + + mux := http.NewServeMux() + mux.HandleFunc("/mcp", func(w http.ResponseWriter, r *http.Request) { + // Read headers for dynamic config + apiCfg := &config.APIConfig{ + BaseURL: r.Header.Get("API_BASE_URL"), + BearerToken: r.Header.Get("BEARER_TOKEN"), + APIKey: r.Header.Get("API_KEY"), + BasicAuth: r.Header.Get("BASIC_AUTH"), + } + + if apiCfg.BaseURL == "" { + http.Error(w, "Missing API_BASE_URL header", http.StatusBadRequest) + return + } + + log.Printf("Incoming HTTP request - BaseURL: %s", apiCfg.BaseURL) + + // Create MCP server for this request + mcpSrv := createMCPServer(apiCfg, transport) + handler := server.NewStreamableHTTPServer(mcpSrv, server.WithHTTPContextFunc( + func(ctx context.Context, req *http.Request) context.Context { + return context.WithValue(ctx, "apiConfig", apiCfg) + }, + )) + + handler.ServeHTTP(w, r) + }) + + mux.HandleFunc("/", func(w http.ResponseWriter, _ *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.Write([]byte(`{"status":"ok"}`)) + }) + + addr := net.JoinHostPort("0.0.0.0", port) + httpServer := &http.Server{Addr: addr, Handler: mux} + + go func() { + // Check if HTTPS mode + if isHTTPS { + certFile := os.Getenv("CERT_FILE") + keyFile := os.Getenv("KEY_FILE") + + if certFile == "" || keyFile == "" { + log.Fatalf("CERT_FILE and KEY_FILE environment variables are required for HTTPS mode") + } + + log.Printf("Starting HTTPS server on %s", addr) + if err := httpServer.ListenAndServeTLS(certFile, keyFile); err != http.ErrServerClosed { + log.Fatalf("HTTPS server error: %v", err) + } + } else { + log.Printf("Starting HTTP server on %s", addr) + if err := httpServer.ListenAndServe(); err != http.ErrServerClosed { + log.Fatalf("HTTP server error: %v", err) + } + } + }() + + <-sigChan + log.Println("Shutdown signal received") + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + if err := httpServer.Shutdown(ctx); err != nil { + log.Printf("Shutdown error: %v", err) + } else { + log.Println("HTTP server shutdown complete") + } + return + } + + // STDIO Mode - default when no transport or transport is "stdio" + log.Println("Running in STDIO mode") + mcp := createMCPServer(cfg, "STDIO") + go func() { + if err := server.ServeStdio(mcp); err != nil { + log.Fatalf("STDIO error: %v", err) + } + }() + <-sigChan + log.Println("Received shutdown signal. Exiting STDIO mode.") +} + +func createMCPServer(cfg *config.APIConfig, mode string) *server.MCPServer { + mcp := server.NewMCPServer("Slack Web API", "1.7.0", + server.WithToolCapabilities(true), + server.WithRecovery(), + ) + + tools := GetAll(cfg) + log.Printf("Loaded %d tools for %s mode", len(tools), mode) + + for _, tool := range tools { + mcp.AddTool(tool.Definition, tool.Handler) + } + + return mcp +} \ No newline at end of file diff --git a/MCP/go/models/models.go b/MCP/go/models/models.go new file mode 100644 index 0000000..0ed6649 --- /dev/null +++ b/MCP/go/models/models.go @@ -0,0 +1,391 @@ +package models + +import ( + "context" + "github.com/mark3labs/mcp-go/mcp" +) + +type Tool struct { + Definition mcp.Tool + Handler func(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) +} + +// Objssubteam represents the Objssubteam schema from the OpenAPI specification +type Objssubteam struct { + Description string `json:"description"` + Id string `json:"id"` + Date_update int `json:"date_update"` + Is_subteam bool `json:"is_subteam"` + Updated_by string `json:"updated_by"` + Auto_provision bool `json:"auto_provision"` + Auto_type map[string]interface{} `json:"auto_type"` + Channel_count int `json:"channel_count,omitempty"` + Enterprise_subteam_id string `json:"enterprise_subteam_id"` + Handle string `json:"handle"` + Date_delete int `json:"date_delete"` + Name string `json:"name"` + User_count int `json:"user_count,omitempty"` + Is_external bool `json:"is_external"` + Is_usergroup bool `json:"is_usergroup"` + Deleted_by map[string]interface{} `json:"deleted_by"` + Prefs map[string]interface{} `json:"prefs"` + Created_by string `json:"created_by"` + Users []string `json:"users,omitempty"` + Date_create int `json:"date_create"` + Team_id string `json:"team_id"` +} + +// Objsuser represents the Objsuser schema from the OpenAPI specification +type Objsuser struct { +} + +// Objsuserprofileshort represents the Objsuserprofileshort schema from the OpenAPI specification +type Objsuserprofileshort struct { + Display_name_normalized string `json:"display_name_normalized,omitempty"` + Real_name string `json:"real_name"` + Is_restricted bool `json:"is_restricted"` + Image_72 string `json:"image_72"` + Name string `json:"name"` + Team string `json:"team"` + Is_ultra_restricted bool `json:"is_ultra_restricted"` + Real_name_normalized string `json:"real_name_normalized,omitempty"` + Avatar_hash string `json:"avatar_hash"` + Display_name string `json:"display_name"` +} + +// Objsresponsemetadata represents the Objsresponsemetadata schema from the OpenAPI specification +type Objsresponsemetadata struct { +} + +// Objscomment represents the Objscomment schema from the OpenAPI specification +type Objscomment struct { + User string `json:"user"` + Reactions []Objsreaction `json:"reactions,omitempty"` + Created int `json:"created"` + Id string `json:"id"` + Is_starred bool `json:"is_starred,omitempty"` + Is_intro bool `json:"is_intro"` + Num_stars int `json:"num_stars,omitempty"` + Pinned_to []string `json:"pinned_to,omitempty"` + Comment string `json:"comment"` + Pinned_info Defspinnedinfo `json:"pinned_info,omitempty"` + Timestamp int `json:"timestamp"` +} + +// Objsprimaryowner represents the Objsprimaryowner schema from the OpenAPI specification +type Objsprimaryowner struct { + Email string `json:"email"` + Id string `json:"id"` +} + +// Objsreaction represents the Objsreaction schema from the OpenAPI specification +type Objsreaction struct { + Users []string `json:"users"` + Count int `json:"count"` + Name string `json:"name"` +} + +// Objsbotprofile represents the Objsbotprofile schema from the OpenAPI specification +type Objsbotprofile struct { + Deleted bool `json:"deleted"` + Icons map[string]interface{} `json:"icons"` + Id string `json:"id"` + Name string `json:"name"` + Team_id string `json:"team_id"` + Updated int `json:"updated"` + App_id string `json:"app_id"` +} + +// Objsteamprofilefieldoption represents the Objsteamprofilefieldoption schema from the OpenAPI specification +type Objsteamprofilefieldoption struct { +} + +// Objschannel represents the Objschannel schema from the OpenAPI specification +type Objschannel struct { + Creator string `json:"creator"` + Is_pending_ext_shared bool `json:"is_pending_ext_shared,omitempty"` + Unread_count int `json:"unread_count,omitempty"` + Is_general bool `json:"is_general,omitempty"` + Is_read_only bool `json:"is_read_only,omitempty"` + Is_member bool `json:"is_member,omitempty"` + Is_org_shared bool `json:"is_org_shared"` + Latest map[string]interface{} `json:"latest,omitempty"` + Purpose map[string]interface{} `json:"purpose"` + Is_mpim bool `json:"is_mpim"` + Name string `json:"name"` + Name_normalized string `json:"name_normalized"` + Id string `json:"id"` + Num_members int `json:"num_members,omitempty"` + Pending_shared []string `json:"pending_shared,omitempty"` + Is_frozen bool `json:"is_frozen,omitempty"` + Is_thread_only bool `json:"is_thread_only,omitempty"` + Members []string `json:"members"` + Is_private bool `json:"is_private"` + Topic map[string]interface{} `json:"topic"` + Unread_count_display int `json:"unread_count_display,omitempty"` + Is_archived bool `json:"is_archived,omitempty"` + Is_shared bool `json:"is_shared"` + Is_channel bool `json:"is_channel"` + Is_non_threadable bool `json:"is_non_threadable,omitempty"` + Last_read string `json:"last_read,omitempty"` + Created int `json:"created"` + Is_moved int `json:"is_moved,omitempty"` + Accepted_user string `json:"accepted_user,omitempty"` + Previous_names []string `json:"previous_names,omitempty"` + Priority float64 `json:"priority,omitempty"` + Unlinked int `json:"unlinked,omitempty"` +} + +// Defspinnedinfo represents the Defspinnedinfo schema from the OpenAPI specification +type Defspinnedinfo struct { +} + +// Objsuserprofile represents the Objsuserprofile schema from the OpenAPI specification +type Objsuserprofile struct { + Display_name_normalized string `json:"display_name_normalized"` + Status_default_text string `json:"status_default_text,omitempty"` + Last_avatar_image_hash string `json:"last_avatar_image_hash,omitempty"` + Phone string `json:"phone"` + Pronouns string `json:"pronouns,omitempty"` + Memberships_count int `json:"memberships_count,omitempty"` + Title string `json:"title"` + Api_app_id string `json:"api_app_id,omitempty"` + Status_text string `json:"status_text"` + Skype string `json:"skype"` + Status_default_emoji string `json:"status_default_emoji,omitempty"` + Status_emoji string `json:"status_emoji"` + Real_name string `json:"real_name"` + User_id string `json:"user_id,omitempty"` + Is_app_user bool `json:"is_app_user,omitempty"` + Is_custom_image bool `json:"is_custom_image,omitempty"` + Real_name_normalized string `json:"real_name_normalized"` + Always_active bool `json:"always_active,omitempty"` + Team string `json:"team,omitempty"` + Avatar_hash string `json:"avatar_hash"` + Updated int `json:"updated,omitempty"` + Status_expiration int `json:"status_expiration,omitempty"` + Bot_id string `json:"bot_id,omitempty"` + Display_name string `json:"display_name"` +} + +// Objsfile represents the Objsfile schema from the OpenAPI specification +type Objsfile struct { + Editor string `json:"editor,omitempty"` + Original_h int `json:"original_h,omitempty"` + Thumb_1024_h int `json:"thumb_1024_h,omitempty"` + Thumb_720 string `json:"thumb_720,omitempty"` + External_id string `json:"external_id,omitempty"` + Thumb_360 string `json:"thumb_360,omitempty"` + Id string `json:"id,omitempty"` + Pinned_to []string `json:"pinned_to,omitempty"` + Title string `json:"title,omitempty"` + Source_team string `json:"source_team,omitempty"` + Comments_count int `json:"comments_count,omitempty"` + Editable bool `json:"editable,omitempty"` + Thumb_960 string `json:"thumb_960,omitempty"` + Date_delete int `json:"date_delete,omitempty"` + Is_tombstoned bool `json:"is_tombstoned,omitempty"` + Thumb_480 string `json:"thumb_480,omitempty"` + Timestamp int `json:"timestamp,omitempty"` + Thumb_1024_w int `json:"thumb_1024_w,omitempty"` + Thumb_480_h int `json:"thumb_480_h,omitempty"` + Is_starred bool `json:"is_starred,omitempty"` + Thumb_960_h int `json:"thumb_960_h,omitempty"` + Thumb_1024 string `json:"thumb_1024,omitempty"` + Thumb_720_h int `json:"thumb_720_h,omitempty"` + Thumb_64 string `json:"thumb_64,omitempty"` + Created int `json:"created,omitempty"` + External_type string `json:"external_type,omitempty"` + Thumb_800_h int `json:"thumb_800_h,omitempty"` + Username string `json:"username,omitempty"` + Channels []string `json:"channels,omitempty"` + Mimetype string `json:"mimetype,omitempty"` + State string `json:"state,omitempty"` + Has_rich_preview bool `json:"has_rich_preview,omitempty"` + Url_private string `json:"url_private,omitempty"` + Public_url_shared bool `json:"public_url_shared,omitempty"` + Mode string `json:"mode,omitempty"` + Thumb_80 string `json:"thumb_80,omitempty"` + Permalink_public string `json:"permalink_public,omitempty"` + External_url string `json:"external_url,omitempty"` + Display_as_bot bool `json:"display_as_bot,omitempty"` + Ims []string `json:"ims,omitempty"` + Thumb_480_w int `json:"thumb_480_w,omitempty"` + Thumb_800 string `json:"thumb_800,omitempty"` + User_team string `json:"user_team,omitempty"` + Thumb_360_w int `json:"thumb_360_w,omitempty"` + Thumb_800_w int `json:"thumb_800_w,omitempty"` + Groups []string `json:"groups,omitempty"` + Permalink string `json:"permalink,omitempty"` + Thumb_360_h int `json:"thumb_360_h,omitempty"` + Pretty_type string `json:"pretty_type,omitempty"` + Last_editor string `json:"last_editor,omitempty"` + Image_exif_rotation int `json:"image_exif_rotation,omitempty"` + Shares map[string]interface{} `json:"shares,omitempty"` + Pinned_info Defspinnedinfo `json:"pinned_info,omitempty"` + Name string `json:"name,omitempty"` + Original_w int `json:"original_w,omitempty"` + Filetype string `json:"filetype,omitempty"` + Non_owner_editable bool `json:"non_owner_editable,omitempty"` + Updated int `json:"updated,omitempty"` + Is_public bool `json:"is_public,omitempty"` + Thumb_960_w int `json:"thumb_960_w,omitempty"` + User string `json:"user,omitempty"` + Preview string `json:"preview,omitempty"` + Is_external bool `json:"is_external,omitempty"` + Num_stars int `json:"num_stars,omitempty"` + Thumb_tiny string `json:"thumb_tiny,omitempty"` + Thumb_160 string `json:"thumb_160,omitempty"` + Reactions []Objsreaction `json:"reactions,omitempty"` + Thumb_720_w int `json:"thumb_720_w,omitempty"` + Url_private_download string `json:"url_private_download,omitempty"` + Size int `json:"size,omitempty"` +} + +// Objsreminder represents the Objsreminder schema from the OpenAPI specification +type Objsreminder struct { + User string `json:"user"` + Complete_ts int `json:"complete_ts,omitempty"` + Creator string `json:"creator"` + Id string `json:"id"` + Recurring bool `json:"recurring"` + Text string `json:"text"` + Time int `json:"time,omitempty"` +} + +// Objsteam represents the Objsteam schema from the OpenAPI specification +type Objsteam struct { + Id string `json:"id"` + Is_assigned bool `json:"is_assigned,omitempty"` + Over_integrations_limit bool `json:"over_integrations_limit,omitempty"` + Sso_provider map[string]interface{} `json:"sso_provider,omitempty"` + Is_enterprise int `json:"is_enterprise,omitempty"` + Msg_edit_window_mins int `json:"msg_edit_window_mins,omitempty"` + Deleted bool `json:"deleted,omitempty"` + Discoverable map[string]interface{} `json:"discoverable,omitempty"` + Primary_owner Objsprimaryowner `json:"primary_owner,omitempty"` + Domain string `json:"domain"` + External_org_migrations Objsexternalorgmigrations `json:"external_org_migrations,omitempty"` + Icon Objsicon `json:"icon"` + Over_storage_limit bool `json:"over_storage_limit,omitempty"` + Avatar_base_url string `json:"avatar_base_url,omitempty"` + Created int `json:"created,omitempty"` + Locale string `json:"locale,omitempty"` + Date_create int `json:"date_create,omitempty"` + Enterprise_id string `json:"enterprise_id,omitempty"` + Name string `json:"name"` + Email_domain string `json:"email_domain"` + Is_over_storage_limit bool `json:"is_over_storage_limit,omitempty"` + Pay_prod_cur string `json:"pay_prod_cur,omitempty"` + Enterprise_name string `json:"enterprise_name,omitempty"` + Messages_count int `json:"messages_count,omitempty"` + Archived bool `json:"archived,omitempty"` + Has_compliance_export bool `json:"has_compliance_export,omitempty"` + Limit_ts int `json:"limit_ts,omitempty"` + Plan string `json:"plan,omitempty"` +} + +// Objsmessage represents the Objsmessage schema from the OpenAPI specification +type Objsmessage struct { + Team string `json:"team,omitempty"` + Pinned_to []string `json:"pinned_to,omitempty"` + Text string `json:"text"` + Purpose string `json:"purpose,omitempty"` + Attachments []map[string]interface{} `json:"attachments,omitempty"` + Name string `json:"name,omitempty"` + Subscribed bool `json:"subscribed,omitempty"` + Unread_count int `json:"unread_count,omitempty"` + Bot_id map[string]interface{} `json:"bot_id,omitempty"` + Client_msg_id string `json:"client_msg_id,omitempty"` + Files []Objsfile `json:"files,omitempty"` + User_profile Objsuserprofileshort `json:"user_profile,omitempty"` + Last_read string `json:"last_read,omitempty"` + Parent_user_id string `json:"parent_user_id,omitempty"` + Is_starred bool `json:"is_starred,omitempty"` + Subtype string `json:"subtype,omitempty"` + File Objsfile `json:"file,omitempty"` + TypeField string `json:"type"` + Reply_users_count int `json:"reply_users_count,omitempty"` + Is_intro bool `json:"is_intro,omitempty"` + Reactions []Objsreaction `json:"reactions,omitempty"` + Inviter string `json:"inviter,omitempty"` + Reply_users []string `json:"reply_users,omitempty"` + Thread_ts string `json:"thread_ts,omitempty"` + Upload bool `json:"upload,omitempty"` + Display_as_bot bool `json:"display_as_bot,omitempty"` + Old_name string `json:"old_name,omitempty"` + Reply_count int `json:"reply_count,omitempty"` + Bot_profile Objsbotprofile `json:"bot_profile,omitempty"` + Is_delayed_message bool `json:"is_delayed_message,omitempty"` + Source_team string `json:"source_team,omitempty"` + Username string `json:"username,omitempty"` + Icons map[string]interface{} `json:"icons,omitempty"` + Latest_reply string `json:"latest_reply,omitempty"` + User string `json:"user,omitempty"` + Comment Objscomment `json:"comment,omitempty"` + Permalink string `json:"permalink,omitempty"` + Blocks []map[string]interface{} `json:"blocks,omitempty"` // This is a very loose definition, in the future, we'll populate this with deeper schema in this definition namespace. + Ts string `json:"ts"` + Topic string `json:"topic,omitempty"` + User_team string `json:"user_team,omitempty"` +} + +// Objsenterpriseuser represents the Objsenterpriseuser schema from the OpenAPI specification +type Objsenterpriseuser struct { + Enterprise_name string `json:"enterprise_name"` + Id string `json:"id"` + Is_admin bool `json:"is_admin"` + Is_owner bool `json:"is_owner"` + Teams []string `json:"teams"` + Enterprise_id string `json:"enterprise_id"` +} + +// Objsconversation represents the Objsconversation schema from the OpenAPI specification +type Objsconversation struct { +} + +// Objsteamprofilefield represents the Objsteamprofilefield schema from the OpenAPI specification +type Objsteamprofilefield struct { + Is_hidden bool `json:"is_hidden,omitempty"` + Label string `json:"label"` + Options map[string]interface{} `json:"options,omitempty"` + Ordering float64 `json:"ordering"` + TypeField string `json:"type"` + Hint string `json:"hint"` + Id string `json:"id"` +} + +// Objsicon represents the Objsicon schema from the OpenAPI specification +type Objsicon struct { + Image_230 string `json:"image_230,omitempty"` + Image_34 string `json:"image_34,omitempty"` + Image_44 string `json:"image_44,omitempty"` + Image_68 string `json:"image_68,omitempty"` + Image_88 string `json:"image_88,omitempty"` + Image_default bool `json:"image_default,omitempty"` + Image_102 string `json:"image_102,omitempty"` + Image_132 string `json:"image_132,omitempty"` +} + +// Objsexternalorgmigrations represents the Objsexternalorgmigrations schema from the OpenAPI specification +type Objsexternalorgmigrations struct { + Current []map[string]interface{} `json:"current"` + Date_updated int `json:"date_updated"` +} + +// Objspaging represents the Objspaging schema from the OpenAPI specification +type Objspaging struct { + Per_page int `json:"per_page,omitempty"` + Spill int `json:"spill,omitempty"` + Total int `json:"total"` + Count int `json:"count,omitempty"` + Page int `json:"page"` + Pages int `json:"pages,omitempty"` +} + +// Objsresources represents the Objsresources schema from the OpenAPI specification +type Objsresources struct { + Ids []map[string]interface{} `json:"ids"` + Wildcard bool `json:"wildcard,omitempty"` + Excluded_ids []map[string]interface{} `json:"excluded_ids,omitempty"` +} diff --git a/MCP/go/registry.go b/MCP/go/registry.go new file mode 100644 index 0000000..1da10ae --- /dev/null +++ b/MCP/go/registry.go @@ -0,0 +1,225 @@ +package main + +import ( + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + tools_admin_conversations "github.com/slack-web-api/mcp-server/tools/admin_conversations" + tools_admin_teams_admins "github.com/slack-web-api/mcp-server/tools/admin_teams_admins" + tools_users "github.com/slack-web-api/mcp-server/tools/users" + tools_admin_conversations_ekm "github.com/slack-web-api/mcp-server/tools/admin_conversations_ekm" + tools_admin_usergroups "github.com/slack-web-api/mcp-server/tools/admin_usergroups" + tools_usergroups "github.com/slack-web-api/mcp-server/tools/usergroups" + tools_views "github.com/slack-web-api/mcp-server/tools/views" + tools_apps_permissions_resources "github.com/slack-web-api/mcp-server/tools/apps_permissions_resources" + tools_reactions "github.com/slack-web-api/mcp-server/tools/reactions" + tools_dnd "github.com/slack-web-api/mcp-server/tools/dnd" + tools_admin_teams "github.com/slack-web-api/mcp-server/tools/admin_teams" + tools_files "github.com/slack-web-api/mcp-server/tools/files" + tools_reminders "github.com/slack-web-api/mcp-server/tools/reminders" + tools_admin_users "github.com/slack-web-api/mcp-server/tools/admin_users" + tools_calls_participants "github.com/slack-web-api/mcp-server/tools/calls_participants" + tools_conversations "github.com/slack-web-api/mcp-server/tools/conversations" + tools_usergroups_users "github.com/slack-web-api/mcp-server/tools/usergroups_users" + tools_admin_teams_settings "github.com/slack-web-api/mcp-server/tools/admin_teams_settings" + tools_admin_apps_requests "github.com/slack-web-api/mcp-server/tools/admin_apps_requests" + tools_workflows "github.com/slack-web-api/mcp-server/tools/workflows" + tools_admin_emoji "github.com/slack-web-api/mcp-server/tools/admin_emoji" + tools_admin_users_session "github.com/slack-web-api/mcp-server/tools/admin_users_session" + tools_dialog "github.com/slack-web-api/mcp-server/tools/dialog" + tools_admin_inviterequests_approved "github.com/slack-web-api/mcp-server/tools/admin_inviterequests_approved" + tools_admin_inviterequests "github.com/slack-web-api/mcp-server/tools/admin_inviterequests" + tools_apps_event_authorizations "github.com/slack-web-api/mcp-server/tools/apps_event_authorizations" + tools_migration "github.com/slack-web-api/mcp-server/tools/migration" + tools_admin_conversations_restrictaccess "github.com/slack-web-api/mcp-server/tools/admin_conversations_restrictaccess" + tools_oauth "github.com/slack-web-api/mcp-server/tools/oauth" + tools_stars "github.com/slack-web-api/mcp-server/tools/stars" + tools_auth "github.com/slack-web-api/mcp-server/tools/auth" + tools_users_profile "github.com/slack-web-api/mcp-server/tools/users_profile" + tools_apps_permissions_users "github.com/slack-web-api/mcp-server/tools/apps_permissions_users" + tools_apps_permissions "github.com/slack-web-api/mcp-server/tools/apps_permissions" + tools_pins "github.com/slack-web-api/mcp-server/tools/pins" + tools_chat "github.com/slack-web-api/mcp-server/tools/chat" + tools_team "github.com/slack-web-api/mcp-server/tools/team" + tools_calls "github.com/slack-web-api/mcp-server/tools/calls" + tools_bots "github.com/slack-web-api/mcp-server/tools/bots" + tools_files_remote "github.com/slack-web-api/mcp-server/tools/files_remote" + tools_files_comments "github.com/slack-web-api/mcp-server/tools/files_comments" + tools_admin_teams_owners "github.com/slack-web-api/mcp-server/tools/admin_teams_owners" + tools_api "github.com/slack-web-api/mcp-server/tools/api" + tools_apps_permissions_scopes "github.com/slack-web-api/mcp-server/tools/apps_permissions_scopes" + tools_admin_apps "github.com/slack-web-api/mcp-server/tools/admin_apps" + tools_admin_inviterequests_denied "github.com/slack-web-api/mcp-server/tools/admin_inviterequests_denied" + tools_admin_apps_restricted "github.com/slack-web-api/mcp-server/tools/admin_apps_restricted" + tools_rtm "github.com/slack-web-api/mcp-server/tools/rtm" + tools_emoji "github.com/slack-web-api/mcp-server/tools/emoji" + tools_team_profile "github.com/slack-web-api/mcp-server/tools/team_profile" + tools_admin_apps_approved "github.com/slack-web-api/mcp-server/tools/admin_apps_approved" + tools_oauth_v2 "github.com/slack-web-api/mcp-server/tools/oauth_v2" + tools_search "github.com/slack-web-api/mcp-server/tools/search" + tools_apps "github.com/slack-web-api/mcp-server/tools/apps" + tools_chat_scheduledmessages "github.com/slack-web-api/mcp-server/tools/chat_scheduledmessages" +) + +func GetAll(cfg *config.APIConfig) []models.Tool { + return []models.Tool{ + tools_admin_conversations.CreateAdmin_conversations_deleteTool(cfg), + tools_admin_teams_admins.CreateAdmin_teams_admins_listTool(cfg), + tools_users.CreateUsers_lookupbyemailTool(cfg), + tools_admin_conversations_ekm.CreateAdmin_conversations_ekm_listoriginalconnectedchannelinfoTool(cfg), + tools_admin_usergroups.CreateAdmin_usergroups_removechannelsTool(cfg), + tools_usergroups.CreateUsergroups_createTool(cfg), + tools_views.CreateViews_openTool(cfg), + tools_apps_permissions_resources.CreateApps_permissions_resources_listTool(cfg), + tools_users.CreateUsers_infoTool(cfg), + tools_reactions.CreateReactions_getTool(cfg), + tools_dnd.CreateDnd_endsnoozeTool(cfg), + tools_admin_teams.CreateAdmin_teams_createTool(cfg), + tools_files.CreateFiles_revokepublicurlTool(cfg), + tools_reminders.CreateReminders_infoTool(cfg), + tools_users.CreateUsers_listTool(cfg), + tools_admin_users.CreateAdmin_users_setownerTool(cfg), + tools_reminders.CreateReminders_listTool(cfg), + tools_calls_participants.CreateCalls_participants_addTool(cfg), + tools_conversations.CreateConversations_settopicTool(cfg), + tools_usergroups_users.CreateUsergroups_users_listTool(cfg), + tools_admin_conversations.CreateAdmin_conversations_getconversationprefsTool(cfg), + tools_admin_usergroups.CreateAdmin_usergroups_addchannelsTool(cfg), + tools_reminders.CreateReminders_completeTool(cfg), + tools_admin_teams_settings.CreateAdmin_teams_settings_setnameTool(cfg), + tools_usergroups.CreateUsergroups_listTool(cfg), + tools_conversations.CreateConversations_historyTool(cfg), + tools_admin_apps_requests.CreateAdmin_apps_requests_listTool(cfg), + tools_conversations.CreateConversations_closeTool(cfg), + tools_admin_teams_settings.CreateAdmin_teams_settings_infoTool(cfg), + tools_workflows.CreateWorkflows_stepfailedTool(cfg), + tools_admin_emoji.CreateAdmin_emoji_listTool(cfg), + tools_admin_users_session.CreateAdmin_users_session_resetTool(cfg), + tools_dialog.CreateDialog_openTool(cfg), + tools_reminders.CreateReminders_deleteTool(cfg), + tools_admin_inviterequests_approved.CreateAdmin_inviterequests_approved_listTool(cfg), + tools_admin_inviterequests.CreateAdmin_inviterequests_denyTool(cfg), + tools_conversations.CreateConversations_setpurposeTool(cfg), + tools_conversations.CreateConversations_infoTool(cfg), + tools_conversations.CreateConversations_joinTool(cfg), + tools_apps_event_authorizations.CreateApps_event_authorizations_listTool(cfg), + tools_admin_users.CreateAdmin_users_assignTool(cfg), + tools_migration.CreateMigration_exchangeTool(cfg), + tools_admin_conversations_restrictaccess.CreateAdmin_conversations_restrictaccess_listgroupsTool(cfg), + tools_oauth.CreateOauth_tokenTool(cfg), + tools_conversations.CreateConversations_markTool(cfg), + tools_stars.CreateStars_removeTool(cfg), + tools_admin_users.CreateAdmin_users_inviteTool(cfg), + tools_reactions.CreateReactions_removeTool(cfg), + tools_auth.CreateAuth_revokeTool(cfg), + tools_stars.CreateStars_listTool(cfg), + tools_admin_conversations.CreateAdmin_conversations_setconversationprefsTool(cfg), + tools_conversations.CreateConversations_leaveTool(cfg), + tools_files.CreateFiles_listTool(cfg), + tools_admin_conversations.CreateAdmin_conversations_searchTool(cfg), + tools_conversations.CreateConversations_unarchiveTool(cfg), + tools_users_profile.CreateUsers_profile_setTool(cfg), + tools_users.CreateUsers_conversationsTool(cfg), + tools_usergroups.CreateUsergroups_updateTool(cfg), + tools_reactions.CreateReactions_listTool(cfg), + tools_apps_permissions_users.CreateApps_permissions_users_listTool(cfg), + tools_files.CreateFiles_infoTool(cfg), + tools_dnd.CreateDnd_enddndTool(cfg), + tools_views.CreateViews_publishTool(cfg), + tools_apps_permissions.CreateApps_permissions_requestTool(cfg), + tools_users.CreateUsers_getpresenceTool(cfg), + tools_conversations.CreateConversations_listTool(cfg), + tools_admin_conversations.CreateAdmin_conversations_setteamsTool(cfg), + tools_admin_conversations.CreateAdmin_conversations_archiveTool(cfg), + tools_admin_inviterequests.CreateAdmin_inviterequests_listTool(cfg), + tools_views.CreateViews_updateTool(cfg), + tools_pins.CreatePins_removeTool(cfg), + tools_pins.CreatePins_listTool(cfg), + tools_calls_participants.CreateCalls_participants_removeTool(cfg), + tools_admin_conversations.CreateAdmin_conversations_inviteTool(cfg), + tools_admin_users.CreateAdmin_users_setadminTool(cfg), + tools_admin_conversations.CreateAdmin_conversations_getteamsTool(cfg), + tools_conversations.CreateConversations_membersTool(cfg), + tools_chat.CreateChat_updateTool(cfg), + tools_apps_permissions_users.CreateApps_permissions_users_requestTool(cfg), + tools_team.CreateTeam_accesslogsTool(cfg), + tools_users_profile.CreateUsers_profile_getTool(cfg), + tools_conversations.CreateConversations_renameTool(cfg), + tools_dnd.CreateDnd_teaminfoTool(cfg), + tools_conversations.CreateConversations_repliesTool(cfg), + tools_conversations.CreateConversations_kickTool(cfg), + tools_pins.CreatePins_addTool(cfg), + tools_workflows.CreateWorkflows_updatestepTool(cfg), + tools_admin_conversations.CreateAdmin_conversations_disconnectsharedTool(cfg), + tools_users.CreateUsers_setpresenceTool(cfg), + tools_team.CreateTeam_integrationlogsTool(cfg), + tools_files.CreateFiles_sharedpublicurlTool(cfg), + tools_calls.CreateCalls_addTool(cfg), + tools_bots.CreateBots_infoTool(cfg), + tools_chat.CreateChat_unfurlTool(cfg), + tools_files_remote.CreateFiles_remote_listTool(cfg), + tools_files_comments.CreateFiles_comments_deleteTool(cfg), + tools_admin_usergroups.CreateAdmin_usergroups_listchannelsTool(cfg), + tools_admin_conversations.CreateAdmin_conversations_unarchiveTool(cfg), + tools_admin_teams_owners.CreateAdmin_teams_owners_listTool(cfg), + tools_api.CreateApi_test_handlerTool(cfg), + tools_calls.CreateCalls_endTool(cfg), + tools_usergroups_users.CreateUsergroups_users_updateTool(cfg), + tools_conversations.CreateConversations_createTool(cfg), + tools_apps_permissions_scopes.CreateApps_permissions_scopes_listTool(cfg), + tools_admin_conversations.CreateAdmin_conversations_converttoprivateTool(cfg), + tools_files_remote.CreateFiles_remote_infoTool(cfg), + tools_team.CreateTeam_billableinfoTool(cfg), + tools_admin_teams_settings.CreateAdmin_teams_settings_setdiscoverabilityTool(cfg), + tools_apps_permissions.CreateApps_permissions_infoTool(cfg), + tools_admin_apps.CreateAdmin_apps_restrictTool(cfg), + tools_reactions.CreateReactions_addTool(cfg), + tools_admin_users.CreateAdmin_users_setexpirationTool(cfg), + tools_views.CreateViews_pushTool(cfg), + tools_admin_users.CreateAdmin_users_listTool(cfg), + tools_admin_teams.CreateAdmin_teams_listTool(cfg), + tools_chat.CreateChat_deletescheduledmessageTool(cfg), + tools_admin_inviterequests_denied.CreateAdmin_inviterequests_denied_listTool(cfg), + tools_files_remote.CreateFiles_remote_shareTool(cfg), + tools_chat.CreateChat_postephemeralTool(cfg), + tools_chat.CreateChat_postmessageTool(cfg), + tools_admin_apps_restricted.CreateAdmin_apps_restricted_listTool(cfg), + tools_users.CreateUsers_identityTool(cfg), + tools_dnd.CreateDnd_infoTool(cfg), + tools_auth.CreateAuth_test_handlerTool(cfg), + tools_workflows.CreateWorkflows_stepcompletedTool(cfg), + tools_calls.CreateCalls_infoTool(cfg), + tools_conversations.CreateConversations_openTool(cfg), + tools_rtm.CreateRtm_connectTool(cfg), + tools_conversations.CreateConversations_archiveTool(cfg), + tools_calls.CreateCalls_updateTool(cfg), + tools_emoji.CreateEmoji_listTool(cfg), + tools_team_profile.CreateTeam_profile_getTool(cfg), + tools_stars.CreateStars_addTool(cfg), + tools_conversations.CreateConversations_inviteTool(cfg), + tools_files.CreateFiles_deleteTool(cfg), + tools_team.CreateTeam_infoTool(cfg), + tools_admin_conversations.CreateAdmin_conversations_renameTool(cfg), + tools_admin_usergroups.CreateAdmin_usergroups_addteamsTool(cfg), + tools_admin_apps_approved.CreateAdmin_apps_approved_listTool(cfg), + tools_chat.CreateChat_schedulemessageTool(cfg), + tools_usergroups.CreateUsergroups_disableTool(cfg), + tools_oauth_v2.CreateOauth_v2_accessTool(cfg), + tools_search.CreateSearch_messagesTool(cfg), + tools_admin_apps.CreateAdmin_apps_approveTool(cfg), + tools_admin_teams_settings.CreateAdmin_teams_settings_setdescriptionTool(cfg), + tools_chat.CreateChat_deleteTool(cfg), + tools_chat.CreateChat_getpermalinkTool(cfg), + tools_reminders.CreateReminders_addTool(cfg), + tools_admin_inviterequests.CreateAdmin_inviterequests_approveTool(cfg), + tools_apps.CreateApps_uninstallTool(cfg), + tools_usergroups.CreateUsergroups_enableTool(cfg), + tools_admin_users_session.CreateAdmin_users_session_invalidateTool(cfg), + tools_chat.CreateChat_memessageTool(cfg), + tools_users.CreateUsers_setactiveTool(cfg), + tools_chat_scheduledmessages.CreateChat_scheduledmessages_listTool(cfg), + tools_oauth.CreateOauth_accessTool(cfg), + tools_admin_users.CreateAdmin_users_setregularTool(cfg), + tools_admin_conversations.CreateAdmin_conversations_createTool(cfg), + tools_admin_users.CreateAdmin_users_removeTool(cfg), + } +} diff --git a/MCP/go/tools/admin_apps/admin_apps_approve.go b/MCP/go/tools/admin_apps/admin_apps_approve.go new file mode 100644 index 0000000..c9f107c --- /dev/null +++ b/MCP/go/tools/admin_apps/admin_apps_approve.go @@ -0,0 +1,101 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_apps_approveHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/admin.apps.approve", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_apps_approveTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_admin_apps_approve", + mcp.WithDescription("Approve an app for installation on a workspace."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.apps:write`")), + mcp.WithString("team_id", mcp.Description("")), + mcp.WithString("app_id", mcp.Description("Input parameter: The id of the app to approve.")), + mcp.WithString("request_id", mcp.Description("Input parameter: The id of the request to approve.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_apps_approveHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_apps/admin_apps_restrict.go b/MCP/go/tools/admin_apps/admin_apps_restrict.go new file mode 100644 index 0000000..57dd9ef --- /dev/null +++ b/MCP/go/tools/admin_apps/admin_apps_restrict.go @@ -0,0 +1,101 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_apps_restrictHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/admin.apps.restrict", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_apps_restrictTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_admin_apps_restrict", + mcp.WithDescription("Restrict an app for installation on a workspace."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.apps:write`")), + mcp.WithString("app_id", mcp.Description("Input parameter: The id of the app to restrict.")), + mcp.WithString("request_id", mcp.Description("Input parameter: The id of the request to restrict.")), + mcp.WithString("team_id", mcp.Description("")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_apps_restrictHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_apps_approved/admin_apps_approved_list.go b/MCP/go/tools/admin_apps_approved/admin_apps_approved_list.go new file mode 100644 index 0000000..2a4d62c --- /dev/null +++ b/MCP/go/tools/admin_apps_approved/admin_apps_approved_list.go @@ -0,0 +1,102 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_apps_approved_listHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["limit"]; ok { + queryParams = append(queryParams, fmt.Sprintf("limit=%v", val)) + } + if val, ok := args["cursor"]; ok { + queryParams = append(queryParams, fmt.Sprintf("cursor=%v", val)) + } + if val, ok := args["team_id"]; ok { + queryParams = append(queryParams, fmt.Sprintf("team_id=%v", val)) + } + if val, ok := args["enterprise_id"]; ok { + queryParams = append(queryParams, fmt.Sprintf("enterprise_id=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/admin.apps.approved.list%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_apps_approved_listTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_admin_apps_approved_list", + mcp.WithDescription("List approved apps for an org or workspace."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.apps:read`")), + mcp.WithNumber("limit", mcp.Description("The maximum number of items to return. Must be between 1 - 1000 both inclusive.")), + mcp.WithString("cursor", mcp.Description("Set `cursor` to `next_cursor` returned by the previous call to list items in the next page")), + mcp.WithString("team_id", mcp.Description("")), + mcp.WithString("enterprise_id", mcp.Description("")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_apps_approved_listHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_apps_requests/admin_apps_requests_list.go b/MCP/go/tools/admin_apps_requests/admin_apps_requests_list.go new file mode 100644 index 0000000..66f8971 --- /dev/null +++ b/MCP/go/tools/admin_apps_requests/admin_apps_requests_list.go @@ -0,0 +1,98 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_apps_requests_listHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["limit"]; ok { + queryParams = append(queryParams, fmt.Sprintf("limit=%v", val)) + } + if val, ok := args["cursor"]; ok { + queryParams = append(queryParams, fmt.Sprintf("cursor=%v", val)) + } + if val, ok := args["team_id"]; ok { + queryParams = append(queryParams, fmt.Sprintf("team_id=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/admin.apps.requests.list%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_apps_requests_listTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_admin_apps_requests_list", + mcp.WithDescription("List app requests for a team/workspace."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.apps:read`")), + mcp.WithNumber("limit", mcp.Description("The maximum number of items to return. Must be between 1 - 1000 both inclusive.")), + mcp.WithString("cursor", mcp.Description("Set `cursor` to `next_cursor` returned by the previous call to list items in the next page")), + mcp.WithString("team_id", mcp.Description("")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_apps_requests_listHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_apps_restricted/admin_apps_restricted_list.go b/MCP/go/tools/admin_apps_restricted/admin_apps_restricted_list.go new file mode 100644 index 0000000..78718c1 --- /dev/null +++ b/MCP/go/tools/admin_apps_restricted/admin_apps_restricted_list.go @@ -0,0 +1,102 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_apps_restricted_listHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["limit"]; ok { + queryParams = append(queryParams, fmt.Sprintf("limit=%v", val)) + } + if val, ok := args["cursor"]; ok { + queryParams = append(queryParams, fmt.Sprintf("cursor=%v", val)) + } + if val, ok := args["team_id"]; ok { + queryParams = append(queryParams, fmt.Sprintf("team_id=%v", val)) + } + if val, ok := args["enterprise_id"]; ok { + queryParams = append(queryParams, fmt.Sprintf("enterprise_id=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/admin.apps.restricted.list%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_apps_restricted_listTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_admin_apps_restricted_list", + mcp.WithDescription("List restricted apps for an org or workspace."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.apps:read`")), + mcp.WithNumber("limit", mcp.Description("The maximum number of items to return. Must be between 1 - 1000 both inclusive.")), + mcp.WithString("cursor", mcp.Description("Set `cursor` to `next_cursor` returned by the previous call to list items in the next page")), + mcp.WithString("team_id", mcp.Description("")), + mcp.WithString("enterprise_id", mcp.Description("")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_apps_restricted_listHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_conversations/admin_conversations_archive.go b/MCP/go/tools/admin_conversations/admin_conversations_archive.go new file mode 100644 index 0000000..2252a84 --- /dev/null +++ b/MCP/go/tools/admin_conversations/admin_conversations_archive.go @@ -0,0 +1,99 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_conversations_archiveHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/admin.conversations.archive", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_conversations_archiveTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_admin_conversations_archive", + mcp.WithDescription("Archive a public or private channel."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.conversations:write`")), + mcp.WithString("channel_id", mcp.Required(), mcp.Description("Input parameter: The channel to archive.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_conversations_archiveHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_conversations/admin_conversations_converttoprivate.go b/MCP/go/tools/admin_conversations/admin_conversations_converttoprivate.go new file mode 100644 index 0000000..f8a24e4 --- /dev/null +++ b/MCP/go/tools/admin_conversations/admin_conversations_converttoprivate.go @@ -0,0 +1,99 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_conversations_converttoprivateHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/admin.conversations.convertToPrivate", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_conversations_converttoprivateTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_admin_conversations_convertToPrivate", + mcp.WithDescription("Convert a public channel to a private channel."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.conversations:write`")), + mcp.WithString("channel_id", mcp.Required(), mcp.Description("Input parameter: The channel to convert to private.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_conversations_converttoprivateHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_conversations/admin_conversations_create.go b/MCP/go/tools/admin_conversations/admin_conversations_create.go new file mode 100644 index 0000000..625e169 --- /dev/null +++ b/MCP/go/tools/admin_conversations/admin_conversations_create.go @@ -0,0 +1,103 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_conversations_createHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/admin.conversations.create", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_conversations_createTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_admin_conversations_create", + mcp.WithDescription("Create a public or private channel-based conversation."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.conversations:write`")), + mcp.WithString("description", mcp.Description("Input parameter: Description of the public or private channel to create.")), + mcp.WithBoolean("is_private", mcp.Required(), mcp.Description("Input parameter: When `true`, creates a private channel instead of a public channel")), + mcp.WithString("name", mcp.Required(), mcp.Description("Input parameter: Name of the public or private channel to create.")), + mcp.WithBoolean("org_wide", mcp.Description("Input parameter: When `true`, the channel will be available org-wide. Note: if the channel is not `org_wide=true`, you must specify a `team_id` for this channel")), + mcp.WithString("team_id", mcp.Description("Input parameter: The workspace to create the channel in. Note: this argument is required unless you set `org_wide=true`.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_conversations_createHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_conversations/admin_conversations_delete.go b/MCP/go/tools/admin_conversations/admin_conversations_delete.go new file mode 100644 index 0000000..a8a1231 --- /dev/null +++ b/MCP/go/tools/admin_conversations/admin_conversations_delete.go @@ -0,0 +1,99 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_conversations_deleteHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/admin.conversations.delete", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_conversations_deleteTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_admin_conversations_delete", + mcp.WithDescription("Delete a public or private channel."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.conversations:write`")), + mcp.WithString("channel_id", mcp.Required(), mcp.Description("Input parameter: The channel to delete.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_conversations_deleteHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_conversations/admin_conversations_disconnectshared.go b/MCP/go/tools/admin_conversations/admin_conversations_disconnectshared.go new file mode 100644 index 0000000..f465858 --- /dev/null +++ b/MCP/go/tools/admin_conversations/admin_conversations_disconnectshared.go @@ -0,0 +1,100 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_conversations_disconnectsharedHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/admin.conversations.disconnectShared", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_conversations_disconnectsharedTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_admin_conversations_disconnectShared", + mcp.WithDescription("Disconnect a connected channel from one or more workspaces."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.conversations:write`")), + mcp.WithString("channel_id", mcp.Required(), mcp.Description("Input parameter: The channel to be disconnected from some workspaces.")), + mcp.WithString("leaving_team_ids", mcp.Description("Input parameter: The team to be removed from the channel. Currently only a single team id can be specified.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_conversations_disconnectsharedHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_conversations/admin_conversations_getconversationprefs.go b/MCP/go/tools/admin_conversations/admin_conversations_getconversationprefs.go new file mode 100644 index 0000000..7c57724 --- /dev/null +++ b/MCP/go/tools/admin_conversations/admin_conversations_getconversationprefs.go @@ -0,0 +1,90 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_conversations_getconversationprefsHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["channel_id"]; ok { + queryParams = append(queryParams, fmt.Sprintf("channel_id=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/admin.conversations.getConversationPrefs%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_conversations_getconversationprefsTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_admin_conversations_getConversationPrefs", + mcp.WithDescription("Get conversation preferences for a public or private channel."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.conversations:read`")), + mcp.WithString("channel_id", mcp.Required(), mcp.Description("The channel to get preferences for.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_conversations_getconversationprefsHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_conversations/admin_conversations_getteams.go b/MCP/go/tools/admin_conversations/admin_conversations_getteams.go new file mode 100644 index 0000000..bd69168 --- /dev/null +++ b/MCP/go/tools/admin_conversations/admin_conversations_getteams.go @@ -0,0 +1,98 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_conversations_getteamsHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["channel_id"]; ok { + queryParams = append(queryParams, fmt.Sprintf("channel_id=%v", val)) + } + if val, ok := args["cursor"]; ok { + queryParams = append(queryParams, fmt.Sprintf("cursor=%v", val)) + } + if val, ok := args["limit"]; ok { + queryParams = append(queryParams, fmt.Sprintf("limit=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/admin.conversations.getTeams%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_conversations_getteamsTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_admin_conversations_getTeams", + mcp.WithDescription("Get all the workspaces a given public or private channel is connected to within this Enterprise org."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.conversations:read`")), + mcp.WithString("channel_id", mcp.Required(), mcp.Description("The channel to determine connected workspaces within the organization for.")), + mcp.WithString("cursor", mcp.Description("Set `cursor` to `next_cursor` returned by the previous call to list items in the next page")), + mcp.WithNumber("limit", mcp.Description("The maximum number of items to return. Must be between 1 - 1000 both inclusive.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_conversations_getteamsHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_conversations/admin_conversations_invite.go b/MCP/go/tools/admin_conversations/admin_conversations_invite.go new file mode 100644 index 0000000..d56beaf --- /dev/null +++ b/MCP/go/tools/admin_conversations/admin_conversations_invite.go @@ -0,0 +1,100 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_conversations_inviteHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/admin.conversations.invite", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_conversations_inviteTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_admin_conversations_invite", + mcp.WithDescription("Invite a user to a public or private channel."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.conversations:write`")), + mcp.WithString("channel_id", mcp.Required(), mcp.Description("Input parameter: The channel that the users will be invited to.")), + mcp.WithString("user_ids", mcp.Required(), mcp.Description("Input parameter: The users to invite.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_conversations_inviteHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_conversations/admin_conversations_rename.go b/MCP/go/tools/admin_conversations/admin_conversations_rename.go new file mode 100644 index 0000000..17a0ed0 --- /dev/null +++ b/MCP/go/tools/admin_conversations/admin_conversations_rename.go @@ -0,0 +1,100 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_conversations_renameHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/admin.conversations.rename", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_conversations_renameTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_admin_conversations_rename", + mcp.WithDescription("Rename a public or private channel."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.conversations:write`")), + mcp.WithString("channel_id", mcp.Required(), mcp.Description("Input parameter: The channel to rename.")), + mcp.WithString("name", mcp.Required(), mcp.Description("")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_conversations_renameHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_conversations/admin_conversations_search.go b/MCP/go/tools/admin_conversations/admin_conversations_search.go new file mode 100644 index 0000000..8dfed12 --- /dev/null +++ b/MCP/go/tools/admin_conversations/admin_conversations_search.go @@ -0,0 +1,114 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_conversations_searchHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["team_ids"]; ok { + queryParams = append(queryParams, fmt.Sprintf("team_ids=%v", val)) + } + if val, ok := args["query"]; ok { + queryParams = append(queryParams, fmt.Sprintf("query=%v", val)) + } + if val, ok := args["limit"]; ok { + queryParams = append(queryParams, fmt.Sprintf("limit=%v", val)) + } + if val, ok := args["cursor"]; ok { + queryParams = append(queryParams, fmt.Sprintf("cursor=%v", val)) + } + if val, ok := args["search_channel_types"]; ok { + queryParams = append(queryParams, fmt.Sprintf("search_channel_types=%v", val)) + } + if val, ok := args["sort"]; ok { + queryParams = append(queryParams, fmt.Sprintf("sort=%v", val)) + } + if val, ok := args["sort_dir"]; ok { + queryParams = append(queryParams, fmt.Sprintf("sort_dir=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/admin.conversations.search%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_conversations_searchTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_admin_conversations_search", + mcp.WithDescription("Search for public or private channels in an Enterprise organization."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.conversations:read`")), + mcp.WithString("team_ids", mcp.Description("Comma separated string of team IDs, signifying the workspaces to search through.")), + mcp.WithString("query", mcp.Description("Name of the the channel to query by.")), + mcp.WithNumber("limit", mcp.Description("Maximum number of items to be returned. Must be between 1 - 20 both inclusive. Default is 10.")), + mcp.WithString("cursor", mcp.Description("Set `cursor` to `next_cursor` returned by the previous call to list items in the next page.")), + mcp.WithString("search_channel_types", mcp.Description("The type of channel to include or exclude in the search. For example `private` will search private channels, while `private_exclude` will exclude them. For a full list of types, check the [Types section](#types).")), + mcp.WithString("sort", mcp.Description("Possible values are `relevant` (search ranking based on what we think is closest), `name` (alphabetical), `member_count` (number of users in the channel), and `created` (date channel was created). You can optionally pair this with the `sort_dir` arg to change how it is sorted ")), + mcp.WithString("sort_dir", mcp.Description("Sort direction. Possible values are `asc` for ascending order like (1, 2, 3) or (a, b, c), and `desc` for descending order like (3, 2, 1) or (c, b, a)")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_conversations_searchHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_conversations/admin_conversations_setconversationprefs.go b/MCP/go/tools/admin_conversations/admin_conversations_setconversationprefs.go new file mode 100644 index 0000000..90e6ae5 --- /dev/null +++ b/MCP/go/tools/admin_conversations/admin_conversations_setconversationprefs.go @@ -0,0 +1,100 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_conversations_setconversationprefsHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/admin.conversations.setConversationPrefs", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_conversations_setconversationprefsTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_admin_conversations_setConversationPrefs", + mcp.WithDescription("Set the posting permissions for a public or private channel."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.conversations:write`")), + mcp.WithString("channel_id", mcp.Required(), mcp.Description("Input parameter: The channel to set the prefs for")), + mcp.WithString("prefs", mcp.Required(), mcp.Description("Input parameter: The prefs for this channel in a stringified JSON format.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_conversations_setconversationprefsHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_conversations/admin_conversations_setteams.go b/MCP/go/tools/admin_conversations/admin_conversations_setteams.go new file mode 100644 index 0000000..30c84e9 --- /dev/null +++ b/MCP/go/tools/admin_conversations/admin_conversations_setteams.go @@ -0,0 +1,102 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_conversations_setteamsHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/admin.conversations.setTeams", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_conversations_setteamsTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_admin_conversations_setTeams", + mcp.WithDescription("Set the workspaces in an Enterprise grid org that connect to a public or private channel."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.conversations:write`")), + mcp.WithString("channel_id", mcp.Required(), mcp.Description("Input parameter: The encoded `channel_id` to add or remove to workspaces.")), + mcp.WithBoolean("org_channel", mcp.Description("Input parameter: True if channel has to be converted to an org channel")), + mcp.WithString("target_team_ids", mcp.Description("Input parameter: A comma-separated list of workspaces to which the channel should be shared. Not required if the channel is being shared org-wide.")), + mcp.WithString("team_id", mcp.Description("Input parameter: The workspace to which the channel belongs. Omit this argument if the channel is a cross-workspace shared channel.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_conversations_setteamsHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_conversations/admin_conversations_unarchive.go b/MCP/go/tools/admin_conversations/admin_conversations_unarchive.go new file mode 100644 index 0000000..6ca47bf --- /dev/null +++ b/MCP/go/tools/admin_conversations/admin_conversations_unarchive.go @@ -0,0 +1,99 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_conversations_unarchiveHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/admin.conversations.unarchive", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_conversations_unarchiveTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_admin_conversations_unarchive", + mcp.WithDescription("Unarchive a public or private channel."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.conversations:write`")), + mcp.WithString("channel_id", mcp.Required(), mcp.Description("Input parameter: The channel to unarchive.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_conversations_unarchiveHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_conversations_ekm/admin_conversations_ekm_listoriginalconnectedchannelinfo.go b/MCP/go/tools/admin_conversations_ekm/admin_conversations_ekm_listoriginalconnectedchannelinfo.go new file mode 100644 index 0000000..60a74df --- /dev/null +++ b/MCP/go/tools/admin_conversations_ekm/admin_conversations_ekm_listoriginalconnectedchannelinfo.go @@ -0,0 +1,102 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_conversations_ekm_listoriginalconnectedchannelinfoHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["channel_ids"]; ok { + queryParams = append(queryParams, fmt.Sprintf("channel_ids=%v", val)) + } + if val, ok := args["team_ids"]; ok { + queryParams = append(queryParams, fmt.Sprintf("team_ids=%v", val)) + } + if val, ok := args["limit"]; ok { + queryParams = append(queryParams, fmt.Sprintf("limit=%v", val)) + } + if val, ok := args["cursor"]; ok { + queryParams = append(queryParams, fmt.Sprintf("cursor=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/admin.conversations.ekm.listOriginalConnectedChannelInfo%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_conversations_ekm_listoriginalconnectedchannelinfoTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_admin_conversations_ekm_listOriginalConnectedChannelInfo", + mcp.WithDescription("List all disconnected channels—i.e., channels that were once connected to other workspaces and then disconnected—and the corresponding original channel IDs for key revocation with EKM."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.conversations:read`")), + mcp.WithString("channel_ids", mcp.Description("A comma-separated list of channels to filter to.")), + mcp.WithString("team_ids", mcp.Description("A comma-separated list of the workspaces to which the channels you would like returned belong.")), + mcp.WithNumber("limit", mcp.Description("The maximum number of items to return. Must be between 1 - 1000 both inclusive.")), + mcp.WithString("cursor", mcp.Description("Set `cursor` to `next_cursor` returned by the previous call to list items in the next page.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_conversations_ekm_listoriginalconnectedchannelinfoHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_conversations_restrictaccess/admin_conversations_restrictaccess_listgroups.go b/MCP/go/tools/admin_conversations_restrictaccess/admin_conversations_restrictaccess_listgroups.go new file mode 100644 index 0000000..1bb5617 --- /dev/null +++ b/MCP/go/tools/admin_conversations_restrictaccess/admin_conversations_restrictaccess_listgroups.go @@ -0,0 +1,94 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_conversations_restrictaccess_listgroupsHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["channel_id"]; ok { + queryParams = append(queryParams, fmt.Sprintf("channel_id=%v", val)) + } + if val, ok := args["team_id"]; ok { + queryParams = append(queryParams, fmt.Sprintf("team_id=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/admin.conversations.restrictAccess.listGroups%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_conversations_restrictaccess_listgroupsTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_admin_conversations_restrictAccess_listGroups", + mcp.WithDescription("List all IDP Groups linked to a channel"), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.conversations:read`")), + mcp.WithString("channel_id", mcp.Required(), mcp.Description("")), + mcp.WithString("team_id", mcp.Description("The workspace where the channel exists. This argument is required for channels only tied to one workspace, and optional for channels that are shared across an organization.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_conversations_restrictaccess_listgroupsHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_emoji/admin_emoji_list.go b/MCP/go/tools/admin_emoji/admin_emoji_list.go new file mode 100644 index 0000000..b2be3d7 --- /dev/null +++ b/MCP/go/tools/admin_emoji/admin_emoji_list.go @@ -0,0 +1,94 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_emoji_listHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["cursor"]; ok { + queryParams = append(queryParams, fmt.Sprintf("cursor=%v", val)) + } + if val, ok := args["limit"]; ok { + queryParams = append(queryParams, fmt.Sprintf("limit=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/admin.emoji.list%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_emoji_listTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_admin_emoji_list", + mcp.WithDescription("List emoji for an Enterprise Grid organization."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.teams:read`")), + mcp.WithString("cursor", mcp.Description("Set `cursor` to `next_cursor` returned by the previous call to list items in the next page")), + mcp.WithNumber("limit", mcp.Description("The maximum number of items to return. Must be between 1 - 1000 both inclusive.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_emoji_listHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_inviterequests/admin_inviterequests_approve.go b/MCP/go/tools/admin_inviterequests/admin_inviterequests_approve.go new file mode 100644 index 0000000..6832f9c --- /dev/null +++ b/MCP/go/tools/admin_inviterequests/admin_inviterequests_approve.go @@ -0,0 +1,100 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_inviterequests_approveHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/admin.inviteRequests.approve", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_inviterequests_approveTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_admin_inviteRequests_approve", + mcp.WithDescription("Approve a workspace invite request."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.invites:write`")), + mcp.WithString("invite_request_id", mcp.Required(), mcp.Description("Input parameter: ID of the request to invite.")), + mcp.WithString("team_id", mcp.Description("Input parameter: ID for the workspace where the invite request was made.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_inviterequests_approveHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_inviterequests/admin_inviterequests_deny.go b/MCP/go/tools/admin_inviterequests/admin_inviterequests_deny.go new file mode 100644 index 0000000..5a9cc3a --- /dev/null +++ b/MCP/go/tools/admin_inviterequests/admin_inviterequests_deny.go @@ -0,0 +1,100 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_inviterequests_denyHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/admin.inviteRequests.deny", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_inviterequests_denyTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_admin_inviteRequests_deny", + mcp.WithDescription("Deny a workspace invite request."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.invites:write`")), + mcp.WithString("invite_request_id", mcp.Required(), mcp.Description("Input parameter: ID of the request to invite.")), + mcp.WithString("team_id", mcp.Description("Input parameter: ID for the workspace where the invite request was made.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_inviterequests_denyHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_inviterequests/admin_inviterequests_list.go b/MCP/go/tools/admin_inviterequests/admin_inviterequests_list.go new file mode 100644 index 0000000..9420993 --- /dev/null +++ b/MCP/go/tools/admin_inviterequests/admin_inviterequests_list.go @@ -0,0 +1,98 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_inviterequests_listHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["team_id"]; ok { + queryParams = append(queryParams, fmt.Sprintf("team_id=%v", val)) + } + if val, ok := args["cursor"]; ok { + queryParams = append(queryParams, fmt.Sprintf("cursor=%v", val)) + } + if val, ok := args["limit"]; ok { + queryParams = append(queryParams, fmt.Sprintf("limit=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/admin.inviteRequests.list%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_inviterequests_listTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_admin_inviteRequests_list", + mcp.WithDescription("List all pending workspace invite requests."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.invites:read`")), + mcp.WithString("team_id", mcp.Description("ID for the workspace where the invite requests were made.")), + mcp.WithString("cursor", mcp.Description("Value of the `next_cursor` field sent as part of the previous API response")), + mcp.WithNumber("limit", mcp.Description("The number of results that will be returned by the API on each invocation. Must be between 1 - 1000, both inclusive")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_inviterequests_listHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_inviterequests_approved/admin_inviterequests_approved_list.go b/MCP/go/tools/admin_inviterequests_approved/admin_inviterequests_approved_list.go new file mode 100644 index 0000000..80b1841 --- /dev/null +++ b/MCP/go/tools/admin_inviterequests_approved/admin_inviterequests_approved_list.go @@ -0,0 +1,98 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_inviterequests_approved_listHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["team_id"]; ok { + queryParams = append(queryParams, fmt.Sprintf("team_id=%v", val)) + } + if val, ok := args["cursor"]; ok { + queryParams = append(queryParams, fmt.Sprintf("cursor=%v", val)) + } + if val, ok := args["limit"]; ok { + queryParams = append(queryParams, fmt.Sprintf("limit=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/admin.inviteRequests.approved.list%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_inviterequests_approved_listTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_admin_inviteRequests_approved_list", + mcp.WithDescription("List all approved workspace invite requests."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.invites:read`")), + mcp.WithString("team_id", mcp.Description("ID for the workspace where the invite requests were made.")), + mcp.WithString("cursor", mcp.Description("Value of the `next_cursor` field sent as part of the previous API response")), + mcp.WithNumber("limit", mcp.Description("The number of results that will be returned by the API on each invocation. Must be between 1 - 1000, both inclusive")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_inviterequests_approved_listHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_inviterequests_denied/admin_inviterequests_denied_list.go b/MCP/go/tools/admin_inviterequests_denied/admin_inviterequests_denied_list.go new file mode 100644 index 0000000..fb3bad1 --- /dev/null +++ b/MCP/go/tools/admin_inviterequests_denied/admin_inviterequests_denied_list.go @@ -0,0 +1,98 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_inviterequests_denied_listHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["team_id"]; ok { + queryParams = append(queryParams, fmt.Sprintf("team_id=%v", val)) + } + if val, ok := args["cursor"]; ok { + queryParams = append(queryParams, fmt.Sprintf("cursor=%v", val)) + } + if val, ok := args["limit"]; ok { + queryParams = append(queryParams, fmt.Sprintf("limit=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/admin.inviteRequests.denied.list%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_inviterequests_denied_listTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_admin_inviteRequests_denied_list", + mcp.WithDescription("List all denied workspace invite requests."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.invites:read`")), + mcp.WithString("team_id", mcp.Description("ID for the workspace where the invite requests were made.")), + mcp.WithString("cursor", mcp.Description("Value of the `next_cursor` field sent as part of the previous api response")), + mcp.WithNumber("limit", mcp.Description("The number of results that will be returned by the API on each invocation. Must be between 1 - 1000 both inclusive")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_inviterequests_denied_listHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_teams/admin_teams_create.go b/MCP/go/tools/admin_teams/admin_teams_create.go new file mode 100644 index 0000000..b7321d6 --- /dev/null +++ b/MCP/go/tools/admin_teams/admin_teams_create.go @@ -0,0 +1,102 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_teams_createHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/admin.teams.create", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_teams_createTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_admin_teams_create", + mcp.WithDescription("Create an Enterprise team."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.teams:write`")), + mcp.WithString("team_name", mcp.Required(), mcp.Description("Input parameter: Team name (for example, Slack Softball Team).")), + mcp.WithString("team_description", mcp.Description("Input parameter: Description for the team.")), + mcp.WithString("team_discoverability", mcp.Description("Input parameter: Who can join the team. A team's discoverability can be `open`, `closed`, `invite_only`, or `unlisted`.")), + mcp.WithString("team_domain", mcp.Required(), mcp.Description("Input parameter: Team domain (for example, slacksoftballteam).")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_teams_createHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_teams/admin_teams_list.go b/MCP/go/tools/admin_teams/admin_teams_list.go new file mode 100644 index 0000000..b320d9e --- /dev/null +++ b/MCP/go/tools/admin_teams/admin_teams_list.go @@ -0,0 +1,94 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_teams_listHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["limit"]; ok { + queryParams = append(queryParams, fmt.Sprintf("limit=%v", val)) + } + if val, ok := args["cursor"]; ok { + queryParams = append(queryParams, fmt.Sprintf("cursor=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/admin.teams.list%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_teams_listTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_admin_teams_list", + mcp.WithDescription("List all teams on an Enterprise organization"), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.teams:read`")), + mcp.WithNumber("limit", mcp.Description("The maximum number of items to return. Must be between 1 - 100 both inclusive.")), + mcp.WithString("cursor", mcp.Description("Set `cursor` to `next_cursor` returned by the previous call to list items in the next page.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_teams_listHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_teams_admins/admin_teams_admins_list.go b/MCP/go/tools/admin_teams_admins/admin_teams_admins_list.go new file mode 100644 index 0000000..c677b93 --- /dev/null +++ b/MCP/go/tools/admin_teams_admins/admin_teams_admins_list.go @@ -0,0 +1,98 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_teams_admins_listHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["limit"]; ok { + queryParams = append(queryParams, fmt.Sprintf("limit=%v", val)) + } + if val, ok := args["cursor"]; ok { + queryParams = append(queryParams, fmt.Sprintf("cursor=%v", val)) + } + if val, ok := args["team_id"]; ok { + queryParams = append(queryParams, fmt.Sprintf("team_id=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/admin.teams.admins.list%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_teams_admins_listTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_admin_teams_admins_list", + mcp.WithDescription("List all of the admins on a given workspace."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.teams:read`")), + mcp.WithNumber("limit", mcp.Description("The maximum number of items to return.")), + mcp.WithString("cursor", mcp.Description("Set `cursor` to `next_cursor` returned by the previous call to list items in the next page.")), + mcp.WithString("team_id", mcp.Required(), mcp.Description("")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_teams_admins_listHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_teams_owners/admin_teams_owners_list.go b/MCP/go/tools/admin_teams_owners/admin_teams_owners_list.go new file mode 100644 index 0000000..83ca437 --- /dev/null +++ b/MCP/go/tools/admin_teams_owners/admin_teams_owners_list.go @@ -0,0 +1,98 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_teams_owners_listHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["team_id"]; ok { + queryParams = append(queryParams, fmt.Sprintf("team_id=%v", val)) + } + if val, ok := args["limit"]; ok { + queryParams = append(queryParams, fmt.Sprintf("limit=%v", val)) + } + if val, ok := args["cursor"]; ok { + queryParams = append(queryParams, fmt.Sprintf("cursor=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/admin.teams.owners.list%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_teams_owners_listTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_admin_teams_owners_list", + mcp.WithDescription("List all of the owners on a given workspace."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.teams:read`")), + mcp.WithString("team_id", mcp.Required(), mcp.Description("")), + mcp.WithNumber("limit", mcp.Description("The maximum number of items to return. Must be between 1 - 1000 both inclusive.")), + mcp.WithString("cursor", mcp.Description("Set `cursor` to `next_cursor` returned by the previous call to list items in the next page.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_teams_owners_listHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_teams_settings/admin_teams_settings_info.go b/MCP/go/tools/admin_teams_settings/admin_teams_settings_info.go new file mode 100644 index 0000000..f4105e8 --- /dev/null +++ b/MCP/go/tools/admin_teams_settings/admin_teams_settings_info.go @@ -0,0 +1,90 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_teams_settings_infoHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["team_id"]; ok { + queryParams = append(queryParams, fmt.Sprintf("team_id=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/admin.teams.settings.info%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_teams_settings_infoTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_admin_teams_settings_info", + mcp.WithDescription("Fetch information about settings in a workspace"), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.teams:read`")), + mcp.WithString("team_id", mcp.Required(), mcp.Description("")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_teams_settings_infoHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_teams_settings/admin_teams_settings_setdescription.go b/MCP/go/tools/admin_teams_settings/admin_teams_settings_setdescription.go new file mode 100644 index 0000000..6f8da1a --- /dev/null +++ b/MCP/go/tools/admin_teams_settings/admin_teams_settings_setdescription.go @@ -0,0 +1,100 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_teams_settings_setdescriptionHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/admin.teams.settings.setDescription", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_teams_settings_setdescriptionTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_admin_teams_settings_setDescription", + mcp.WithDescription("Set the description of a given workspace."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.teams:write`")), + mcp.WithString("team_id", mcp.Required(), mcp.Description("Input parameter: ID for the workspace to set the description for.")), + mcp.WithString("description", mcp.Required(), mcp.Description("Input parameter: The new description for the workspace.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_teams_settings_setdescriptionHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_teams_settings/admin_teams_settings_setdiscoverability.go b/MCP/go/tools/admin_teams_settings/admin_teams_settings_setdiscoverability.go new file mode 100644 index 0000000..a5a984d --- /dev/null +++ b/MCP/go/tools/admin_teams_settings/admin_teams_settings_setdiscoverability.go @@ -0,0 +1,100 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_teams_settings_setdiscoverabilityHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/admin.teams.settings.setDiscoverability", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_teams_settings_setdiscoverabilityTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_admin_teams_settings_setDiscoverability", + mcp.WithDescription("An API method that allows admins to set the discoverability of a given workspace"), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.teams:write`")), + mcp.WithString("discoverability", mcp.Required(), mcp.Description("Input parameter: This workspace's discovery setting. It must be set to one of `open`, `invite_only`, `closed`, or `unlisted`.")), + mcp.WithString("team_id", mcp.Required(), mcp.Description("Input parameter: The ID of the workspace to set discoverability on.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_teams_settings_setdiscoverabilityHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_teams_settings/admin_teams_settings_setname.go b/MCP/go/tools/admin_teams_settings/admin_teams_settings_setname.go new file mode 100644 index 0000000..00e2e39 --- /dev/null +++ b/MCP/go/tools/admin_teams_settings/admin_teams_settings_setname.go @@ -0,0 +1,100 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_teams_settings_setnameHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/admin.teams.settings.setName", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_teams_settings_setnameTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_admin_teams_settings_setName", + mcp.WithDescription("Set the name of a given workspace."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.teams:write`")), + mcp.WithString("name", mcp.Required(), mcp.Description("Input parameter: The new name of the workspace.")), + mcp.WithString("team_id", mcp.Required(), mcp.Description("Input parameter: ID for the workspace to set the name for.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_teams_settings_setnameHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_usergroups/admin_usergroups_addchannels.go b/MCP/go/tools/admin_usergroups/admin_usergroups_addchannels.go new file mode 100644 index 0000000..b197bdd --- /dev/null +++ b/MCP/go/tools/admin_usergroups/admin_usergroups_addchannels.go @@ -0,0 +1,101 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_usergroups_addchannelsHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/admin.usergroups.addChannels", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_usergroups_addchannelsTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_admin_usergroups_addChannels", + mcp.WithDescription("Add one or more default channels to an IDP group."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.usergroups:write`")), + mcp.WithString("channel_ids", mcp.Required(), mcp.Description("Input parameter: Comma separated string of channel IDs.")), + mcp.WithString("team_id", mcp.Description("Input parameter: The workspace to add default channels in.")), + mcp.WithString("usergroup_id", mcp.Required(), mcp.Description("Input parameter: ID of the IDP group to add default channels for.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_usergroups_addchannelsHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_usergroups/admin_usergroups_addteams.go b/MCP/go/tools/admin_usergroups/admin_usergroups_addteams.go new file mode 100644 index 0000000..a391698 --- /dev/null +++ b/MCP/go/tools/admin_usergroups/admin_usergroups_addteams.go @@ -0,0 +1,101 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_usergroups_addteamsHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/admin.usergroups.addTeams", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_usergroups_addteamsTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_admin_usergroups_addTeams", + mcp.WithDescription("Associate one or more default workspaces with an organization-wide IDP group."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.teams:write`")), + mcp.WithBoolean("auto_provision", mcp.Description("Input parameter: When `true`, this method automatically creates new workspace accounts for the IDP group members.")), + mcp.WithString("team_ids", mcp.Required(), mcp.Description("Input parameter: A comma separated list of encoded team (workspace) IDs. Each workspace *MUST* belong to the organization associated with the token.")), + mcp.WithString("usergroup_id", mcp.Required(), mcp.Description("Input parameter: An encoded usergroup (IDP Group) ID.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_usergroups_addteamsHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_usergroups/admin_usergroups_listchannels.go b/MCP/go/tools/admin_usergroups/admin_usergroups_listchannels.go new file mode 100644 index 0000000..72f2b5a --- /dev/null +++ b/MCP/go/tools/admin_usergroups/admin_usergroups_listchannels.go @@ -0,0 +1,98 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_usergroups_listchannelsHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["usergroup_id"]; ok { + queryParams = append(queryParams, fmt.Sprintf("usergroup_id=%v", val)) + } + if val, ok := args["team_id"]; ok { + queryParams = append(queryParams, fmt.Sprintf("team_id=%v", val)) + } + if val, ok := args["include_num_members"]; ok { + queryParams = append(queryParams, fmt.Sprintf("include_num_members=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/admin.usergroups.listChannels%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_usergroups_listchannelsTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_admin_usergroups_listChannels", + mcp.WithDescription("List the channels linked to an org-level IDP group (user group)."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.usergroups:read`")), + mcp.WithString("usergroup_id", mcp.Required(), mcp.Description("ID of the IDP group to list default channels for.")), + mcp.WithString("team_id", mcp.Description("ID of the the workspace.")), + mcp.WithBoolean("include_num_members", mcp.Description("Flag to include or exclude the count of members per channel.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_usergroups_listchannelsHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_usergroups/admin_usergroups_removechannels.go b/MCP/go/tools/admin_usergroups/admin_usergroups_removechannels.go new file mode 100644 index 0000000..272fe7d --- /dev/null +++ b/MCP/go/tools/admin_usergroups/admin_usergroups_removechannels.go @@ -0,0 +1,100 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_usergroups_removechannelsHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/admin.usergroups.removeChannels", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_usergroups_removechannelsTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_admin_usergroups_removeChannels", + mcp.WithDescription("Remove one or more default channels from an org-level IDP group (user group)."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.usergroups:write`")), + mcp.WithString("usergroup_id", mcp.Required(), mcp.Description("Input parameter: ID of the IDP Group")), + mcp.WithString("channel_ids", mcp.Required(), mcp.Description("Input parameter: Comma-separated string of channel IDs")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_usergroups_removechannelsHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_users/admin_users_assign.go b/MCP/go/tools/admin_users/admin_users_assign.go new file mode 100644 index 0000000..2f6ccfe --- /dev/null +++ b/MCP/go/tools/admin_users/admin_users_assign.go @@ -0,0 +1,103 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_users_assignHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/admin.users.assign", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_users_assignTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_admin_users_assign", + mcp.WithDescription("Add an Enterprise user to a workspace."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.users:write`")), + mcp.WithBoolean("is_restricted", mcp.Description("Input parameter: True if user should be added to the workspace as a guest.")), + mcp.WithBoolean("is_ultra_restricted", mcp.Description("Input parameter: True if user should be added to the workspace as a single-channel guest.")), + mcp.WithString("team_id", mcp.Required(), mcp.Description("Input parameter: The ID (`T1234`) of the workspace.")), + mcp.WithString("user_id", mcp.Required(), mcp.Description("Input parameter: The ID of the user to add to the workspace.")), + mcp.WithString("channel_ids", mcp.Description("Input parameter: Comma separated values of channel IDs to add user in the new workspace.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_users_assignHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_users/admin_users_invite.go b/MCP/go/tools/admin_users/admin_users_invite.go new file mode 100644 index 0000000..67cab65 --- /dev/null +++ b/MCP/go/tools/admin_users/admin_users_invite.go @@ -0,0 +1,107 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_users_inviteHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/admin.users.invite", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_users_inviteTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_admin_users_invite", + mcp.WithDescription("Invite a user to a workspace."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.users:write`")), + mcp.WithString("channel_ids", mcp.Required(), mcp.Description("Input parameter: A comma-separated list of `channel_id`s for this user to join. At least one channel is required.")), + mcp.WithString("team_id", mcp.Required(), mcp.Description("Input parameter: The ID (`T1234`) of the workspace.")), + mcp.WithString("custom_message", mcp.Description("Input parameter: An optional message to send to the user in the invite email.")), + mcp.WithBoolean("is_restricted", mcp.Description("Input parameter: Is this user a multi-channel guest user? (default: false)")), + mcp.WithString("real_name", mcp.Description("Input parameter: Full name of the user.")), + mcp.WithString("guest_expiration_ts", mcp.Description("Input parameter: Timestamp when guest account should be disabled. Only include this timestamp if you are inviting a guest user and you want their account to expire on a certain date.")), + mcp.WithBoolean("is_ultra_restricted", mcp.Description("Input parameter: Is this user a single channel guest user? (default: false)")), + mcp.WithBoolean("resend", mcp.Description("Input parameter: Allow this invite to be resent in the future if a user has not signed up yet. (default: false)")), + mcp.WithString("email", mcp.Required(), mcp.Description("Input parameter: The email address of the person to invite.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_users_inviteHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_users/admin_users_list.go b/MCP/go/tools/admin_users/admin_users_list.go new file mode 100644 index 0000000..2175070 --- /dev/null +++ b/MCP/go/tools/admin_users/admin_users_list.go @@ -0,0 +1,98 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_users_listHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["team_id"]; ok { + queryParams = append(queryParams, fmt.Sprintf("team_id=%v", val)) + } + if val, ok := args["cursor"]; ok { + queryParams = append(queryParams, fmt.Sprintf("cursor=%v", val)) + } + if val, ok := args["limit"]; ok { + queryParams = append(queryParams, fmt.Sprintf("limit=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/admin.users.list%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_users_listTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_admin_users_list", + mcp.WithDescription("List users on a workspace"), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.users:read`")), + mcp.WithString("team_id", mcp.Required(), mcp.Description("The ID (`T1234`) of the workspace.")), + mcp.WithString("cursor", mcp.Description("Set `cursor` to `next_cursor` returned by the previous call to list items in the next page.")), + mcp.WithNumber("limit", mcp.Description("Limit for how many users to be retrieved per page")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_users_listHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_users/admin_users_remove.go b/MCP/go/tools/admin_users/admin_users_remove.go new file mode 100644 index 0000000..0974a45 --- /dev/null +++ b/MCP/go/tools/admin_users/admin_users_remove.go @@ -0,0 +1,100 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_users_removeHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/admin.users.remove", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_users_removeTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_admin_users_remove", + mcp.WithDescription("Remove a user from a workspace."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.users:write`")), + mcp.WithString("team_id", mcp.Required(), mcp.Description("Input parameter: The ID (`T1234`) of the workspace.")), + mcp.WithString("user_id", mcp.Required(), mcp.Description("Input parameter: The ID of the user to remove.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_users_removeHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_users/admin_users_setadmin.go b/MCP/go/tools/admin_users/admin_users_setadmin.go new file mode 100644 index 0000000..88934cd --- /dev/null +++ b/MCP/go/tools/admin_users/admin_users_setadmin.go @@ -0,0 +1,100 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_users_setadminHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/admin.users.setAdmin", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_users_setadminTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_admin_users_setAdmin", + mcp.WithDescription("Set an existing guest, regular user, or owner to be an admin user."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.users:write`")), + mcp.WithString("team_id", mcp.Required(), mcp.Description("Input parameter: The ID (`T1234`) of the workspace.")), + mcp.WithString("user_id", mcp.Required(), mcp.Description("Input parameter: The ID of the user to designate as an admin.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_users_setadminHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_users/admin_users_setexpiration.go b/MCP/go/tools/admin_users/admin_users_setexpiration.go new file mode 100644 index 0000000..198e702 --- /dev/null +++ b/MCP/go/tools/admin_users/admin_users_setexpiration.go @@ -0,0 +1,101 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_users_setexpirationHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/admin.users.setExpiration", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_users_setexpirationTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_admin_users_setExpiration", + mcp.WithDescription("Set an expiration for a guest user"), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.users:write`")), + mcp.WithString("user_id", mcp.Required(), mcp.Description("Input parameter: The ID of the user to set an expiration for.")), + mcp.WithNumber("expiration_ts", mcp.Required(), mcp.Description("Input parameter: Timestamp when guest account should be disabled.")), + mcp.WithString("team_id", mcp.Required(), mcp.Description("Input parameter: The ID (`T1234`) of the workspace.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_users_setexpirationHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_users/admin_users_setowner.go b/MCP/go/tools/admin_users/admin_users_setowner.go new file mode 100644 index 0000000..5e49047 --- /dev/null +++ b/MCP/go/tools/admin_users/admin_users_setowner.go @@ -0,0 +1,100 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_users_setownerHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/admin.users.setOwner", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_users_setownerTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_admin_users_setOwner", + mcp.WithDescription("Set an existing guest, regular user, or admin user to be a workspace owner."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.users:write`")), + mcp.WithString("team_id", mcp.Required(), mcp.Description("Input parameter: The ID (`T1234`) of the workspace.")), + mcp.WithString("user_id", mcp.Required(), mcp.Description("Input parameter: Id of the user to promote to owner.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_users_setownerHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_users/admin_users_setregular.go b/MCP/go/tools/admin_users/admin_users_setregular.go new file mode 100644 index 0000000..7b72c07 --- /dev/null +++ b/MCP/go/tools/admin_users/admin_users_setregular.go @@ -0,0 +1,100 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_users_setregularHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/admin.users.setRegular", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_users_setregularTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_admin_users_setRegular", + mcp.WithDescription("Set an existing guest user, admin user, or owner to be a regular user."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.users:write`")), + mcp.WithString("team_id", mcp.Required(), mcp.Description("Input parameter: The ID (`T1234`) of the workspace.")), + mcp.WithString("user_id", mcp.Required(), mcp.Description("Input parameter: The ID of the user to designate as a regular user.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_users_setregularHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_users_session/admin_users_session_invalidate.go b/MCP/go/tools/admin_users_session/admin_users_session_invalidate.go new file mode 100644 index 0000000..49c80c2 --- /dev/null +++ b/MCP/go/tools/admin_users_session/admin_users_session_invalidate.go @@ -0,0 +1,100 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_users_session_invalidateHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/admin.users.session.invalidate", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_users_session_invalidateTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_admin_users_session_invalidate", + mcp.WithDescription("Invalidate a single session for a user by session_id"), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.users:write`")), + mcp.WithNumber("session_id", mcp.Required(), mcp.Description("")), + mcp.WithString("team_id", mcp.Required(), mcp.Description("Input parameter: ID of the team that the session belongs to")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_users_session_invalidateHandler(cfg), + } +} diff --git a/MCP/go/tools/admin_users_session/admin_users_session_reset.go b/MCP/go/tools/admin_users_session/admin_users_session_reset.go new file mode 100644 index 0000000..c47ba2a --- /dev/null +++ b/MCP/go/tools/admin_users_session/admin_users_session_reset.go @@ -0,0 +1,101 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Admin_users_session_resetHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/admin.users.session.reset", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAdmin_users_session_resetTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_admin_users_session_reset", + mcp.WithDescription("Wipes all valid sessions on all devices for a given user"), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin.users:write`")), + mcp.WithBoolean("mobile_only", mcp.Description("Input parameter: Only expire mobile sessions (default: false)")), + mcp.WithString("user_id", mcp.Required(), mcp.Description("Input parameter: The ID of the user to wipe sessions for")), + mcp.WithBoolean("web_only", mcp.Description("Input parameter: Only expire web sessions (default: false)")), + ) + + return models.Tool{ + Definition: tool, + Handler: Admin_users_session_resetHandler(cfg), + } +} diff --git a/MCP/go/tools/api/api_test_handler.go b/MCP/go/tools/api/api_test_handler.go new file mode 100644 index 0000000..ece0dbb --- /dev/null +++ b/MCP/go/tools/api/api_test_handler.go @@ -0,0 +1,90 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Api_test_handlerHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["error"]; ok { + queryParams = append(queryParams, fmt.Sprintf("error=%v", val)) + } + if val, ok := args["foo"]; ok { + queryParams = append(queryParams, fmt.Sprintf("foo=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/api.test%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateApi_test_handlerTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_api_test", + mcp.WithDescription("Checks API calling code."), + mcp.WithString("error", mcp.Description("Error response to return")), + mcp.WithString("foo", mcp.Description("example property to return")), + ) + + return models.Tool{ + Definition: tool, + Handler: Api_test_handlerHandler(cfg), + } +} diff --git a/MCP/go/tools/apps/apps_uninstall.go b/MCP/go/tools/apps/apps_uninstall.go new file mode 100644 index 0000000..812c41b --- /dev/null +++ b/MCP/go/tools/apps/apps_uninstall.go @@ -0,0 +1,94 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Apps_uninstallHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["client_id"]; ok { + queryParams = append(queryParams, fmt.Sprintf("client_id=%v", val)) + } + if val, ok := args["client_secret"]; ok { + queryParams = append(queryParams, fmt.Sprintf("client_secret=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/apps.uninstall%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateApps_uninstallTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_apps_uninstall", + mcp.WithDescription("Uninstalls your app from a workspace."), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `none`")), + mcp.WithString("client_id", mcp.Description("Issued when you created your application.")), + mcp.WithString("client_secret", mcp.Description("Issued when you created your application.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Apps_uninstallHandler(cfg), + } +} diff --git a/MCP/go/tools/apps_event_authorizations/apps_event_authorizations_list.go b/MCP/go/tools/apps_event_authorizations/apps_event_authorizations_list.go new file mode 100644 index 0000000..11e7fcb --- /dev/null +++ b/MCP/go/tools/apps_event_authorizations/apps_event_authorizations_list.go @@ -0,0 +1,98 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Apps_event_authorizations_listHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["event_context"]; ok { + queryParams = append(queryParams, fmt.Sprintf("event_context=%v", val)) + } + if val, ok := args["cursor"]; ok { + queryParams = append(queryParams, fmt.Sprintf("cursor=%v", val)) + } + if val, ok := args["limit"]; ok { + queryParams = append(queryParams, fmt.Sprintf("limit=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/apps.event.authorizations.list%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateApps_event_authorizations_listTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_apps_event_authorizations_list", + mcp.WithDescription("Get a list of authorizations for the given event context. Each authorization represents an app installation that the event is visible to."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `authorizations:read`")), + mcp.WithString("event_context", mcp.Required(), mcp.Description("")), + mcp.WithString("cursor", mcp.Description("")), + mcp.WithNumber("limit", mcp.Description("")), + ) + + return models.Tool{ + Definition: tool, + Handler: Apps_event_authorizations_listHandler(cfg), + } +} diff --git a/MCP/go/tools/apps_permissions/apps_permissions_info.go b/MCP/go/tools/apps_permissions/apps_permissions_info.go new file mode 100644 index 0000000..5974372 --- /dev/null +++ b/MCP/go/tools/apps_permissions/apps_permissions_info.go @@ -0,0 +1,86 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Apps_permissions_infoHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/apps.permissions.info%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateApps_permissions_infoTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_apps_permissions_info", + mcp.WithDescription("Returns list of permissions this app has on a team."), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `none`")), + ) + + return models.Tool{ + Definition: tool, + Handler: Apps_permissions_infoHandler(cfg), + } +} diff --git a/MCP/go/tools/apps_permissions/apps_permissions_request.go b/MCP/go/tools/apps_permissions/apps_permissions_request.go new file mode 100644 index 0000000..133d967 --- /dev/null +++ b/MCP/go/tools/apps_permissions/apps_permissions_request.go @@ -0,0 +1,94 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Apps_permissions_requestHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["scopes"]; ok { + queryParams = append(queryParams, fmt.Sprintf("scopes=%v", val)) + } + if val, ok := args["trigger_id"]; ok { + queryParams = append(queryParams, fmt.Sprintf("trigger_id=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/apps.permissions.request%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateApps_permissions_requestTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_apps_permissions_request", + mcp.WithDescription("Allows an app to request additional scopes"), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `none`")), + mcp.WithString("scopes", mcp.Required(), mcp.Description("A comma separated list of scopes to request for")), + mcp.WithString("trigger_id", mcp.Required(), mcp.Description("Token used to trigger the permissions API")), + ) + + return models.Tool{ + Definition: tool, + Handler: Apps_permissions_requestHandler(cfg), + } +} diff --git a/MCP/go/tools/apps_permissions_resources/apps_permissions_resources_list.go b/MCP/go/tools/apps_permissions_resources/apps_permissions_resources_list.go new file mode 100644 index 0000000..b964520 --- /dev/null +++ b/MCP/go/tools/apps_permissions_resources/apps_permissions_resources_list.go @@ -0,0 +1,94 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Apps_permissions_resources_listHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["cursor"]; ok { + queryParams = append(queryParams, fmt.Sprintf("cursor=%v", val)) + } + if val, ok := args["limit"]; ok { + queryParams = append(queryParams, fmt.Sprintf("limit=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/apps.permissions.resources.list%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateApps_permissions_resources_listTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_apps_permissions_resources_list", + mcp.WithDescription("Returns list of resource grants this app has on a team."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `none`")), + mcp.WithString("cursor", mcp.Description("Paginate through collections of data by setting the `cursor` parameter to a `next_cursor` attribute returned by a previous request's `response_metadata`. Default value fetches the first \"page\" of the collection. See [pagination](/docs/pagination) for more detail.")), + mcp.WithNumber("limit", mcp.Description("The maximum number of items to return.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Apps_permissions_resources_listHandler(cfg), + } +} diff --git a/MCP/go/tools/apps_permissions_scopes/apps_permissions_scopes_list.go b/MCP/go/tools/apps_permissions_scopes/apps_permissions_scopes_list.go new file mode 100644 index 0000000..83beced --- /dev/null +++ b/MCP/go/tools/apps_permissions_scopes/apps_permissions_scopes_list.go @@ -0,0 +1,86 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Apps_permissions_scopes_listHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/apps.permissions.scopes.list%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateApps_permissions_scopes_listTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_apps_permissions_scopes_list", + mcp.WithDescription("Returns list of scopes this app has on a team."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `none`")), + ) + + return models.Tool{ + Definition: tool, + Handler: Apps_permissions_scopes_listHandler(cfg), + } +} diff --git a/MCP/go/tools/apps_permissions_users/apps_permissions_users_list.go b/MCP/go/tools/apps_permissions_users/apps_permissions_users_list.go new file mode 100644 index 0000000..be08450 --- /dev/null +++ b/MCP/go/tools/apps_permissions_users/apps_permissions_users_list.go @@ -0,0 +1,94 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Apps_permissions_users_listHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["cursor"]; ok { + queryParams = append(queryParams, fmt.Sprintf("cursor=%v", val)) + } + if val, ok := args["limit"]; ok { + queryParams = append(queryParams, fmt.Sprintf("limit=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/apps.permissions.users.list%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateApps_permissions_users_listTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_apps_permissions_users_list", + mcp.WithDescription("Returns list of user grants and corresponding scopes this app has on a team."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `none`")), + mcp.WithString("cursor", mcp.Description("Paginate through collections of data by setting the `cursor` parameter to a `next_cursor` attribute returned by a previous request's `response_metadata`. Default value fetches the first \"page\" of the collection. See [pagination](/docs/pagination) for more detail.")), + mcp.WithNumber("limit", mcp.Description("The maximum number of items to return.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Apps_permissions_users_listHandler(cfg), + } +} diff --git a/MCP/go/tools/apps_permissions_users/apps_permissions_users_request.go b/MCP/go/tools/apps_permissions_users/apps_permissions_users_request.go new file mode 100644 index 0000000..49f2dd3 --- /dev/null +++ b/MCP/go/tools/apps_permissions_users/apps_permissions_users_request.go @@ -0,0 +1,98 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Apps_permissions_users_requestHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["scopes"]; ok { + queryParams = append(queryParams, fmt.Sprintf("scopes=%v", val)) + } + if val, ok := args["trigger_id"]; ok { + queryParams = append(queryParams, fmt.Sprintf("trigger_id=%v", val)) + } + if val, ok := args["user"]; ok { + queryParams = append(queryParams, fmt.Sprintf("user=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/apps.permissions.users.request%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateApps_permissions_users_requestTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_apps_permissions_users_request", + mcp.WithDescription("Enables an app to trigger a permissions modal to grant an app access to a user access scope."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `none`")), + mcp.WithString("scopes", mcp.Required(), mcp.Description("A comma separated list of user scopes to request for")), + mcp.WithString("trigger_id", mcp.Required(), mcp.Description("Token used to trigger the request")), + mcp.WithString("user", mcp.Required(), mcp.Description("The user this scope is being requested for")), + ) + + return models.Tool{ + Definition: tool, + Handler: Apps_permissions_users_requestHandler(cfg), + } +} diff --git a/MCP/go/tools/auth/auth_revoke.go b/MCP/go/tools/auth/auth_revoke.go new file mode 100644 index 0000000..bf2cc09 --- /dev/null +++ b/MCP/go/tools/auth/auth_revoke.go @@ -0,0 +1,90 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Auth_revokeHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["test"]; ok { + queryParams = append(queryParams, fmt.Sprintf("test=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/auth.revoke%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAuth_revokeTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_auth_revoke", + mcp.WithDescription("Revokes a token."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `none`")), + mcp.WithBoolean("test", mcp.Description("Setting this parameter to `1` triggers a _testing mode_ where the specified token will not actually be revoked.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Auth_revokeHandler(cfg), + } +} diff --git a/MCP/go/tools/auth/auth_test_handler.go b/MCP/go/tools/auth/auth_test_handler.go new file mode 100644 index 0000000..df2447a --- /dev/null +++ b/MCP/go/tools/auth/auth_test_handler.go @@ -0,0 +1,80 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Auth_test_handlerHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + url := fmt.Sprintf("%s/auth.test", cfg.BaseURL) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateAuth_test_handlerTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_auth_test", + mcp.WithDescription("Checks authentication & identity."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `none`")), + ) + + return models.Tool{ + Definition: tool, + Handler: Auth_test_handlerHandler(cfg), + } +} diff --git a/MCP/go/tools/bots/bots_info.go b/MCP/go/tools/bots/bots_info.go new file mode 100644 index 0000000..2b2304e --- /dev/null +++ b/MCP/go/tools/bots/bots_info.go @@ -0,0 +1,90 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Bots_infoHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["bot"]; ok { + queryParams = append(queryParams, fmt.Sprintf("bot=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/bots.info%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateBots_infoTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_bots_info", + mcp.WithDescription("Gets information about a bot user."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `users:read`")), + mcp.WithString("bot", mcp.Description("Bot user to get info on")), + ) + + return models.Tool{ + Definition: tool, + Handler: Bots_infoHandler(cfg), + } +} diff --git a/MCP/go/tools/calls/calls_add.go b/MCP/go/tools/calls/calls_add.go new file mode 100644 index 0000000..10eb31a --- /dev/null +++ b/MCP/go/tools/calls/calls_add.go @@ -0,0 +1,106 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Calls_addHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/calls.add", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateCalls_addTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_calls_add", + mcp.WithDescription("Registers a new Call."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `calls:write`")), + mcp.WithNumber("date_start", mcp.Description("Input parameter: Call start time in UTC UNIX timestamp format")), + mcp.WithString("desktop_app_join_url", mcp.Description("Input parameter: When supplied, available Slack clients will attempt to directly launch the 3rd-party Call with this URL.")), + mcp.WithString("external_display_id", mcp.Description("Input parameter: An optional, human-readable ID supplied by the 3rd-party Call provider. If supplied, this ID will be displayed in the Call object.")), + mcp.WithString("external_unique_id", mcp.Required(), mcp.Description("Input parameter: An ID supplied by the 3rd-party Call provider. It must be unique across all Calls from that service.")), + mcp.WithString("join_url", mcp.Required(), mcp.Description("Input parameter: The URL required for a client to join the Call.")), + mcp.WithString("title", mcp.Description("Input parameter: The name of the Call.")), + mcp.WithString("users", mcp.Description("Input parameter: The list of users to register as participants in the Call. [Read more on how to specify users here](/apis/calls#users).")), + mcp.WithString("created_by", mcp.Description("Input parameter: The valid Slack user ID of the user who created this Call. When this method is called with a user token, the `created_by` field is optional and defaults to the authed user of the token. Otherwise, the field is required.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Calls_addHandler(cfg), + } +} diff --git a/MCP/go/tools/calls/calls_end.go b/MCP/go/tools/calls/calls_end.go new file mode 100644 index 0000000..278d82e --- /dev/null +++ b/MCP/go/tools/calls/calls_end.go @@ -0,0 +1,100 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Calls_endHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/calls.end", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateCalls_endTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_calls_end", + mcp.WithDescription("Ends a Call."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `calls:write`")), + mcp.WithNumber("duration", mcp.Description("Input parameter: Call duration in seconds")), + mcp.WithString("id", mcp.Required(), mcp.Description("Input parameter: `id` returned when registering the call using the [`calls.add`](/methods/calls.add) method.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Calls_endHandler(cfg), + } +} diff --git a/MCP/go/tools/calls/calls_info.go b/MCP/go/tools/calls/calls_info.go new file mode 100644 index 0000000..f9a8233 --- /dev/null +++ b/MCP/go/tools/calls/calls_info.go @@ -0,0 +1,90 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Calls_infoHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["id"]; ok { + queryParams = append(queryParams, fmt.Sprintf("id=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/calls.info%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateCalls_infoTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_calls_info", + mcp.WithDescription("Returns information about a Call."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `calls:read`")), + mcp.WithString("id", mcp.Required(), mcp.Description("`id` of the Call returned by the [`calls.add`](/methods/calls.add) method.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Calls_infoHandler(cfg), + } +} diff --git a/MCP/go/tools/calls/calls_update.go b/MCP/go/tools/calls/calls_update.go new file mode 100644 index 0000000..2bce2ec --- /dev/null +++ b/MCP/go/tools/calls/calls_update.go @@ -0,0 +1,101 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Calls_updateHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/calls.update", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateCalls_updateTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_calls_update", + mcp.WithDescription("Updates information about a Call."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `calls:write`")), + mcp.WithString("desktop_app_join_url", mcp.Description("Input parameter: When supplied, available Slack clients will attempt to directly launch the 3rd-party Call with this URL.")), + mcp.WithString("join_url", mcp.Description("Input parameter: The URL required for a client to join the Call.")), + mcp.WithString("title", mcp.Description("Input parameter: The name of the Call.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Calls_updateHandler(cfg), + } +} diff --git a/MCP/go/tools/calls_participants/calls_participants_add.go b/MCP/go/tools/calls_participants/calls_participants_add.go new file mode 100644 index 0000000..37ad7f0 --- /dev/null +++ b/MCP/go/tools/calls_participants/calls_participants_add.go @@ -0,0 +1,99 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Calls_participants_addHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/calls.participants.add", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateCalls_participants_addTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_calls_participants_add", + mcp.WithDescription("Registers new participants added to a Call."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `calls:write`")), + mcp.WithString("users", mcp.Required(), mcp.Description("Input parameter: The list of users to add as participants in the Call. [Read more on how to specify users here](/apis/calls#users).")), + ) + + return models.Tool{ + Definition: tool, + Handler: Calls_participants_addHandler(cfg), + } +} diff --git a/MCP/go/tools/calls_participants/calls_participants_remove.go b/MCP/go/tools/calls_participants/calls_participants_remove.go new file mode 100644 index 0000000..d517880 --- /dev/null +++ b/MCP/go/tools/calls_participants/calls_participants_remove.go @@ -0,0 +1,99 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Calls_participants_removeHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/calls.participants.remove", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateCalls_participants_removeTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_calls_participants_remove", + mcp.WithDescription("Registers participants removed from a Call."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `calls:write`")), + mcp.WithString("users", mcp.Required(), mcp.Description("Input parameter: The list of users to remove as participants in the Call. [Read more on how to specify users here](/apis/calls#users).")), + ) + + return models.Tool{ + Definition: tool, + Handler: Calls_participants_removeHandler(cfg), + } +} diff --git a/MCP/go/tools/chat/chat_delete.go b/MCP/go/tools/chat/chat_delete.go new file mode 100644 index 0000000..e920e9f --- /dev/null +++ b/MCP/go/tools/chat/chat_delete.go @@ -0,0 +1,101 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Chat_deleteHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/chat.delete", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateChat_deleteTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_chat_delete", + mcp.WithDescription("Deletes a message."), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `chat:write`")), + mcp.WithString("channel", mcp.Description("Input parameter: Channel containing the message to be deleted.")), + mcp.WithString("ts", mcp.Description("Input parameter: Timestamp of the message to be deleted.")), + mcp.WithBoolean("as_user", mcp.Description("Input parameter: Pass true to delete the message as the authed user with `chat:write:user` scope. [Bot users](/bot-users) in this context are considered authed users. If unused or false, the message will be deleted with `chat:write:bot` scope.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Chat_deleteHandler(cfg), + } +} diff --git a/MCP/go/tools/chat/chat_deletescheduledmessage.go b/MCP/go/tools/chat/chat_deletescheduledmessage.go new file mode 100644 index 0000000..d8c4f42 --- /dev/null +++ b/MCP/go/tools/chat/chat_deletescheduledmessage.go @@ -0,0 +1,101 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Chat_deletescheduledmessageHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/chat.deleteScheduledMessage", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateChat_deletescheduledmessageTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_chat_deleteScheduledMessage", + mcp.WithDescription("Deletes a pending scheduled message from the queue."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `chat:write`")), + mcp.WithString("scheduled_message_id", mcp.Required(), mcp.Description("Input parameter: `scheduled_message_id` returned from call to chat.scheduleMessage")), + mcp.WithBoolean("as_user", mcp.Description("Input parameter: Pass true to delete the message as the authed user with `chat:write:user` scope. [Bot users](/bot-users) in this context are considered authed users. If unused or false, the message will be deleted with `chat:write:bot` scope.")), + mcp.WithString("channel", mcp.Required(), mcp.Description("Input parameter: The channel the scheduled_message is posting to")), + ) + + return models.Tool{ + Definition: tool, + Handler: Chat_deletescheduledmessageHandler(cfg), + } +} diff --git a/MCP/go/tools/chat/chat_getpermalink.go b/MCP/go/tools/chat/chat_getpermalink.go new file mode 100644 index 0000000..d11d7f3 --- /dev/null +++ b/MCP/go/tools/chat/chat_getpermalink.go @@ -0,0 +1,94 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Chat_getpermalinkHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["channel"]; ok { + queryParams = append(queryParams, fmt.Sprintf("channel=%v", val)) + } + if val, ok := args["message_ts"]; ok { + queryParams = append(queryParams, fmt.Sprintf("message_ts=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/chat.getPermalink%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateChat_getpermalinkTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_chat_getPermalink", + mcp.WithDescription("Retrieve a permalink URL for a specific extant message"), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `none`")), + mcp.WithString("channel", mcp.Required(), mcp.Description("The ID of the conversation or channel containing the message")), + mcp.WithString("message_ts", mcp.Required(), mcp.Description("A message's `ts` value, uniquely identifying it within a channel")), + ) + + return models.Tool{ + Definition: tool, + Handler: Chat_getpermalinkHandler(cfg), + } +} diff --git a/MCP/go/tools/chat/chat_memessage.go b/MCP/go/tools/chat/chat_memessage.go new file mode 100644 index 0000000..955c385 --- /dev/null +++ b/MCP/go/tools/chat/chat_memessage.go @@ -0,0 +1,100 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Chat_memessageHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/chat.meMessage", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateChat_memessageTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_chat_meMessage", + mcp.WithDescription("Share a me message into a channel."), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `chat:write`")), + mcp.WithString("channel", mcp.Description("Input parameter: Channel to send message to. Can be a public channel, private group or IM channel. Can be an encoded ID, or a name.")), + mcp.WithString("text", mcp.Description("Input parameter: Text of the message to send.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Chat_memessageHandler(cfg), + } +} diff --git a/MCP/go/tools/chat/chat_postephemeral.go b/MCP/go/tools/chat/chat_postephemeral.go new file mode 100644 index 0000000..e3a8050 --- /dev/null +++ b/MCP/go/tools/chat/chat_postephemeral.go @@ -0,0 +1,110 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Chat_postephemeralHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/chat.postEphemeral", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateChat_postephemeralTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_chat_postEphemeral", + mcp.WithDescription("Sends an ephemeral message to a user in a channel."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `chat:write`")), + mcp.WithBoolean("as_user", mcp.Description("Input parameter: Pass true to post the message as the authed user. Defaults to true if the chat:write:bot scope is not included. Otherwise, defaults to false.")), + mcp.WithString("channel", mcp.Required(), mcp.Description("Input parameter: Channel, private group, or IM channel to send message to. Can be an encoded ID, or a name.")), + mcp.WithBoolean("link_names", mcp.Description("Input parameter: Find and link channel names and usernames.")), + mcp.WithString("text", mcp.Description("Input parameter: How this field works and whether it is required depends on other fields you use in your API call. [See below](#text_usage) for more detail.")), + mcp.WithString("username", mcp.Description("Input parameter: Set your bot's user name. Must be used in conjunction with `as_user` set to false, otherwise ignored. See [authorship](#authorship) below.")), + mcp.WithString("thread_ts", mcp.Description("Input parameter: Provide another message's `ts` value to post this message in a thread. Avoid using a reply's `ts` value; use its parent's value instead. Ephemeral messages in threads are only shown if there is already an active thread.")), + mcp.WithString("user", mcp.Required(), mcp.Description("Input parameter: `id` of the user who will receive the ephemeral message. The user should be in the channel specified by the `channel` argument.")), + mcp.WithString("attachments", mcp.Description("Input parameter: A JSON-based array of structured attachments, presented as a URL-encoded string.")), + mcp.WithString("icon_emoji", mcp.Description("Input parameter: Emoji to use as the icon for this message. Overrides `icon_url`. Must be used in conjunction with `as_user` set to `false`, otherwise ignored. See [authorship](#authorship) below.")), + mcp.WithString("blocks", mcp.Description("Input parameter: A JSON-based array of structured blocks, presented as a URL-encoded string.")), + mcp.WithString("icon_url", mcp.Description("Input parameter: URL to an image to use as the icon for this message. Must be used in conjunction with `as_user` set to false, otherwise ignored. See [authorship](#authorship) below.")), + mcp.WithString("parse", mcp.Description("Input parameter: Change how messages are treated. Defaults to `none`. See [below](#formatting).")), + ) + + return models.Tool{ + Definition: tool, + Handler: Chat_postephemeralHandler(cfg), + } +} diff --git a/MCP/go/tools/chat/chat_postmessage.go b/MCP/go/tools/chat/chat_postmessage.go new file mode 100644 index 0000000..2124474 --- /dev/null +++ b/MCP/go/tools/chat/chat_postmessage.go @@ -0,0 +1,113 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Chat_postmessageHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/chat.postMessage", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateChat_postmessageTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_chat_postMessage", + mcp.WithDescription("Sends a message to a channel."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `chat:write`")), + mcp.WithString("text", mcp.Description("Input parameter: How this field works and whether it is required depends on other fields you use in your API call. [See below](#text_usage) for more detail.")), + mcp.WithString("thread_ts", mcp.Description("Input parameter: Provide another message's `ts` value to make this message a reply. Avoid using a reply's `ts` value; use its parent instead.")), + mcp.WithString("blocks", mcp.Description("Input parameter: A JSON-based array of structured blocks, presented as a URL-encoded string.")), + mcp.WithString("icon_emoji", mcp.Description("Input parameter: Emoji to use as the icon for this message. Overrides `icon_url`. Must be used in conjunction with `as_user` set to `false`, otherwise ignored. See [authorship](#authorship) below.")), + mcp.WithBoolean("reply_broadcast", mcp.Description("Input parameter: Used in conjunction with `thread_ts` and indicates whether reply should be made visible to everyone in the channel or conversation. Defaults to `false`.")), + mcp.WithString("username", mcp.Description("Input parameter: Set your bot's user name. Must be used in conjunction with `as_user` set to false, otherwise ignored. See [authorship](#authorship) below.")), + mcp.WithBoolean("link_names", mcp.Description("Input parameter: Find and link channel names and usernames.")), + mcp.WithString("as_user", mcp.Description("Input parameter: Pass true to post the message as the authed user, instead of as a bot. Defaults to false. See [authorship](#authorship) below.")), + mcp.WithString("attachments", mcp.Description("Input parameter: A JSON-based array of structured attachments, presented as a URL-encoded string.")), + mcp.WithBoolean("unfurl_links", mcp.Description("Input parameter: Pass true to enable unfurling of primarily text-based content.")), + mcp.WithBoolean("unfurl_media", mcp.Description("Input parameter: Pass false to disable unfurling of media content.")), + mcp.WithString("channel", mcp.Required(), mcp.Description("Input parameter: Channel, private group, or IM channel to send message to. Can be an encoded ID, or a name. See [below](#channels) for more details.")), + mcp.WithString("icon_url", mcp.Description("Input parameter: URL to an image to use as the icon for this message. Must be used in conjunction with `as_user` set to false, otherwise ignored. See [authorship](#authorship) below.")), + mcp.WithBoolean("mrkdwn", mcp.Description("Input parameter: Disable Slack markup parsing by setting to `false`. Enabled by default.")), + mcp.WithString("parse", mcp.Description("Input parameter: Change how messages are treated. Defaults to `none`. See [below](#formatting).")), + ) + + return models.Tool{ + Definition: tool, + Handler: Chat_postmessageHandler(cfg), + } +} diff --git a/MCP/go/tools/chat/chat_schedulemessage.go b/MCP/go/tools/chat/chat_schedulemessage.go new file mode 100644 index 0000000..ba7e8c4 --- /dev/null +++ b/MCP/go/tools/chat/chat_schedulemessage.go @@ -0,0 +1,110 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Chat_schedulemessageHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/chat.scheduleMessage", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateChat_schedulemessageTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_chat_scheduleMessage", + mcp.WithDescription("Schedules a message to be sent to a channel."), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `chat:write`")), + mcp.WithString("attachments", mcp.Description("Input parameter: A JSON-based array of structured attachments, presented as a URL-encoded string.")), + mcp.WithString("text", mcp.Description("Input parameter: How this field works and whether it is required depends on other fields you use in your API call. [See below](#text_usage) for more detail.")), + mcp.WithBoolean("unfurl_links", mcp.Description("Input parameter: Pass true to enable unfurling of primarily text-based content.")), + mcp.WithString("parse", mcp.Description("Input parameter: Change how messages are treated. Defaults to `none`. See [chat.postMessage](chat.postMessage#formatting).")), + mcp.WithBoolean("unfurl_media", mcp.Description("Input parameter: Pass false to disable unfurling of media content.")), + mcp.WithBoolean("as_user", mcp.Description("Input parameter: Pass true to post the message as the authed user, instead of as a bot. Defaults to false. See [chat.postMessage](chat.postMessage#authorship).")), + mcp.WithString("blocks", mcp.Description("Input parameter: A JSON-based array of structured blocks, presented as a URL-encoded string.")), + mcp.WithBoolean("link_names", mcp.Description("Input parameter: Find and link channel names and usernames.")), + mcp.WithString("channel", mcp.Description("Input parameter: Channel, private group, or DM channel to send message to. Can be an encoded ID, or a name. See [below](#channels) for more details.")), + mcp.WithString("post_at", mcp.Description("Input parameter: Unix EPOCH timestamp of time in future to send the message.")), + mcp.WithBoolean("reply_broadcast", mcp.Description("Input parameter: Used in conjunction with `thread_ts` and indicates whether reply should be made visible to everyone in the channel or conversation. Defaults to `false`.")), + mcp.WithString("thread_ts", mcp.Description("Input parameter: Provide another message's `ts` value to make this message a reply. Avoid using a reply's `ts` value; use its parent instead.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Chat_schedulemessageHandler(cfg), + } +} diff --git a/MCP/go/tools/chat/chat_unfurl.go b/MCP/go/tools/chat/chat_unfurl.go new file mode 100644 index 0000000..9ec83cf --- /dev/null +++ b/MCP/go/tools/chat/chat_unfurl.go @@ -0,0 +1,104 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Chat_unfurlHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/chat.unfurl", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateChat_unfurlTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_chat_unfurl", + mcp.WithDescription("Provide custom unfurl behavior for user-posted URLs"), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `links:write`")), + mcp.WithBoolean("user_auth_required", mcp.Description("Input parameter: Set to `true` or `1` to indicate the user must install your Slack app to trigger unfurls for this domain")), + mcp.WithString("user_auth_url", mcp.Description("Input parameter: Send users to this custom URL where they will complete authentication in your app to fully trigger unfurling. Value should be properly URL-encoded.")), + mcp.WithString("channel", mcp.Required(), mcp.Description("Input parameter: Channel ID of the message")), + mcp.WithString("ts", mcp.Required(), mcp.Description("Input parameter: Timestamp of the message to add unfurl behavior to.")), + mcp.WithString("unfurls", mcp.Description("Input parameter: URL-encoded JSON map with keys set to URLs featured in the the message, pointing to their unfurl blocks or message attachments.")), + mcp.WithString("user_auth_message", mcp.Description("Input parameter: Provide a simply-formatted string to send as an ephemeral message to the user as invitation to authenticate further and enable full unfurling behavior")), + ) + + return models.Tool{ + Definition: tool, + Handler: Chat_unfurlHandler(cfg), + } +} diff --git a/MCP/go/tools/chat/chat_update.go b/MCP/go/tools/chat/chat_update.go new file mode 100644 index 0000000..8072c49 --- /dev/null +++ b/MCP/go/tools/chat/chat_update.go @@ -0,0 +1,106 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Chat_updateHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/chat.update", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateChat_updateTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_chat_update", + mcp.WithDescription("Updates a message."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `chat:write`")), + mcp.WithString("text", mcp.Description("Input parameter: New text for the message, using the [default formatting rules](/reference/surfaces/formatting). It's not required when presenting `blocks` or `attachments`.")), + mcp.WithString("ts", mcp.Required(), mcp.Description("Input parameter: Timestamp of the message to be updated.")), + mcp.WithString("as_user", mcp.Description("Input parameter: Pass true to update the message as the authed user. [Bot users](/bot-users) in this context are considered authed users.")), + mcp.WithString("attachments", mcp.Description("Input parameter: A JSON-based array of structured attachments, presented as a URL-encoded string. This field is required when not presenting `text`. If you don't include this field, the message's previous `attachments` will be retained. To remove previous `attachments`, include an empty array for this field.")), + mcp.WithString("blocks", mcp.Description("Input parameter: A JSON-based array of [structured blocks](/block-kit/building), presented as a URL-encoded string. If you don't include this field, the message's previous `blocks` will be retained. To remove previous `blocks`, include an empty array for this field.")), + mcp.WithString("channel", mcp.Required(), mcp.Description("Input parameter: Channel containing the message to be updated.")), + mcp.WithString("link_names", mcp.Description("Input parameter: Find and link channel names and usernames. Defaults to `none`. If you do not specify a value for this field, the original value set for the message will be overwritten with the default, `none`.")), + mcp.WithString("parse", mcp.Description("Input parameter: Change how messages are treated. Defaults to `client`, unlike `chat.postMessage`. Accepts either `none` or `full`. If you do not specify a value for this field, the original value set for the message will be overwritten with the default, `client`.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Chat_updateHandler(cfg), + } +} diff --git a/MCP/go/tools/chat_scheduledmessages/chat_scheduledmessages_list.go b/MCP/go/tools/chat_scheduledmessages/chat_scheduledmessages_list.go new file mode 100644 index 0000000..361f5e6 --- /dev/null +++ b/MCP/go/tools/chat_scheduledmessages/chat_scheduledmessages_list.go @@ -0,0 +1,106 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Chat_scheduledmessages_listHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["channel"]; ok { + queryParams = append(queryParams, fmt.Sprintf("channel=%v", val)) + } + if val, ok := args["latest"]; ok { + queryParams = append(queryParams, fmt.Sprintf("latest=%v", val)) + } + if val, ok := args["oldest"]; ok { + queryParams = append(queryParams, fmt.Sprintf("oldest=%v", val)) + } + if val, ok := args["limit"]; ok { + queryParams = append(queryParams, fmt.Sprintf("limit=%v", val)) + } + if val, ok := args["cursor"]; ok { + queryParams = append(queryParams, fmt.Sprintf("cursor=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/chat.scheduledMessages.list%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateChat_scheduledmessages_listTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_chat_scheduledMessages_list", + mcp.WithDescription("Returns a list of scheduled messages."), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `none`")), + mcp.WithString("channel", mcp.Description("The channel of the scheduled messages")), + mcp.WithString("latest", mcp.Description("A UNIX timestamp of the latest value in the time range")), + mcp.WithString("oldest", mcp.Description("A UNIX timestamp of the oldest value in the time range")), + mcp.WithNumber("limit", mcp.Description("Maximum number of original entries to return.")), + mcp.WithString("cursor", mcp.Description("For pagination purposes, this is the `cursor` value returned from a previous call to `chat.scheduledmessages.list` indicating where you want to start this call from.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Chat_scheduledmessages_listHandler(cfg), + } +} diff --git a/MCP/go/tools/conversations/conversations_archive.go b/MCP/go/tools/conversations/conversations_archive.go new file mode 100644 index 0000000..95809e2 --- /dev/null +++ b/MCP/go/tools/conversations/conversations_archive.go @@ -0,0 +1,99 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Conversations_archiveHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/conversations.archive", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateConversations_archiveTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_conversations_archive", + mcp.WithDescription("Archives a conversation."), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `conversations:write`")), + mcp.WithString("channel", mcp.Description("Input parameter: ID of conversation to archive")), + ) + + return models.Tool{ + Definition: tool, + Handler: Conversations_archiveHandler(cfg), + } +} diff --git a/MCP/go/tools/conversations/conversations_close.go b/MCP/go/tools/conversations/conversations_close.go new file mode 100644 index 0000000..0cb8d3c --- /dev/null +++ b/MCP/go/tools/conversations/conversations_close.go @@ -0,0 +1,99 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Conversations_closeHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/conversations.close", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateConversations_closeTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_conversations_close", + mcp.WithDescription("Closes a direct message or multi-person direct message."), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `conversations:write`")), + mcp.WithString("channel", mcp.Description("Input parameter: Conversation to close.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Conversations_closeHandler(cfg), + } +} diff --git a/MCP/go/tools/conversations/conversations_create.go b/MCP/go/tools/conversations/conversations_create.go new file mode 100644 index 0000000..0fdd6e1 --- /dev/null +++ b/MCP/go/tools/conversations/conversations_create.go @@ -0,0 +1,100 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Conversations_createHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/conversations.create", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateConversations_createTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_conversations_create", + mcp.WithDescription("Initiates a public or private channel-based conversation"), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `conversations:write`")), + mcp.WithBoolean("is_private", mcp.Description("Input parameter: Create a private channel instead of a public one")), + mcp.WithString("name", mcp.Description("Input parameter: Name of the public or private channel to create")), + ) + + return models.Tool{ + Definition: tool, + Handler: Conversations_createHandler(cfg), + } +} diff --git a/MCP/go/tools/conversations/conversations_history.go b/MCP/go/tools/conversations/conversations_history.go new file mode 100644 index 0000000..4a01763 --- /dev/null +++ b/MCP/go/tools/conversations/conversations_history.go @@ -0,0 +1,110 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Conversations_historyHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["channel"]; ok { + queryParams = append(queryParams, fmt.Sprintf("channel=%v", val)) + } + if val, ok := args["latest"]; ok { + queryParams = append(queryParams, fmt.Sprintf("latest=%v", val)) + } + if val, ok := args["oldest"]; ok { + queryParams = append(queryParams, fmt.Sprintf("oldest=%v", val)) + } + if val, ok := args["inclusive"]; ok { + queryParams = append(queryParams, fmt.Sprintf("inclusive=%v", val)) + } + if val, ok := args["limit"]; ok { + queryParams = append(queryParams, fmt.Sprintf("limit=%v", val)) + } + if val, ok := args["cursor"]; ok { + queryParams = append(queryParams, fmt.Sprintf("cursor=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/conversations.history%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateConversations_historyTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_conversations_history", + mcp.WithDescription("Fetches a conversation's history of messages and events."), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `conversations:history`")), + mcp.WithString("channel", mcp.Description("Conversation ID to fetch history for.")), + mcp.WithString("latest", mcp.Description("End of time range of messages to include in results.")), + mcp.WithString("oldest", mcp.Description("Start of time range of messages to include in results.")), + mcp.WithBoolean("inclusive", mcp.Description("Include messages with latest or oldest timestamp in results only when either timestamp is specified.")), + mcp.WithNumber("limit", mcp.Description("The maximum number of items to return. Fewer than the requested number of items may be returned, even if the end of the users list hasn't been reached.")), + mcp.WithString("cursor", mcp.Description("Paginate through collections of data by setting the `cursor` parameter to a `next_cursor` attribute returned by a previous request's `response_metadata`. Default value fetches the first \"page\" of the collection. See [pagination](/docs/pagination) for more detail.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Conversations_historyHandler(cfg), + } +} diff --git a/MCP/go/tools/conversations/conversations_info.go b/MCP/go/tools/conversations/conversations_info.go new file mode 100644 index 0000000..887d444 --- /dev/null +++ b/MCP/go/tools/conversations/conversations_info.go @@ -0,0 +1,98 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Conversations_infoHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["channel"]; ok { + queryParams = append(queryParams, fmt.Sprintf("channel=%v", val)) + } + if val, ok := args["include_locale"]; ok { + queryParams = append(queryParams, fmt.Sprintf("include_locale=%v", val)) + } + if val, ok := args["include_num_members"]; ok { + queryParams = append(queryParams, fmt.Sprintf("include_num_members=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/conversations.info%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateConversations_infoTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_conversations_info", + mcp.WithDescription("Retrieve information about a conversation."), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `conversations:read`")), + mcp.WithString("channel", mcp.Description("Conversation ID to learn more about")), + mcp.WithBoolean("include_locale", mcp.Description("Set this to `true` to receive the locale for this conversation. Defaults to `false`")), + mcp.WithBoolean("include_num_members", mcp.Description("Set to `true` to include the member count for the specified conversation. Defaults to `false`")), + ) + + return models.Tool{ + Definition: tool, + Handler: Conversations_infoHandler(cfg), + } +} diff --git a/MCP/go/tools/conversations/conversations_invite.go b/MCP/go/tools/conversations/conversations_invite.go new file mode 100644 index 0000000..c3e275f --- /dev/null +++ b/MCP/go/tools/conversations/conversations_invite.go @@ -0,0 +1,100 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Conversations_inviteHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/conversations.invite", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateConversations_inviteTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_conversations_invite", + mcp.WithDescription("Invites users to a channel."), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `conversations:write`")), + mcp.WithString("channel", mcp.Description("Input parameter: The ID of the public or private channel to invite user(s) to.")), + mcp.WithString("users", mcp.Description("Input parameter: A comma separated list of user IDs. Up to 1000 users may be listed.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Conversations_inviteHandler(cfg), + } +} diff --git a/MCP/go/tools/conversations/conversations_join.go b/MCP/go/tools/conversations/conversations_join.go new file mode 100644 index 0000000..3412cd9 --- /dev/null +++ b/MCP/go/tools/conversations/conversations_join.go @@ -0,0 +1,99 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Conversations_joinHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/conversations.join", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateConversations_joinTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_conversations_join", + mcp.WithDescription("Joins an existing conversation."), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `channels:write`")), + mcp.WithString("channel", mcp.Description("Input parameter: ID of conversation to join")), + ) + + return models.Tool{ + Definition: tool, + Handler: Conversations_joinHandler(cfg), + } +} diff --git a/MCP/go/tools/conversations/conversations_kick.go b/MCP/go/tools/conversations/conversations_kick.go new file mode 100644 index 0000000..3e92242 --- /dev/null +++ b/MCP/go/tools/conversations/conversations_kick.go @@ -0,0 +1,100 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Conversations_kickHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/conversations.kick", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateConversations_kickTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_conversations_kick", + mcp.WithDescription("Removes a user from a conversation."), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `conversations:write`")), + mcp.WithString("channel", mcp.Description("Input parameter: ID of conversation to remove user from.")), + mcp.WithString("user", mcp.Description("Input parameter: User ID to be removed.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Conversations_kickHandler(cfg), + } +} diff --git a/MCP/go/tools/conversations/conversations_leave.go b/MCP/go/tools/conversations/conversations_leave.go new file mode 100644 index 0000000..4550ad5 --- /dev/null +++ b/MCP/go/tools/conversations/conversations_leave.go @@ -0,0 +1,99 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Conversations_leaveHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/conversations.leave", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateConversations_leaveTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_conversations_leave", + mcp.WithDescription("Leaves a conversation."), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `conversations:write`")), + mcp.WithString("channel", mcp.Description("Input parameter: Conversation to leave")), + ) + + return models.Tool{ + Definition: tool, + Handler: Conversations_leaveHandler(cfg), + } +} diff --git a/MCP/go/tools/conversations/conversations_list.go b/MCP/go/tools/conversations/conversations_list.go new file mode 100644 index 0000000..25e79e8 --- /dev/null +++ b/MCP/go/tools/conversations/conversations_list.go @@ -0,0 +1,102 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Conversations_listHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["exclude_archived"]; ok { + queryParams = append(queryParams, fmt.Sprintf("exclude_archived=%v", val)) + } + if val, ok := args["types"]; ok { + queryParams = append(queryParams, fmt.Sprintf("types=%v", val)) + } + if val, ok := args["limit"]; ok { + queryParams = append(queryParams, fmt.Sprintf("limit=%v", val)) + } + if val, ok := args["cursor"]; ok { + queryParams = append(queryParams, fmt.Sprintf("cursor=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/conversations.list%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateConversations_listTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_conversations_list", + mcp.WithDescription("Lists all channels in a Slack team."), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `conversations:read`")), + mcp.WithBoolean("exclude_archived", mcp.Description("Set to `true` to exclude archived channels from the list")), + mcp.WithString("types", mcp.Description("Mix and match channel types by providing a comma-separated list of any combination of `public_channel`, `private_channel`, `mpim`, `im`")), + mcp.WithNumber("limit", mcp.Description("The maximum number of items to return. Fewer than the requested number of items may be returned, even if the end of the list hasn't been reached. Must be an integer no larger than 1000.")), + mcp.WithString("cursor", mcp.Description("Paginate through collections of data by setting the `cursor` parameter to a `next_cursor` attribute returned by a previous request's `response_metadata`. Default value fetches the first \"page\" of the collection. See [pagination](/docs/pagination) for more detail.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Conversations_listHandler(cfg), + } +} diff --git a/MCP/go/tools/conversations/conversations_mark.go b/MCP/go/tools/conversations/conversations_mark.go new file mode 100644 index 0000000..41e7586 --- /dev/null +++ b/MCP/go/tools/conversations/conversations_mark.go @@ -0,0 +1,100 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Conversations_markHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/conversations.mark", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateConversations_markTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_conversations_mark", + mcp.WithDescription("Sets the read cursor in a channel."), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `conversations:write`")), + mcp.WithString("channel", mcp.Description("Input parameter: Channel or conversation to set the read cursor for.")), + mcp.WithString("ts", mcp.Description("Input parameter: Unique identifier of message you want marked as most recently seen in this conversation.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Conversations_markHandler(cfg), + } +} diff --git a/MCP/go/tools/conversations/conversations_members.go b/MCP/go/tools/conversations/conversations_members.go new file mode 100644 index 0000000..9056902 --- /dev/null +++ b/MCP/go/tools/conversations/conversations_members.go @@ -0,0 +1,98 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Conversations_membersHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["channel"]; ok { + queryParams = append(queryParams, fmt.Sprintf("channel=%v", val)) + } + if val, ok := args["limit"]; ok { + queryParams = append(queryParams, fmt.Sprintf("limit=%v", val)) + } + if val, ok := args["cursor"]; ok { + queryParams = append(queryParams, fmt.Sprintf("cursor=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/conversations.members%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateConversations_membersTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_conversations_members", + mcp.WithDescription("Retrieve members of a conversation."), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `conversations:read`")), + mcp.WithString("channel", mcp.Description("ID of the conversation to retrieve members for")), + mcp.WithNumber("limit", mcp.Description("The maximum number of items to return. Fewer than the requested number of items may be returned, even if the end of the users list hasn't been reached.")), + mcp.WithString("cursor", mcp.Description("Paginate through collections of data by setting the `cursor` parameter to a `next_cursor` attribute returned by a previous request's `response_metadata`. Default value fetches the first \"page\" of the collection. See [pagination](/docs/pagination) for more detail.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Conversations_membersHandler(cfg), + } +} diff --git a/MCP/go/tools/conversations/conversations_open.go b/MCP/go/tools/conversations/conversations_open.go new file mode 100644 index 0000000..f9da266 --- /dev/null +++ b/MCP/go/tools/conversations/conversations_open.go @@ -0,0 +1,101 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Conversations_openHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/conversations.open", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateConversations_openTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_conversations_open", + mcp.WithDescription("Opens or resumes a direct message or multi-person direct message."), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `conversations:write`")), + mcp.WithString("channel", mcp.Description("Input parameter: Resume a conversation by supplying an `im` or `mpim`'s ID. Or provide the `users` field instead.")), + mcp.WithBoolean("return_im", mcp.Description("Input parameter: Boolean, indicates you want the full IM channel definition in the response.")), + mcp.WithString("users", mcp.Description("Input parameter: Comma separated lists of users. If only one user is included, this creates a 1:1 DM. The ordering of the users is preserved whenever a multi-person direct message is returned. Supply a `channel` when not supplying `users`.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Conversations_openHandler(cfg), + } +} diff --git a/MCP/go/tools/conversations/conversations_rename.go b/MCP/go/tools/conversations/conversations_rename.go new file mode 100644 index 0000000..9d3b178 --- /dev/null +++ b/MCP/go/tools/conversations/conversations_rename.go @@ -0,0 +1,100 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Conversations_renameHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/conversations.rename", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateConversations_renameTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_conversations_rename", + mcp.WithDescription("Renames a conversation."), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `conversations:write`")), + mcp.WithString("name", mcp.Description("Input parameter: New name for conversation.")), + mcp.WithString("channel", mcp.Description("Input parameter: ID of conversation to rename")), + ) + + return models.Tool{ + Definition: tool, + Handler: Conversations_renameHandler(cfg), + } +} diff --git a/MCP/go/tools/conversations/conversations_replies.go b/MCP/go/tools/conversations/conversations_replies.go new file mode 100644 index 0000000..ebad7d0 --- /dev/null +++ b/MCP/go/tools/conversations/conversations_replies.go @@ -0,0 +1,114 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Conversations_repliesHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["channel"]; ok { + queryParams = append(queryParams, fmt.Sprintf("channel=%v", val)) + } + if val, ok := args["ts"]; ok { + queryParams = append(queryParams, fmt.Sprintf("ts=%v", val)) + } + if val, ok := args["latest"]; ok { + queryParams = append(queryParams, fmt.Sprintf("latest=%v", val)) + } + if val, ok := args["oldest"]; ok { + queryParams = append(queryParams, fmt.Sprintf("oldest=%v", val)) + } + if val, ok := args["inclusive"]; ok { + queryParams = append(queryParams, fmt.Sprintf("inclusive=%v", val)) + } + if val, ok := args["limit"]; ok { + queryParams = append(queryParams, fmt.Sprintf("limit=%v", val)) + } + if val, ok := args["cursor"]; ok { + queryParams = append(queryParams, fmt.Sprintf("cursor=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/conversations.replies%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateConversations_repliesTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_conversations_replies", + mcp.WithDescription("Retrieve a thread of messages posted to a conversation"), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `conversations:history`")), + mcp.WithString("channel", mcp.Description("Conversation ID to fetch thread from.")), + mcp.WithString("ts", mcp.Description("Unique identifier of a thread's parent message. `ts` must be the timestamp of an existing message with 0 or more replies. If there are no replies then just the single message referenced by `ts` will return - it is just an ordinary, unthreaded message.")), + mcp.WithString("latest", mcp.Description("End of time range of messages to include in results.")), + mcp.WithString("oldest", mcp.Description("Start of time range of messages to include in results.")), + mcp.WithBoolean("inclusive", mcp.Description("Include messages with latest or oldest timestamp in results only when either timestamp is specified.")), + mcp.WithNumber("limit", mcp.Description("The maximum number of items to return. Fewer than the requested number of items may be returned, even if the end of the users list hasn't been reached.")), + mcp.WithString("cursor", mcp.Description("Paginate through collections of data by setting the `cursor` parameter to a `next_cursor` attribute returned by a previous request's `response_metadata`. Default value fetches the first \"page\" of the collection. See [pagination](/docs/pagination) for more detail.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Conversations_repliesHandler(cfg), + } +} diff --git a/MCP/go/tools/conversations/conversations_setpurpose.go b/MCP/go/tools/conversations/conversations_setpurpose.go new file mode 100644 index 0000000..d7e6ccf --- /dev/null +++ b/MCP/go/tools/conversations/conversations_setpurpose.go @@ -0,0 +1,100 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Conversations_setpurposeHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/conversations.setPurpose", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateConversations_setpurposeTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_conversations_setPurpose", + mcp.WithDescription("Sets the purpose for a conversation."), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `conversations:write`")), + mcp.WithString("purpose", mcp.Description("Input parameter: A new, specialer purpose")), + mcp.WithString("channel", mcp.Description("Input parameter: Conversation to set the purpose of")), + ) + + return models.Tool{ + Definition: tool, + Handler: Conversations_setpurposeHandler(cfg), + } +} diff --git a/MCP/go/tools/conversations/conversations_settopic.go b/MCP/go/tools/conversations/conversations_settopic.go new file mode 100644 index 0000000..ab18568 --- /dev/null +++ b/MCP/go/tools/conversations/conversations_settopic.go @@ -0,0 +1,100 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Conversations_settopicHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/conversations.setTopic", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateConversations_settopicTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_conversations_setTopic", + mcp.WithDescription("Sets the topic for a conversation."), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `conversations:write`")), + mcp.WithString("channel", mcp.Description("Input parameter: Conversation to set the topic of")), + mcp.WithString("topic", mcp.Description("Input parameter: The new topic string. Does not support formatting or linkification.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Conversations_settopicHandler(cfg), + } +} diff --git a/MCP/go/tools/conversations/conversations_unarchive.go b/MCP/go/tools/conversations/conversations_unarchive.go new file mode 100644 index 0000000..89e4e55 --- /dev/null +++ b/MCP/go/tools/conversations/conversations_unarchive.go @@ -0,0 +1,99 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Conversations_unarchiveHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/conversations.unarchive", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateConversations_unarchiveTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_conversations_unarchive", + mcp.WithDescription("Reverses conversation archival."), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `conversations:write`")), + mcp.WithString("channel", mcp.Description("Input parameter: ID of conversation to unarchive")), + ) + + return models.Tool{ + Definition: tool, + Handler: Conversations_unarchiveHandler(cfg), + } +} diff --git a/MCP/go/tools/dialog/dialog_open.go b/MCP/go/tools/dialog/dialog_open.go new file mode 100644 index 0000000..bde8364 --- /dev/null +++ b/MCP/go/tools/dialog/dialog_open.go @@ -0,0 +1,94 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Dialog_openHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["dialog"]; ok { + queryParams = append(queryParams, fmt.Sprintf("dialog=%v", val)) + } + if val, ok := args["trigger_id"]; ok { + queryParams = append(queryParams, fmt.Sprintf("trigger_id=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/dialog.open%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateDialog_openTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_dialog_open", + mcp.WithDescription("Open a dialog with a user"), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `none`")), + mcp.WithString("dialog", mcp.Required(), mcp.Description("The dialog definition. This must be a JSON-encoded string.")), + mcp.WithString("trigger_id", mcp.Required(), mcp.Description("Exchange a trigger to post to the user.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Dialog_openHandler(cfg), + } +} diff --git a/MCP/go/tools/dnd/dnd_enddnd.go b/MCP/go/tools/dnd/dnd_enddnd.go new file mode 100644 index 0000000..5015fa6 --- /dev/null +++ b/MCP/go/tools/dnd/dnd_enddnd.go @@ -0,0 +1,80 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Dnd_enddndHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + url := fmt.Sprintf("%s/dnd.endDnd", cfg.BaseURL) + req, err := http.NewRequest("POST", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateDnd_enddndTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_dnd_endDnd", + mcp.WithDescription("Ends the current user's Do Not Disturb session immediately."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `dnd:write`")), + ) + + return models.Tool{ + Definition: tool, + Handler: Dnd_enddndHandler(cfg), + } +} diff --git a/MCP/go/tools/dnd/dnd_endsnooze.go b/MCP/go/tools/dnd/dnd_endsnooze.go new file mode 100644 index 0000000..ec2f9ac --- /dev/null +++ b/MCP/go/tools/dnd/dnd_endsnooze.go @@ -0,0 +1,80 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Dnd_endsnoozeHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + url := fmt.Sprintf("%s/dnd.endSnooze", cfg.BaseURL) + req, err := http.NewRequest("POST", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateDnd_endsnoozeTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_dnd_endSnooze", + mcp.WithDescription("Ends the current user's snooze mode immediately."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `dnd:write`")), + ) + + return models.Tool{ + Definition: tool, + Handler: Dnd_endsnoozeHandler(cfg), + } +} diff --git a/MCP/go/tools/dnd/dnd_info.go b/MCP/go/tools/dnd/dnd_info.go new file mode 100644 index 0000000..991cc73 --- /dev/null +++ b/MCP/go/tools/dnd/dnd_info.go @@ -0,0 +1,90 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Dnd_infoHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["user"]; ok { + queryParams = append(queryParams, fmt.Sprintf("user=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/dnd.info%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateDnd_infoTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_dnd_info", + mcp.WithDescription("Retrieves a user's current Do Not Disturb status."), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `dnd:read`")), + mcp.WithString("user", mcp.Description("User to fetch status for (defaults to current user)")), + ) + + return models.Tool{ + Definition: tool, + Handler: Dnd_infoHandler(cfg), + } +} diff --git a/MCP/go/tools/dnd/dnd_teaminfo.go b/MCP/go/tools/dnd/dnd_teaminfo.go new file mode 100644 index 0000000..f4638e3 --- /dev/null +++ b/MCP/go/tools/dnd/dnd_teaminfo.go @@ -0,0 +1,90 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Dnd_teaminfoHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["users"]; ok { + queryParams = append(queryParams, fmt.Sprintf("users=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/dnd.teamInfo%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateDnd_teaminfoTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_dnd_teamInfo", + mcp.WithDescription("Retrieves the Do Not Disturb status for up to 50 users on a team."), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `dnd:read`")), + mcp.WithString("users", mcp.Description("Comma-separated list of users to fetch Do Not Disturb status for")), + ) + + return models.Tool{ + Definition: tool, + Handler: Dnd_teaminfoHandler(cfg), + } +} diff --git a/MCP/go/tools/emoji/emoji_list.go b/MCP/go/tools/emoji/emoji_list.go new file mode 100644 index 0000000..6a71b2c --- /dev/null +++ b/MCP/go/tools/emoji/emoji_list.go @@ -0,0 +1,86 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Emoji_listHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/emoji.list%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateEmoji_listTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_emoji_list", + mcp.WithDescription("Lists custom emoji for a team."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `emoji:read`")), + ) + + return models.Tool{ + Definition: tool, + Handler: Emoji_listHandler(cfg), + } +} diff --git a/MCP/go/tools/files/files_delete.go b/MCP/go/tools/files/files_delete.go new file mode 100644 index 0000000..a500e34 --- /dev/null +++ b/MCP/go/tools/files/files_delete.go @@ -0,0 +1,99 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Files_deleteHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/files.delete", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateFiles_deleteTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_files_delete", + mcp.WithDescription("Deletes a file."), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `files:write:user`")), + mcp.WithString("file", mcp.Description("Input parameter: ID of file to delete.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Files_deleteHandler(cfg), + } +} diff --git a/MCP/go/tools/files/files_info.go b/MCP/go/tools/files/files_info.go new file mode 100644 index 0000000..fcc3f77 --- /dev/null +++ b/MCP/go/tools/files/files_info.go @@ -0,0 +1,106 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Files_infoHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["file"]; ok { + queryParams = append(queryParams, fmt.Sprintf("file=%v", val)) + } + if val, ok := args["count"]; ok { + queryParams = append(queryParams, fmt.Sprintf("count=%v", val)) + } + if val, ok := args["page"]; ok { + queryParams = append(queryParams, fmt.Sprintf("page=%v", val)) + } + if val, ok := args["limit"]; ok { + queryParams = append(queryParams, fmt.Sprintf("limit=%v", val)) + } + if val, ok := args["cursor"]; ok { + queryParams = append(queryParams, fmt.Sprintf("cursor=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/files.info%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateFiles_infoTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_files_info", + mcp.WithDescription("Gets information about a file."), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `files:read`")), + mcp.WithString("file", mcp.Description("Specify a file by providing its ID.")), + mcp.WithString("count", mcp.Description("")), + mcp.WithString("page", mcp.Description("")), + mcp.WithNumber("limit", mcp.Description("The maximum number of items to return. Fewer than the requested number of items may be returned, even if the end of the list hasn't been reached.")), + mcp.WithString("cursor", mcp.Description("Parameter for pagination. File comments are paginated for a single file. Set `cursor` equal to the `next_cursor` attribute returned by the previous request's `response_metadata`. This parameter is optional, but pagination is mandatory: the default value simply fetches the first \"page\" of the collection of comments. See [pagination](/docs/pagination) for more details.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Files_infoHandler(cfg), + } +} diff --git a/MCP/go/tools/files/files_list.go b/MCP/go/tools/files/files_list.go new file mode 100644 index 0000000..c7de7c6 --- /dev/null +++ b/MCP/go/tools/files/files_list.go @@ -0,0 +1,118 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Files_listHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["user"]; ok { + queryParams = append(queryParams, fmt.Sprintf("user=%v", val)) + } + if val, ok := args["channel"]; ok { + queryParams = append(queryParams, fmt.Sprintf("channel=%v", val)) + } + if val, ok := args["ts_from"]; ok { + queryParams = append(queryParams, fmt.Sprintf("ts_from=%v", val)) + } + if val, ok := args["ts_to"]; ok { + queryParams = append(queryParams, fmt.Sprintf("ts_to=%v", val)) + } + if val, ok := args["types"]; ok { + queryParams = append(queryParams, fmt.Sprintf("types=%v", val)) + } + if val, ok := args["count"]; ok { + queryParams = append(queryParams, fmt.Sprintf("count=%v", val)) + } + if val, ok := args["page"]; ok { + queryParams = append(queryParams, fmt.Sprintf("page=%v", val)) + } + if val, ok := args["show_files_hidden_by_limit"]; ok { + queryParams = append(queryParams, fmt.Sprintf("show_files_hidden_by_limit=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/files.list%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateFiles_listTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_files_list", + mcp.WithDescription("List for a team, in a channel, or from a user with applied filters."), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `files:read`")), + mcp.WithString("user", mcp.Description("Filter files created by a single user.")), + mcp.WithString("channel", mcp.Description("Filter files appearing in a specific channel, indicated by its ID.")), + mcp.WithString("ts_from", mcp.Description("Filter files created after this timestamp (inclusive).")), + mcp.WithString("ts_to", mcp.Description("Filter files created before this timestamp (inclusive).")), + mcp.WithString("types", mcp.Description("Filter files by type ([see below](#file_types)). You can pass multiple values in the types argument, like `types=spaces,snippets`.The default value is `all`, which does not filter the list.")), + mcp.WithString("count", mcp.Description("")), + mcp.WithString("page", mcp.Description("")), + mcp.WithBoolean("show_files_hidden_by_limit", mcp.Description("Show truncated file info for files hidden due to being too old, and the team who owns the file being over the file limit.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Files_listHandler(cfg), + } +} diff --git a/MCP/go/tools/files/files_revokepublicurl.go b/MCP/go/tools/files/files_revokepublicurl.go new file mode 100644 index 0000000..4ed0cf2 --- /dev/null +++ b/MCP/go/tools/files/files_revokepublicurl.go @@ -0,0 +1,99 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Files_revokepublicurlHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/files.revokePublicURL", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateFiles_revokepublicurlTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_files_revokePublicURL", + mcp.WithDescription("Revokes public/external sharing access for a file"), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `files:write:user`")), + mcp.WithString("file", mcp.Description("Input parameter: File to revoke")), + ) + + return models.Tool{ + Definition: tool, + Handler: Files_revokepublicurlHandler(cfg), + } +} diff --git a/MCP/go/tools/files/files_sharedpublicurl.go b/MCP/go/tools/files/files_sharedpublicurl.go new file mode 100644 index 0000000..de8f32a --- /dev/null +++ b/MCP/go/tools/files/files_sharedpublicurl.go @@ -0,0 +1,99 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Files_sharedpublicurlHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/files.sharedPublicURL", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateFiles_sharedpublicurlTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_files_sharedPublicURL", + mcp.WithDescription("Enables a file for public/external sharing."), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `files:write:user`")), + mcp.WithString("file", mcp.Description("Input parameter: File to share")), + ) + + return models.Tool{ + Definition: tool, + Handler: Files_sharedpublicurlHandler(cfg), + } +} diff --git a/MCP/go/tools/files_comments/files_comments_delete.go b/MCP/go/tools/files_comments/files_comments_delete.go new file mode 100644 index 0000000..26647a7 --- /dev/null +++ b/MCP/go/tools/files_comments/files_comments_delete.go @@ -0,0 +1,100 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Files_comments_deleteHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/files.comments.delete", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateFiles_comments_deleteTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_files_comments_delete", + mcp.WithDescription("Deletes an existing comment on a file."), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `files:write:user`")), + mcp.WithString("id", mcp.Description("Input parameter: The comment to delete.")), + mcp.WithString("file", mcp.Description("Input parameter: File to delete a comment from.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Files_comments_deleteHandler(cfg), + } +} diff --git a/MCP/go/tools/files_remote/files_remote_info.go b/MCP/go/tools/files_remote/files_remote_info.go new file mode 100644 index 0000000..fa8caa1 --- /dev/null +++ b/MCP/go/tools/files_remote/files_remote_info.go @@ -0,0 +1,94 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Files_remote_infoHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["file"]; ok { + queryParams = append(queryParams, fmt.Sprintf("file=%v", val)) + } + if val, ok := args["external_id"]; ok { + queryParams = append(queryParams, fmt.Sprintf("external_id=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/files.remote.info%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateFiles_remote_infoTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_files_remote_info", + mcp.WithDescription("Retrieve information about a remote file added to Slack"), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `remote_files:read`")), + mcp.WithString("file", mcp.Description("Specify a file by providing its ID.")), + mcp.WithString("external_id", mcp.Description("Creator defined GUID for the file.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Files_remote_infoHandler(cfg), + } +} diff --git a/MCP/go/tools/files_remote/files_remote_list.go b/MCP/go/tools/files_remote/files_remote_list.go new file mode 100644 index 0000000..97feddb --- /dev/null +++ b/MCP/go/tools/files_remote/files_remote_list.go @@ -0,0 +1,106 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Files_remote_listHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["channel"]; ok { + queryParams = append(queryParams, fmt.Sprintf("channel=%v", val)) + } + if val, ok := args["ts_from"]; ok { + queryParams = append(queryParams, fmt.Sprintf("ts_from=%v", val)) + } + if val, ok := args["ts_to"]; ok { + queryParams = append(queryParams, fmt.Sprintf("ts_to=%v", val)) + } + if val, ok := args["limit"]; ok { + queryParams = append(queryParams, fmt.Sprintf("limit=%v", val)) + } + if val, ok := args["cursor"]; ok { + queryParams = append(queryParams, fmt.Sprintf("cursor=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/files.remote.list%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateFiles_remote_listTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_files_remote_list", + mcp.WithDescription("Retrieve information about a remote file added to Slack"), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `remote_files:read`")), + mcp.WithString("channel", mcp.Description("Filter files appearing in a specific channel, indicated by its ID.")), + mcp.WithString("ts_from", mcp.Description("Filter files created after this timestamp (inclusive).")), + mcp.WithString("ts_to", mcp.Description("Filter files created before this timestamp (inclusive).")), + mcp.WithNumber("limit", mcp.Description("The maximum number of items to return.")), + mcp.WithString("cursor", mcp.Description("Paginate through collections of data by setting the `cursor` parameter to a `next_cursor` attribute returned by a previous request's `response_metadata`. Default value fetches the first \"page\" of the collection. See [pagination](/docs/pagination) for more detail.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Files_remote_listHandler(cfg), + } +} diff --git a/MCP/go/tools/files_remote/files_remote_share.go b/MCP/go/tools/files_remote/files_remote_share.go new file mode 100644 index 0000000..eaeace8 --- /dev/null +++ b/MCP/go/tools/files_remote/files_remote_share.go @@ -0,0 +1,98 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Files_remote_shareHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["file"]; ok { + queryParams = append(queryParams, fmt.Sprintf("file=%v", val)) + } + if val, ok := args["external_id"]; ok { + queryParams = append(queryParams, fmt.Sprintf("external_id=%v", val)) + } + if val, ok := args["channels"]; ok { + queryParams = append(queryParams, fmt.Sprintf("channels=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/files.remote.share%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateFiles_remote_shareTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_files_remote_share", + mcp.WithDescription("Share a remote file into a channel."), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `remote_files:share`")), + mcp.WithString("file", mcp.Description("Specify a file registered with Slack by providing its ID. Either this field or `external_id` or both are required.")), + mcp.WithString("external_id", mcp.Description("The globally unique identifier (GUID) for the file, as set by the app registering the file with Slack. Either this field or `file` or both are required.")), + mcp.WithString("channels", mcp.Description("Comma-separated list of channel IDs where the file will be shared.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Files_remote_shareHandler(cfg), + } +} diff --git a/MCP/go/tools/migration/migration_exchange.go b/MCP/go/tools/migration/migration_exchange.go new file mode 100644 index 0000000..1b64c9b --- /dev/null +++ b/MCP/go/tools/migration/migration_exchange.go @@ -0,0 +1,98 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Migration_exchangeHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["users"]; ok { + queryParams = append(queryParams, fmt.Sprintf("users=%v", val)) + } + if val, ok := args["team_id"]; ok { + queryParams = append(queryParams, fmt.Sprintf("team_id=%v", val)) + } + if val, ok := args["to_old"]; ok { + queryParams = append(queryParams, fmt.Sprintf("to_old=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/migration.exchange%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateMigration_exchangeTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_migration_exchange", + mcp.WithDescription("For Enterprise Grid workspaces, map local user IDs to global user IDs"), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `tokens.basic`")), + mcp.WithString("users", mcp.Required(), mcp.Description("A comma-separated list of user ids, up to 400 per request")), + mcp.WithString("team_id", mcp.Description("Specify team_id starts with `T` in case of Org Token")), + mcp.WithBoolean("to_old", mcp.Description("Specify `true` to convert `W` global user IDs to workspace-specific `U` IDs. Defaults to `false`.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Migration_exchangeHandler(cfg), + } +} diff --git a/MCP/go/tools/oauth/oauth_access.go b/MCP/go/tools/oauth/oauth_access.go new file mode 100644 index 0000000..c393114 --- /dev/null +++ b/MCP/go/tools/oauth/oauth_access.go @@ -0,0 +1,102 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Oauth_accessHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["client_id"]; ok { + queryParams = append(queryParams, fmt.Sprintf("client_id=%v", val)) + } + if val, ok := args["client_secret"]; ok { + queryParams = append(queryParams, fmt.Sprintf("client_secret=%v", val)) + } + if val, ok := args["code"]; ok { + queryParams = append(queryParams, fmt.Sprintf("code=%v", val)) + } + if val, ok := args["redirect_uri"]; ok { + queryParams = append(queryParams, fmt.Sprintf("redirect_uri=%v", val)) + } + if val, ok := args["single_channel"]; ok { + queryParams = append(queryParams, fmt.Sprintf("single_channel=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/oauth.access%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateOauth_accessTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_oauth_access", + mcp.WithDescription("Exchanges a temporary OAuth verifier code for an access token."), + mcp.WithString("client_id", mcp.Description("Issued when you created your application.")), + mcp.WithString("client_secret", mcp.Description("Issued when you created your application.")), + mcp.WithString("code", mcp.Description("The `code` param returned via the OAuth callback.")), + mcp.WithString("redirect_uri", mcp.Description("This must match the originally submitted URI (if one was sent).")), + mcp.WithBoolean("single_channel", mcp.Description("Request the user to add your app only to a single channel. Only valid with a [legacy workspace app](https://api.slack.com/legacy-workspace-apps).")), + ) + + return models.Tool{ + Definition: tool, + Handler: Oauth_accessHandler(cfg), + } +} diff --git a/MCP/go/tools/oauth/oauth_token.go b/MCP/go/tools/oauth/oauth_token.go new file mode 100644 index 0000000..4ffc827 --- /dev/null +++ b/MCP/go/tools/oauth/oauth_token.go @@ -0,0 +1,102 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Oauth_tokenHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["client_id"]; ok { + queryParams = append(queryParams, fmt.Sprintf("client_id=%v", val)) + } + if val, ok := args["client_secret"]; ok { + queryParams = append(queryParams, fmt.Sprintf("client_secret=%v", val)) + } + if val, ok := args["code"]; ok { + queryParams = append(queryParams, fmt.Sprintf("code=%v", val)) + } + if val, ok := args["redirect_uri"]; ok { + queryParams = append(queryParams, fmt.Sprintf("redirect_uri=%v", val)) + } + if val, ok := args["single_channel"]; ok { + queryParams = append(queryParams, fmt.Sprintf("single_channel=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/oauth.token%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateOauth_tokenTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_oauth_token", + mcp.WithDescription("Exchanges a temporary OAuth verifier code for a workspace token."), + mcp.WithString("client_id", mcp.Description("Issued when you created your application.")), + mcp.WithString("client_secret", mcp.Description("Issued when you created your application.")), + mcp.WithString("code", mcp.Description("The `code` param returned via the OAuth callback.")), + mcp.WithString("redirect_uri", mcp.Description("This must match the originally submitted URI (if one was sent).")), + mcp.WithBoolean("single_channel", mcp.Description("Request the user to add your app only to a single channel.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Oauth_tokenHandler(cfg), + } +} diff --git a/MCP/go/tools/oauth_v2/oauth_v2_access.go b/MCP/go/tools/oauth_v2/oauth_v2_access.go new file mode 100644 index 0000000..cb9da51 --- /dev/null +++ b/MCP/go/tools/oauth_v2/oauth_v2_access.go @@ -0,0 +1,98 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Oauth_v2_accessHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["client_id"]; ok { + queryParams = append(queryParams, fmt.Sprintf("client_id=%v", val)) + } + if val, ok := args["client_secret"]; ok { + queryParams = append(queryParams, fmt.Sprintf("client_secret=%v", val)) + } + if val, ok := args["code"]; ok { + queryParams = append(queryParams, fmt.Sprintf("code=%v", val)) + } + if val, ok := args["redirect_uri"]; ok { + queryParams = append(queryParams, fmt.Sprintf("redirect_uri=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/oauth.v2.access%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateOauth_v2_accessTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_oauth_v2_access", + mcp.WithDescription("Exchanges a temporary OAuth verifier code for an access token."), + mcp.WithString("client_id", mcp.Description("Issued when you created your application.")), + mcp.WithString("client_secret", mcp.Description("Issued when you created your application.")), + mcp.WithString("code", mcp.Required(), mcp.Description("The `code` param returned via the OAuth callback.")), + mcp.WithString("redirect_uri", mcp.Description("This must match the originally submitted URI (if one was sent).")), + ) + + return models.Tool{ + Definition: tool, + Handler: Oauth_v2_accessHandler(cfg), + } +} diff --git a/MCP/go/tools/pins/pins_add.go b/MCP/go/tools/pins/pins_add.go new file mode 100644 index 0000000..c58fdf8 --- /dev/null +++ b/MCP/go/tools/pins/pins_add.go @@ -0,0 +1,100 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Pins_addHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/pins.add", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreatePins_addTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_pins_add", + mcp.WithDescription("Pins an item to a channel."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `pins:write`")), + mcp.WithString("channel", mcp.Required(), mcp.Description("Input parameter: Channel to pin the item in.")), + mcp.WithString("timestamp", mcp.Description("Input parameter: Timestamp of the message to pin.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Pins_addHandler(cfg), + } +} diff --git a/MCP/go/tools/pins/pins_list.go b/MCP/go/tools/pins/pins_list.go new file mode 100644 index 0000000..bf16666 --- /dev/null +++ b/MCP/go/tools/pins/pins_list.go @@ -0,0 +1,90 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Pins_listHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["channel"]; ok { + queryParams = append(queryParams, fmt.Sprintf("channel=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/pins.list%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreatePins_listTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_pins_list", + mcp.WithDescription("Lists items pinned to a channel."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `pins:read`")), + mcp.WithString("channel", mcp.Required(), mcp.Description("Channel to get pinned items for.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Pins_listHandler(cfg), + } +} diff --git a/MCP/go/tools/pins/pins_remove.go b/MCP/go/tools/pins/pins_remove.go new file mode 100644 index 0000000..682b49a --- /dev/null +++ b/MCP/go/tools/pins/pins_remove.go @@ -0,0 +1,100 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Pins_removeHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/pins.remove", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreatePins_removeTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_pins_remove", + mcp.WithDescription("Un-pins an item from a channel."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `pins:write`")), + mcp.WithString("channel", mcp.Required(), mcp.Description("Input parameter: Channel where the item is pinned to.")), + mcp.WithString("timestamp", mcp.Description("Input parameter: Timestamp of the message to un-pin.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Pins_removeHandler(cfg), + } +} diff --git a/MCP/go/tools/reactions/reactions_add.go b/MCP/go/tools/reactions/reactions_add.go new file mode 100644 index 0000000..f48cad7 --- /dev/null +++ b/MCP/go/tools/reactions/reactions_add.go @@ -0,0 +1,101 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Reactions_addHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/reactions.add", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateReactions_addTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_reactions_add", + mcp.WithDescription("Adds a reaction to an item."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `reactions:write`")), + mcp.WithString("name", mcp.Required(), mcp.Description("Input parameter: Reaction (emoji) name.")), + mcp.WithString("timestamp", mcp.Required(), mcp.Description("Input parameter: Timestamp of the message to add reaction to.")), + mcp.WithString("channel", mcp.Required(), mcp.Description("Input parameter: Channel where the message to add reaction to was posted.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Reactions_addHandler(cfg), + } +} diff --git a/MCP/go/tools/reactions/reactions_get.go b/MCP/go/tools/reactions/reactions_get.go new file mode 100644 index 0000000..34a8660 --- /dev/null +++ b/MCP/go/tools/reactions/reactions_get.go @@ -0,0 +1,106 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Reactions_getHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["channel"]; ok { + queryParams = append(queryParams, fmt.Sprintf("channel=%v", val)) + } + if val, ok := args["file"]; ok { + queryParams = append(queryParams, fmt.Sprintf("file=%v", val)) + } + if val, ok := args["file_comment"]; ok { + queryParams = append(queryParams, fmt.Sprintf("file_comment=%v", val)) + } + if val, ok := args["full"]; ok { + queryParams = append(queryParams, fmt.Sprintf("full=%v", val)) + } + if val, ok := args["timestamp"]; ok { + queryParams = append(queryParams, fmt.Sprintf("timestamp=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/reactions.get%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateReactions_getTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_reactions", + mcp.WithDescription("Gets reactions for an item."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `reactions:read`")), + mcp.WithString("channel", mcp.Description("Channel where the message to get reactions for was posted.")), + mcp.WithString("file", mcp.Description("File to get reactions for.")), + mcp.WithString("file_comment", mcp.Description("File comment to get reactions for.")), + mcp.WithBoolean("full", mcp.Description("If true always return the complete reaction list.")), + mcp.WithString("timestamp", mcp.Description("Timestamp of the message to get reactions for.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Reactions_getHandler(cfg), + } +} diff --git a/MCP/go/tools/reactions/reactions_list.go b/MCP/go/tools/reactions/reactions_list.go new file mode 100644 index 0000000..5acd4e9 --- /dev/null +++ b/MCP/go/tools/reactions/reactions_list.go @@ -0,0 +1,110 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Reactions_listHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["user"]; ok { + queryParams = append(queryParams, fmt.Sprintf("user=%v", val)) + } + if val, ok := args["full"]; ok { + queryParams = append(queryParams, fmt.Sprintf("full=%v", val)) + } + if val, ok := args["count"]; ok { + queryParams = append(queryParams, fmt.Sprintf("count=%v", val)) + } + if val, ok := args["page"]; ok { + queryParams = append(queryParams, fmt.Sprintf("page=%v", val)) + } + if val, ok := args["cursor"]; ok { + queryParams = append(queryParams, fmt.Sprintf("cursor=%v", val)) + } + if val, ok := args["limit"]; ok { + queryParams = append(queryParams, fmt.Sprintf("limit=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/reactions.list%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateReactions_listTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_reactions_list", + mcp.WithDescription("Lists reactions made by a user."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `reactions:read`")), + mcp.WithString("user", mcp.Description("Show reactions made by this user. Defaults to the authed user.")), + mcp.WithBoolean("full", mcp.Description("If true always return the complete reaction list.")), + mcp.WithNumber("count", mcp.Description("")), + mcp.WithNumber("page", mcp.Description("")), + mcp.WithString("cursor", mcp.Description("Parameter for pagination. Set `cursor` equal to the `next_cursor` attribute returned by the previous request's `response_metadata`. This parameter is optional, but pagination is mandatory: the default value simply fetches the first \"page\" of the collection. See [pagination](/docs/pagination) for more details.")), + mcp.WithNumber("limit", mcp.Description("The maximum number of items to return. Fewer than the requested number of items may be returned, even if the end of the list hasn't been reached.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Reactions_listHandler(cfg), + } +} diff --git a/MCP/go/tools/reactions/reactions_remove.go b/MCP/go/tools/reactions/reactions_remove.go new file mode 100644 index 0000000..7b468ab --- /dev/null +++ b/MCP/go/tools/reactions/reactions_remove.go @@ -0,0 +1,103 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Reactions_removeHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/reactions.remove", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateReactions_removeTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_reactions_remove", + mcp.WithDescription("Removes a reaction from an item."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `reactions:write`")), + mcp.WithString("channel", mcp.Description("Input parameter: Channel where the message to remove reaction from was posted.")), + mcp.WithString("file", mcp.Description("Input parameter: File to remove reaction from.")), + mcp.WithString("file_comment", mcp.Description("Input parameter: File comment to remove reaction from.")), + mcp.WithString("name", mcp.Required(), mcp.Description("Input parameter: Reaction (emoji) name.")), + mcp.WithString("timestamp", mcp.Description("Input parameter: Timestamp of the message to remove reaction from.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Reactions_removeHandler(cfg), + } +} diff --git a/MCP/go/tools/reminders/reminders_add.go b/MCP/go/tools/reminders/reminders_add.go new file mode 100644 index 0000000..1c5066e --- /dev/null +++ b/MCP/go/tools/reminders/reminders_add.go @@ -0,0 +1,101 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Reminders_addHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/reminders.add", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateReminders_addTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_reminders_add", + mcp.WithDescription("Creates a reminder."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `reminders:write`")), + mcp.WithString("user", mcp.Description("Input parameter: The user who will receive the reminder. If no user is specified, the reminder will go to user who created it.")), + mcp.WithString("text", mcp.Required(), mcp.Description("Input parameter: The content of the reminder")), + mcp.WithString("time", mcp.Required(), mcp.Description("Input parameter: When this reminder should happen: the Unix timestamp (up to five years from now), the number of seconds until the reminder (if within 24 hours), or a natural language description (Ex. \"in 15 minutes,\" or \"every Thursday\")")), + ) + + return models.Tool{ + Definition: tool, + Handler: Reminders_addHandler(cfg), + } +} diff --git a/MCP/go/tools/reminders/reminders_complete.go b/MCP/go/tools/reminders/reminders_complete.go new file mode 100644 index 0000000..1d8c151 --- /dev/null +++ b/MCP/go/tools/reminders/reminders_complete.go @@ -0,0 +1,99 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Reminders_completeHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/reminders.complete", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateReminders_completeTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_reminders_complete", + mcp.WithDescription("Marks a reminder as complete."), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `reminders:write`")), + mcp.WithString("reminder", mcp.Description("Input parameter: The ID of the reminder to be marked as complete")), + ) + + return models.Tool{ + Definition: tool, + Handler: Reminders_completeHandler(cfg), + } +} diff --git a/MCP/go/tools/reminders/reminders_delete.go b/MCP/go/tools/reminders/reminders_delete.go new file mode 100644 index 0000000..954eb43 --- /dev/null +++ b/MCP/go/tools/reminders/reminders_delete.go @@ -0,0 +1,99 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Reminders_deleteHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/reminders.delete", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateReminders_deleteTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_reminders_delete", + mcp.WithDescription("Deletes a reminder."), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `reminders:write`")), + mcp.WithString("reminder", mcp.Description("Input parameter: The ID of the reminder")), + ) + + return models.Tool{ + Definition: tool, + Handler: Reminders_deleteHandler(cfg), + } +} diff --git a/MCP/go/tools/reminders/reminders_info.go b/MCP/go/tools/reminders/reminders_info.go new file mode 100644 index 0000000..423a483 --- /dev/null +++ b/MCP/go/tools/reminders/reminders_info.go @@ -0,0 +1,90 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Reminders_infoHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["reminder"]; ok { + queryParams = append(queryParams, fmt.Sprintf("reminder=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/reminders.info%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateReminders_infoTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_reminders_info", + mcp.WithDescription("Gets information about a reminder."), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `reminders:read`")), + mcp.WithString("reminder", mcp.Description("The ID of the reminder")), + ) + + return models.Tool{ + Definition: tool, + Handler: Reminders_infoHandler(cfg), + } +} diff --git a/MCP/go/tools/reminders/reminders_list.go b/MCP/go/tools/reminders/reminders_list.go new file mode 100644 index 0000000..b17f9f2 --- /dev/null +++ b/MCP/go/tools/reminders/reminders_list.go @@ -0,0 +1,86 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Reminders_listHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/reminders.list%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateReminders_listTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_reminders_list", + mcp.WithDescription("Lists all reminders created by or for a given user."), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `reminders:read`")), + ) + + return models.Tool{ + Definition: tool, + Handler: Reminders_listHandler(cfg), + } +} diff --git a/MCP/go/tools/rtm/rtm_connect.go b/MCP/go/tools/rtm/rtm_connect.go new file mode 100644 index 0000000..0dbb6eb --- /dev/null +++ b/MCP/go/tools/rtm/rtm_connect.go @@ -0,0 +1,94 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Rtm_connectHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["batch_presence_aware"]; ok { + queryParams = append(queryParams, fmt.Sprintf("batch_presence_aware=%v", val)) + } + if val, ok := args["presence_sub"]; ok { + queryParams = append(queryParams, fmt.Sprintf("presence_sub=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/rtm.connect%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateRtm_connectTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_rtm_connect", + mcp.WithDescription("Starts a Real Time Messaging session."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `rtm:stream`")), + mcp.WithBoolean("batch_presence_aware", mcp.Description("Batch presence deliveries via subscription. Enabling changes the shape of `presence_change` events. See [batch presence](/docs/presence-and-status#batching).")), + mcp.WithBoolean("presence_sub", mcp.Description("Only deliver presence events when requested by subscription. See [presence subscriptions](/docs/presence-and-status#subscriptions).")), + ) + + return models.Tool{ + Definition: tool, + Handler: Rtm_connectHandler(cfg), + } +} diff --git a/MCP/go/tools/search/search_messages.go b/MCP/go/tools/search/search_messages.go new file mode 100644 index 0000000..32444f5 --- /dev/null +++ b/MCP/go/tools/search/search_messages.go @@ -0,0 +1,110 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Search_messagesHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["count"]; ok { + queryParams = append(queryParams, fmt.Sprintf("count=%v", val)) + } + if val, ok := args["highlight"]; ok { + queryParams = append(queryParams, fmt.Sprintf("highlight=%v", val)) + } + if val, ok := args["page"]; ok { + queryParams = append(queryParams, fmt.Sprintf("page=%v", val)) + } + if val, ok := args["query"]; ok { + queryParams = append(queryParams, fmt.Sprintf("query=%v", val)) + } + if val, ok := args["sort"]; ok { + queryParams = append(queryParams, fmt.Sprintf("sort=%v", val)) + } + if val, ok := args["sort_dir"]; ok { + queryParams = append(queryParams, fmt.Sprintf("sort_dir=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/search.messages%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateSearch_messagesTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_search_messages", + mcp.WithDescription("Searches for messages matching a query."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `search:read`")), + mcp.WithNumber("count", mcp.Description("Pass the number of results you want per \"page\". Maximum of `100`.")), + mcp.WithBoolean("highlight", mcp.Description("Pass a value of `true` to enable query highlight markers (see below).")), + mcp.WithNumber("page", mcp.Description("")), + mcp.WithString("query", mcp.Required(), mcp.Description("Search query.")), + mcp.WithString("sort", mcp.Description("Return matches sorted by either `score` or `timestamp`.")), + mcp.WithString("sort_dir", mcp.Description("Change sort direction to ascending (`asc`) or descending (`desc`).")), + ) + + return models.Tool{ + Definition: tool, + Handler: Search_messagesHandler(cfg), + } +} diff --git a/MCP/go/tools/stars/stars_add.go b/MCP/go/tools/stars/stars_add.go new file mode 100644 index 0000000..cf682e7 --- /dev/null +++ b/MCP/go/tools/stars/stars_add.go @@ -0,0 +1,102 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Stars_addHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/stars.add", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateStars_addTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_stars_add", + mcp.WithDescription("Adds a star to an item."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `stars:write`")), + mcp.WithString("file", mcp.Description("Input parameter: File to add star to.")), + mcp.WithString("file_comment", mcp.Description("Input parameter: File comment to add star to.")), + mcp.WithString("timestamp", mcp.Description("Input parameter: Timestamp of the message to add star to.")), + mcp.WithString("channel", mcp.Description("Input parameter: Channel to add star to, or channel where the message to add star to was posted (used with `timestamp`).")), + ) + + return models.Tool{ + Definition: tool, + Handler: Stars_addHandler(cfg), + } +} diff --git a/MCP/go/tools/stars/stars_list.go b/MCP/go/tools/stars/stars_list.go new file mode 100644 index 0000000..48b886e --- /dev/null +++ b/MCP/go/tools/stars/stars_list.go @@ -0,0 +1,102 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Stars_listHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["count"]; ok { + queryParams = append(queryParams, fmt.Sprintf("count=%v", val)) + } + if val, ok := args["page"]; ok { + queryParams = append(queryParams, fmt.Sprintf("page=%v", val)) + } + if val, ok := args["cursor"]; ok { + queryParams = append(queryParams, fmt.Sprintf("cursor=%v", val)) + } + if val, ok := args["limit"]; ok { + queryParams = append(queryParams, fmt.Sprintf("limit=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/stars.list%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateStars_listTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_stars_list", + mcp.WithDescription("Lists stars for a user."), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `stars:read`")), + mcp.WithString("count", mcp.Description("")), + mcp.WithString("page", mcp.Description("")), + mcp.WithString("cursor", mcp.Description("Parameter for pagination. Set `cursor` equal to the `next_cursor` attribute returned by the previous request's `response_metadata`. This parameter is optional, but pagination is mandatory: the default value simply fetches the first \"page\" of the collection. See [pagination](/docs/pagination) for more details.")), + mcp.WithNumber("limit", mcp.Description("The maximum number of items to return. Fewer than the requested number of items may be returned, even if the end of the list hasn't been reached.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Stars_listHandler(cfg), + } +} diff --git a/MCP/go/tools/stars/stars_remove.go b/MCP/go/tools/stars/stars_remove.go new file mode 100644 index 0000000..cb4dad3 --- /dev/null +++ b/MCP/go/tools/stars/stars_remove.go @@ -0,0 +1,102 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Stars_removeHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/stars.remove", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateStars_removeTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_stars_remove", + mcp.WithDescription("Removes a star from an item."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `stars:write`")), + mcp.WithString("channel", mcp.Description("Input parameter: Channel to remove star from, or channel where the message to remove star from was posted (used with `timestamp`).")), + mcp.WithString("file", mcp.Description("Input parameter: File to remove star from.")), + mcp.WithString("file_comment", mcp.Description("Input parameter: File comment to remove star from.")), + mcp.WithString("timestamp", mcp.Description("Input parameter: Timestamp of the message to remove star from.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Stars_removeHandler(cfg), + } +} diff --git a/MCP/go/tools/team/team_accesslogs.go b/MCP/go/tools/team/team_accesslogs.go new file mode 100644 index 0000000..b8736fa --- /dev/null +++ b/MCP/go/tools/team/team_accesslogs.go @@ -0,0 +1,98 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Team_accesslogsHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["before"]; ok { + queryParams = append(queryParams, fmt.Sprintf("before=%v", val)) + } + if val, ok := args["count"]; ok { + queryParams = append(queryParams, fmt.Sprintf("count=%v", val)) + } + if val, ok := args["page"]; ok { + queryParams = append(queryParams, fmt.Sprintf("page=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/team.accessLogs%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateTeam_accesslogsTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_team_accessLogs", + mcp.WithDescription("Gets the access logs for the current team."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin`")), + mcp.WithString("before", mcp.Description("End of time range of logs to include in results (inclusive).")), + mcp.WithString("count", mcp.Description("")), + mcp.WithString("page", mcp.Description("")), + ) + + return models.Tool{ + Definition: tool, + Handler: Team_accesslogsHandler(cfg), + } +} diff --git a/MCP/go/tools/team/team_billableinfo.go b/MCP/go/tools/team/team_billableinfo.go new file mode 100644 index 0000000..39bfe32 --- /dev/null +++ b/MCP/go/tools/team/team_billableinfo.go @@ -0,0 +1,90 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Team_billableinfoHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["user"]; ok { + queryParams = append(queryParams, fmt.Sprintf("user=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/team.billableInfo%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateTeam_billableinfoTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_team_billableInfo", + mcp.WithDescription("Gets billable users information for the current team."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin`")), + mcp.WithString("user", mcp.Description("A user to retrieve the billable information for. Defaults to all users.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Team_billableinfoHandler(cfg), + } +} diff --git a/MCP/go/tools/team/team_info.go b/MCP/go/tools/team/team_info.go new file mode 100644 index 0000000..6dfa3c8 --- /dev/null +++ b/MCP/go/tools/team/team_info.go @@ -0,0 +1,90 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Team_infoHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["team"]; ok { + queryParams = append(queryParams, fmt.Sprintf("team=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/team.info%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateTeam_infoTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_team_info", + mcp.WithDescription("Gets information about the current team."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `team:read`")), + mcp.WithString("team", mcp.Description("Team to get info on, if omitted, will return information about the current team. Will only return team that the authenticated token is allowed to see through external shared channels")), + ) + + return models.Tool{ + Definition: tool, + Handler: Team_infoHandler(cfg), + } +} diff --git a/MCP/go/tools/team/team_integrationlogs.go b/MCP/go/tools/team/team_integrationlogs.go new file mode 100644 index 0000000..556e683 --- /dev/null +++ b/MCP/go/tools/team/team_integrationlogs.go @@ -0,0 +1,110 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Team_integrationlogsHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["app_id"]; ok { + queryParams = append(queryParams, fmt.Sprintf("app_id=%v", val)) + } + if val, ok := args["change_type"]; ok { + queryParams = append(queryParams, fmt.Sprintf("change_type=%v", val)) + } + if val, ok := args["count"]; ok { + queryParams = append(queryParams, fmt.Sprintf("count=%v", val)) + } + if val, ok := args["page"]; ok { + queryParams = append(queryParams, fmt.Sprintf("page=%v", val)) + } + if val, ok := args["service_id"]; ok { + queryParams = append(queryParams, fmt.Sprintf("service_id=%v", val)) + } + if val, ok := args["user"]; ok { + queryParams = append(queryParams, fmt.Sprintf("user=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/team.integrationLogs%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateTeam_integrationlogsTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_team_integrationLogs", + mcp.WithDescription("Gets the integration logs for the current team."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `admin`")), + mcp.WithString("app_id", mcp.Description("Filter logs to this Slack app. Defaults to all logs.")), + mcp.WithString("change_type", mcp.Description("Filter logs with this change type. Defaults to all logs.")), + mcp.WithString("count", mcp.Description("")), + mcp.WithString("page", mcp.Description("")), + mcp.WithString("service_id", mcp.Description("Filter logs to this service. Defaults to all logs.")), + mcp.WithString("user", mcp.Description("Filter logs generated by this user’s actions. Defaults to all logs.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Team_integrationlogsHandler(cfg), + } +} diff --git a/MCP/go/tools/team_profile/team_profile_get.go b/MCP/go/tools/team_profile/team_profile_get.go new file mode 100644 index 0000000..3e2a127 --- /dev/null +++ b/MCP/go/tools/team_profile/team_profile_get.go @@ -0,0 +1,90 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Team_profile_getHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["visibility"]; ok { + queryParams = append(queryParams, fmt.Sprintf("visibility=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/team.profile.get%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateTeam_profile_getTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_team_profile", + mcp.WithDescription("Retrieve a team's profile."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `users.profile:read`")), + mcp.WithString("visibility", mcp.Description("Filter by visibility.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Team_profile_getHandler(cfg), + } +} diff --git a/MCP/go/tools/usergroups/usergroups_create.go b/MCP/go/tools/usergroups/usergroups_create.go new file mode 100644 index 0000000..78e4a4b --- /dev/null +++ b/MCP/go/tools/usergroups/usergroups_create.go @@ -0,0 +1,103 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Usergroups_createHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/usergroups.create", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateUsergroups_createTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_usergroups_create", + mcp.WithDescription("Create a User Group"), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `usergroups:write`")), + mcp.WithString("channels", mcp.Description("Input parameter: A comma separated string of encoded channel IDs for which the User Group uses as a default.")), + mcp.WithString("description", mcp.Description("Input parameter: A short description of the User Group.")), + mcp.WithString("handle", mcp.Description("Input parameter: A mention handle. Must be unique among channels, users and User Groups.")), + mcp.WithBoolean("include_count", mcp.Description("Input parameter: Include the number of users in each User Group.")), + mcp.WithString("name", mcp.Required(), mcp.Description("Input parameter: A name for the User Group. Must be unique among User Groups.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Usergroups_createHandler(cfg), + } +} diff --git a/MCP/go/tools/usergroups/usergroups_disable.go b/MCP/go/tools/usergroups/usergroups_disable.go new file mode 100644 index 0000000..5ee6923 --- /dev/null +++ b/MCP/go/tools/usergroups/usergroups_disable.go @@ -0,0 +1,100 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Usergroups_disableHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/usergroups.disable", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateUsergroups_disableTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_usergroups_disable", + mcp.WithDescription("Disable an existing User Group"), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `usergroups:write`")), + mcp.WithBoolean("include_count", mcp.Description("Input parameter: Include the number of users in the User Group.")), + mcp.WithString("usergroup", mcp.Required(), mcp.Description("Input parameter: The encoded ID of the User Group to disable.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Usergroups_disableHandler(cfg), + } +} diff --git a/MCP/go/tools/usergroups/usergroups_enable.go b/MCP/go/tools/usergroups/usergroups_enable.go new file mode 100644 index 0000000..81b3c81 --- /dev/null +++ b/MCP/go/tools/usergroups/usergroups_enable.go @@ -0,0 +1,100 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Usergroups_enableHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/usergroups.enable", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateUsergroups_enableTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_usergroups_enable", + mcp.WithDescription("Enable a User Group"), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `usergroups:write`")), + mcp.WithString("usergroup", mcp.Required(), mcp.Description("Input parameter: The encoded ID of the User Group to enable.")), + mcp.WithBoolean("include_count", mcp.Description("Input parameter: Include the number of users in the User Group.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Usergroups_enableHandler(cfg), + } +} diff --git a/MCP/go/tools/usergroups/usergroups_list.go b/MCP/go/tools/usergroups/usergroups_list.go new file mode 100644 index 0000000..3624c31 --- /dev/null +++ b/MCP/go/tools/usergroups/usergroups_list.go @@ -0,0 +1,98 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Usergroups_listHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["include_users"]; ok { + queryParams = append(queryParams, fmt.Sprintf("include_users=%v", val)) + } + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["include_count"]; ok { + queryParams = append(queryParams, fmt.Sprintf("include_count=%v", val)) + } + if val, ok := args["include_disabled"]; ok { + queryParams = append(queryParams, fmt.Sprintf("include_disabled=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/usergroups.list%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateUsergroups_listTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_usergroups_list", + mcp.WithDescription("List all User Groups for a team"), + mcp.WithBoolean("include_users", mcp.Description("Include the list of users for each User Group.")), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `usergroups:read`")), + mcp.WithBoolean("include_count", mcp.Description("Include the number of users in each User Group.")), + mcp.WithBoolean("include_disabled", mcp.Description("Include disabled User Groups.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Usergroups_listHandler(cfg), + } +} diff --git a/MCP/go/tools/usergroups/usergroups_update.go b/MCP/go/tools/usergroups/usergroups_update.go new file mode 100644 index 0000000..7310fa2 --- /dev/null +++ b/MCP/go/tools/usergroups/usergroups_update.go @@ -0,0 +1,104 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Usergroups_updateHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/usergroups.update", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateUsergroups_updateTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_usergroups_update", + mcp.WithDescription("Update an existing User Group"), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `usergroups:write`")), + mcp.WithString("usergroup", mcp.Required(), mcp.Description("Input parameter: The encoded ID of the User Group to update.")), + mcp.WithString("channels", mcp.Description("Input parameter: A comma separated string of encoded channel IDs for which the User Group uses as a default.")), + mcp.WithString("description", mcp.Description("Input parameter: A short description of the User Group.")), + mcp.WithString("handle", mcp.Description("Input parameter: A mention handle. Must be unique among channels, users and User Groups.")), + mcp.WithBoolean("include_count", mcp.Description("Input parameter: Include the number of users in the User Group.")), + mcp.WithString("name", mcp.Description("Input parameter: A name for the User Group. Must be unique among User Groups.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Usergroups_updateHandler(cfg), + } +} diff --git a/MCP/go/tools/usergroups_users/usergroups_users_list.go b/MCP/go/tools/usergroups_users/usergroups_users_list.go new file mode 100644 index 0000000..cd8b42d --- /dev/null +++ b/MCP/go/tools/usergroups_users/usergroups_users_list.go @@ -0,0 +1,94 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Usergroups_users_listHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["include_disabled"]; ok { + queryParams = append(queryParams, fmt.Sprintf("include_disabled=%v", val)) + } + if val, ok := args["usergroup"]; ok { + queryParams = append(queryParams, fmt.Sprintf("usergroup=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/usergroups.users.list%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateUsergroups_users_listTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_usergroups_users_list", + mcp.WithDescription("List all users in a User Group"), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `usergroups:read`")), + mcp.WithBoolean("include_disabled", mcp.Description("Allow results that involve disabled User Groups.")), + mcp.WithString("usergroup", mcp.Required(), mcp.Description("The encoded ID of the User Group to update.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Usergroups_users_listHandler(cfg), + } +} diff --git a/MCP/go/tools/usergroups_users/usergroups_users_update.go b/MCP/go/tools/usergroups_users/usergroups_users_update.go new file mode 100644 index 0000000..ff3e1cb --- /dev/null +++ b/MCP/go/tools/usergroups_users/usergroups_users_update.go @@ -0,0 +1,101 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Usergroups_users_updateHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/usergroups.users.update", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateUsergroups_users_updateTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_usergroups_users_update", + mcp.WithDescription("Update the list of users for a User Group"), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `usergroups:write`")), + mcp.WithBoolean("include_count", mcp.Description("Input parameter: Include the number of users in the User Group.")), + mcp.WithString("usergroup", mcp.Required(), mcp.Description("Input parameter: The encoded ID of the User Group to update.")), + mcp.WithString("users", mcp.Required(), mcp.Description("Input parameter: A comma separated string of encoded user IDs that represent the entire list of users for the User Group.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Usergroups_users_updateHandler(cfg), + } +} diff --git a/MCP/go/tools/users/users_conversations.go b/MCP/go/tools/users/users_conversations.go new file mode 100644 index 0000000..ae4992b --- /dev/null +++ b/MCP/go/tools/users/users_conversations.go @@ -0,0 +1,106 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Users_conversationsHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["user"]; ok { + queryParams = append(queryParams, fmt.Sprintf("user=%v", val)) + } + if val, ok := args["types"]; ok { + queryParams = append(queryParams, fmt.Sprintf("types=%v", val)) + } + if val, ok := args["exclude_archived"]; ok { + queryParams = append(queryParams, fmt.Sprintf("exclude_archived=%v", val)) + } + if val, ok := args["limit"]; ok { + queryParams = append(queryParams, fmt.Sprintf("limit=%v", val)) + } + if val, ok := args["cursor"]; ok { + queryParams = append(queryParams, fmt.Sprintf("cursor=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/users.conversations%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateUsers_conversationsTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_users_conversations", + mcp.WithDescription("List conversations the calling user may access."), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `conversations:read`")), + mcp.WithString("user", mcp.Description("Browse conversations by a specific user ID's membership. Non-public channels are restricted to those where the calling user shares membership.")), + mcp.WithString("types", mcp.Description("Mix and match channel types by providing a comma-separated list of any combination of `public_channel`, `private_channel`, `mpim`, `im`")), + mcp.WithBoolean("exclude_archived", mcp.Description("Set to `true` to exclude archived channels from the list")), + mcp.WithNumber("limit", mcp.Description("The maximum number of items to return. Fewer than the requested number of items may be returned, even if the end of the list hasn't been reached. Must be an integer no larger than 1000.")), + mcp.WithString("cursor", mcp.Description("Paginate through collections of data by setting the `cursor` parameter to a `next_cursor` attribute returned by a previous request's `response_metadata`. Default value fetches the first \"page\" of the collection. See [pagination](/docs/pagination) for more detail.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Users_conversationsHandler(cfg), + } +} diff --git a/MCP/go/tools/users/users_getpresence.go b/MCP/go/tools/users/users_getpresence.go new file mode 100644 index 0000000..774bde4 --- /dev/null +++ b/MCP/go/tools/users/users_getpresence.go @@ -0,0 +1,90 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Users_getpresenceHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["user"]; ok { + queryParams = append(queryParams, fmt.Sprintf("user=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/users.getPresence%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateUsers_getpresenceTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_users_getPresence", + mcp.WithDescription("Gets user presence information."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `users:read`")), + mcp.WithString("user", mcp.Description("User to get presence info on. Defaults to the authed user.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Users_getpresenceHandler(cfg), + } +} diff --git a/MCP/go/tools/users/users_identity.go b/MCP/go/tools/users/users_identity.go new file mode 100644 index 0000000..e19ec3a --- /dev/null +++ b/MCP/go/tools/users/users_identity.go @@ -0,0 +1,86 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Users_identityHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/users.identity%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateUsers_identityTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_users_identity", + mcp.WithDescription("Get a user's identity."), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `identity.basic`")), + ) + + return models.Tool{ + Definition: tool, + Handler: Users_identityHandler(cfg), + } +} diff --git a/MCP/go/tools/users/users_info.go b/MCP/go/tools/users/users_info.go new file mode 100644 index 0000000..3187368 --- /dev/null +++ b/MCP/go/tools/users/users_info.go @@ -0,0 +1,94 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Users_infoHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["include_locale"]; ok { + queryParams = append(queryParams, fmt.Sprintf("include_locale=%v", val)) + } + if val, ok := args["user"]; ok { + queryParams = append(queryParams, fmt.Sprintf("user=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/users.info%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateUsers_infoTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_users_info", + mcp.WithDescription("Gets information about a user."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `users:read`")), + mcp.WithBoolean("include_locale", mcp.Description("Set this to `true` to receive the locale for this user. Defaults to `false`")), + mcp.WithString("user", mcp.Description("User to get info on")), + ) + + return models.Tool{ + Definition: tool, + Handler: Users_infoHandler(cfg), + } +} diff --git a/MCP/go/tools/users/users_list.go b/MCP/go/tools/users/users_list.go new file mode 100644 index 0000000..21178d9 --- /dev/null +++ b/MCP/go/tools/users/users_list.go @@ -0,0 +1,98 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Users_listHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["limit"]; ok { + queryParams = append(queryParams, fmt.Sprintf("limit=%v", val)) + } + if val, ok := args["cursor"]; ok { + queryParams = append(queryParams, fmt.Sprintf("cursor=%v", val)) + } + if val, ok := args["include_locale"]; ok { + queryParams = append(queryParams, fmt.Sprintf("include_locale=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/users.list%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateUsers_listTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_users_list", + mcp.WithDescription("Lists all users in a Slack team."), + mcp.WithString("token", mcp.Description("Authentication token. Requires scope: `users:read`")), + mcp.WithNumber("limit", mcp.Description("The maximum number of items to return. Fewer than the requested number of items may be returned, even if the end of the users list hasn't been reached. Providing no `limit` value will result in Slack attempting to deliver you the entire result set. If the collection is too large you may experience `limit_required` or HTTP 500 errors.")), + mcp.WithString("cursor", mcp.Description("Paginate through collections of data by setting the `cursor` parameter to a `next_cursor` attribute returned by a previous request's `response_metadata`. Default value fetches the first \"page\" of the collection. See [pagination](/docs/pagination) for more detail.")), + mcp.WithBoolean("include_locale", mcp.Description("Set this to `true` to receive the locale for users. Defaults to `false`")), + ) + + return models.Tool{ + Definition: tool, + Handler: Users_listHandler(cfg), + } +} diff --git a/MCP/go/tools/users/users_lookupbyemail.go b/MCP/go/tools/users/users_lookupbyemail.go new file mode 100644 index 0000000..d2da97f --- /dev/null +++ b/MCP/go/tools/users/users_lookupbyemail.go @@ -0,0 +1,90 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Users_lookupbyemailHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["email"]; ok { + queryParams = append(queryParams, fmt.Sprintf("email=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/users.lookupByEmail%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateUsers_lookupbyemailTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_users_lookupByEmail", + mcp.WithDescription("Find a user with an email address."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `users:read.email`")), + mcp.WithString("email", mcp.Required(), mcp.Description("An email address belonging to a user in the workspace")), + ) + + return models.Tool{ + Definition: tool, + Handler: Users_lookupbyemailHandler(cfg), + } +} diff --git a/MCP/go/tools/users/users_setactive.go b/MCP/go/tools/users/users_setactive.go new file mode 100644 index 0000000..6834505 --- /dev/null +++ b/MCP/go/tools/users/users_setactive.go @@ -0,0 +1,80 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Users_setactiveHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + url := fmt.Sprintf("%s/users.setActive", cfg.BaseURL) + req, err := http.NewRequest("POST", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateUsers_setactiveTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_users_setActive", + mcp.WithDescription("Marked a user as active. Deprecated and non-functional."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `users:write`")), + ) + + return models.Tool{ + Definition: tool, + Handler: Users_setactiveHandler(cfg), + } +} diff --git a/MCP/go/tools/users/users_setpresence.go b/MCP/go/tools/users/users_setpresence.go new file mode 100644 index 0000000..c280bc2 --- /dev/null +++ b/MCP/go/tools/users/users_setpresence.go @@ -0,0 +1,99 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Users_setpresenceHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/users.setPresence", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateUsers_setpresenceTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_users_setPresence", + mcp.WithDescription("Manually sets user presence."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `users:write`")), + mcp.WithString("presence", mcp.Required(), mcp.Description("Input parameter: Either `auto` or `away`")), + ) + + return models.Tool{ + Definition: tool, + Handler: Users_setpresenceHandler(cfg), + } +} diff --git a/MCP/go/tools/users_profile/users_profile_get.go b/MCP/go/tools/users_profile/users_profile_get.go new file mode 100644 index 0000000..954a643 --- /dev/null +++ b/MCP/go/tools/users_profile/users_profile_get.go @@ -0,0 +1,94 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Users_profile_getHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["token"]; ok { + queryParams = append(queryParams, fmt.Sprintf("token=%v", val)) + } + if val, ok := args["include_labels"]; ok { + queryParams = append(queryParams, fmt.Sprintf("include_labels=%v", val)) + } + if val, ok := args["user"]; ok { + queryParams = append(queryParams, fmt.Sprintf("user=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/users.profile.get%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateUsers_profile_getTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_users_profile", + mcp.WithDescription("Retrieves a user's profile information."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `users.profile:read`")), + mcp.WithBoolean("include_labels", mcp.Description("Include labels for each ID in custom profile fields")), + mcp.WithString("user", mcp.Description("User to retrieve profile info for")), + ) + + return models.Tool{ + Definition: tool, + Handler: Users_profile_getHandler(cfg), + } +} diff --git a/MCP/go/tools/users_profile/users_profile_set.go b/MCP/go/tools/users_profile/users_profile_set.go new file mode 100644 index 0000000..3b7f831 --- /dev/null +++ b/MCP/go/tools/users_profile/users_profile_set.go @@ -0,0 +1,102 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "bytes" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Users_profile_setHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + // Create properly typed request body using the generated schema + var requestBody interface{} + + // Optimized: Single marshal/unmarshal with JSON tags handling field mapping + if argsJSON, err := json.Marshal(args); err == nil { + if err := json.Unmarshal(argsJSON, &requestBody); err != nil { + return mcp.NewToolResultError(fmt.Sprintf("Failed to convert arguments to request type: %v", err)), nil + } + } else { + return mcp.NewToolResultError(fmt.Sprintf("Failed to marshal arguments: %v", err)), nil + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to encode request body", err), nil + } + url := fmt.Sprintf("%s/users.profile.set", cfg.BaseURL) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) + req.Header.Set("Content-Type", "application/json") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateUsers_profile_setTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("post_users_profile_set", + mcp.WithDescription("Set the profile information for a user."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `users.profile:write`")), + mcp.WithString("value", mcp.Description("Input parameter: Value to set a single key to. Usable only if `profile` is not passed.")), + mcp.WithString("name", mcp.Description("Input parameter: Name of a single key to set. Usable only if `profile` is not passed.")), + mcp.WithString("profile", mcp.Description("Input parameter: Collection of key:value pairs presented as a URL-encoded JSON hash. At most 50 fields may be set. Each field name is limited to 255 characters.")), + mcp.WithString("user", mcp.Description("Input parameter: ID of user to change. This argument may only be specified by team admins on paid teams.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Users_profile_setHandler(cfg), + } +} diff --git a/MCP/go/tools/views/views_open.go b/MCP/go/tools/views/views_open.go new file mode 100644 index 0000000..bb59994 --- /dev/null +++ b/MCP/go/tools/views/views_open.go @@ -0,0 +1,94 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Views_openHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["trigger_id"]; ok { + queryParams = append(queryParams, fmt.Sprintf("trigger_id=%v", val)) + } + if val, ok := args["view"]; ok { + queryParams = append(queryParams, fmt.Sprintf("view=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/views.open%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateViews_openTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_views_open", + mcp.WithDescription("Open a view for a user."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `none`")), + mcp.WithString("trigger_id", mcp.Required(), mcp.Description("Exchange a trigger to post to the user.")), + mcp.WithString("view", mcp.Required(), mcp.Description("A [view payload](/reference/surfaces/views). This must be a JSON-encoded string.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Views_openHandler(cfg), + } +} diff --git a/MCP/go/tools/views/views_publish.go b/MCP/go/tools/views/views_publish.go new file mode 100644 index 0000000..b6ebc53 --- /dev/null +++ b/MCP/go/tools/views/views_publish.go @@ -0,0 +1,98 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Views_publishHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["user_id"]; ok { + queryParams = append(queryParams, fmt.Sprintf("user_id=%v", val)) + } + if val, ok := args["view"]; ok { + queryParams = append(queryParams, fmt.Sprintf("view=%v", val)) + } + if val, ok := args["hash"]; ok { + queryParams = append(queryParams, fmt.Sprintf("hash=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/views.publish%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateViews_publishTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_views_publish", + mcp.WithDescription("Publish a static view for a User."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `none`")), + mcp.WithString("user_id", mcp.Required(), mcp.Description("`id` of the user you want publish a view to.")), + mcp.WithString("view", mcp.Required(), mcp.Description("A [view payload](/reference/surfaces/views). This must be a JSON-encoded string.")), + mcp.WithString("hash", mcp.Description("A string that represents view state to protect against possible race conditions.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Views_publishHandler(cfg), + } +} diff --git a/MCP/go/tools/views/views_push.go b/MCP/go/tools/views/views_push.go new file mode 100644 index 0000000..2dc1324 --- /dev/null +++ b/MCP/go/tools/views/views_push.go @@ -0,0 +1,94 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Views_pushHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["trigger_id"]; ok { + queryParams = append(queryParams, fmt.Sprintf("trigger_id=%v", val)) + } + if val, ok := args["view"]; ok { + queryParams = append(queryParams, fmt.Sprintf("view=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/views.push%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateViews_pushTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_views_push", + mcp.WithDescription("Push a view onto the stack of a root view."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `none`")), + mcp.WithString("trigger_id", mcp.Required(), mcp.Description("Exchange a trigger to post to the user.")), + mcp.WithString("view", mcp.Required(), mcp.Description("A [view payload](/reference/surfaces/views). This must be a JSON-encoded string.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Views_pushHandler(cfg), + } +} diff --git a/MCP/go/tools/views/views_update.go b/MCP/go/tools/views/views_update.go new file mode 100644 index 0000000..7fef9d5 --- /dev/null +++ b/MCP/go/tools/views/views_update.go @@ -0,0 +1,102 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Views_updateHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["view_id"]; ok { + queryParams = append(queryParams, fmt.Sprintf("view_id=%v", val)) + } + if val, ok := args["external_id"]; ok { + queryParams = append(queryParams, fmt.Sprintf("external_id=%v", val)) + } + if val, ok := args["view"]; ok { + queryParams = append(queryParams, fmt.Sprintf("view=%v", val)) + } + if val, ok := args["hash"]; ok { + queryParams = append(queryParams, fmt.Sprintf("hash=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/views.update%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateViews_updateTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_views_update", + mcp.WithDescription("Update an existing view."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `none`")), + mcp.WithString("view_id", mcp.Description("A unique identifier of the view to be updated. Either `view_id` or `external_id` is required.")), + mcp.WithString("external_id", mcp.Description("A unique identifier of the view set by the developer. Must be unique for all views on a team. Max length of 255 characters. Either `view_id` or `external_id` is required.")), + mcp.WithString("view", mcp.Description("A [view object](/reference/surfaces/views). This must be a JSON-encoded string.")), + mcp.WithString("hash", mcp.Description("A string that represents view state to protect against possible race conditions.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Views_updateHandler(cfg), + } +} diff --git a/MCP/go/tools/workflows/workflows_stepcompleted.go b/MCP/go/tools/workflows/workflows_stepcompleted.go new file mode 100644 index 0000000..ce18010 --- /dev/null +++ b/MCP/go/tools/workflows/workflows_stepcompleted.go @@ -0,0 +1,94 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Workflows_stepcompletedHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["workflow_step_execute_id"]; ok { + queryParams = append(queryParams, fmt.Sprintf("workflow_step_execute_id=%v", val)) + } + if val, ok := args["outputs"]; ok { + queryParams = append(queryParams, fmt.Sprintf("outputs=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/workflows.stepCompleted%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateWorkflows_stepcompletedTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_workflows_stepCompleted", + mcp.WithDescription("Indicate that an app's step in a workflow completed execution."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `workflow.steps:execute`")), + mcp.WithString("workflow_step_execute_id", mcp.Required(), mcp.Description("Context identifier that maps to the correct workflow step execution.")), + mcp.WithString("outputs", mcp.Description("Key-value object of outputs from your step. Keys of this object reflect the configured `key` properties of your [`outputs`](/reference/workflows/workflow_step#output) array from your `workflow_step` object.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Workflows_stepcompletedHandler(cfg), + } +} diff --git a/MCP/go/tools/workflows/workflows_stepfailed.go b/MCP/go/tools/workflows/workflows_stepfailed.go new file mode 100644 index 0000000..80cffcc --- /dev/null +++ b/MCP/go/tools/workflows/workflows_stepfailed.go @@ -0,0 +1,94 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Workflows_stepfailedHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["workflow_step_execute_id"]; ok { + queryParams = append(queryParams, fmt.Sprintf("workflow_step_execute_id=%v", val)) + } + if val, ok := args["error"]; ok { + queryParams = append(queryParams, fmt.Sprintf("error=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/workflows.stepFailed%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateWorkflows_stepfailedTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_workflows_stepFailed", + mcp.WithDescription("Indicate that an app's step in a workflow failed to execute."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `workflow.steps:execute`")), + mcp.WithString("workflow_step_execute_id", mcp.Required(), mcp.Description("Context identifier that maps to the correct workflow step execution.")), + mcp.WithString("error", mcp.Required(), mcp.Description("A JSON-based object with a `message` property that should contain a human readable error message.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Workflows_stepfailedHandler(cfg), + } +} diff --git a/MCP/go/tools/workflows/workflows_updatestep.go b/MCP/go/tools/workflows/workflows_updatestep.go new file mode 100644 index 0000000..3f59763 --- /dev/null +++ b/MCP/go/tools/workflows/workflows_updatestep.go @@ -0,0 +1,106 @@ +package tools + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/slack-web-api/mcp-server/config" + "github.com/slack-web-api/mcp-server/models" + "github.com/mark3labs/mcp-go/mcp" +) + +func Workflows_updatestepHandler(cfg *config.APIConfig) func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + args, ok := request.Params.Arguments.(map[string]any) + if !ok { + return mcp.NewToolResultError("Invalid arguments object"), nil + } + queryParams := make([]string, 0) + if val, ok := args["workflow_step_edit_id"]; ok { + queryParams = append(queryParams, fmt.Sprintf("workflow_step_edit_id=%v", val)) + } + if val, ok := args["inputs"]; ok { + queryParams = append(queryParams, fmt.Sprintf("inputs=%v", val)) + } + if val, ok := args["outputs"]; ok { + queryParams = append(queryParams, fmt.Sprintf("outputs=%v", val)) + } + if val, ok := args["step_name"]; ok { + queryParams = append(queryParams, fmt.Sprintf("step_name=%v", val)) + } + if val, ok := args["step_image_url"]; ok { + queryParams = append(queryParams, fmt.Sprintf("step_image_url=%v", val)) + } + queryString := "" + if len(queryParams) > 0 { + queryString = "?" + strings.Join(queryParams, "&") + } + url := fmt.Sprintf("%s/workflows.updateStep%s", cfg.BaseURL, queryString) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to create request", err), nil + } + // Set authentication based on auth type + if cfg.BearerToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", cfg.BearerToken)) + } + + // Add custom headers if provided + + // Set client identification headers + req.Header.Set("X-Request-Source", "Codeglide-MCP-generator") + req.Header.Set("Accept", "application/json") + if val, ok := args["token"]; ok { + req.Header.Set("token", fmt.Sprintf("%v", val)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return mcp.NewToolResultErrorFromErr("Request failed", err), nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to read response body", err), nil + } + + if resp.StatusCode >= 400 { + return mcp.NewToolResultError(fmt.Sprintf("API error: %s", body)), nil + } + // Use properly typed response + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + // Fallback to raw text if unmarshaling fails + return mcp.NewToolResultText(string(body)), nil + } + + prettyJSON, err := json.MarshalIndent(result, "", " ") + if err != nil { + return mcp.NewToolResultErrorFromErr("Failed to format JSON", err), nil + } + + return mcp.NewToolResultText(string(prettyJSON)), nil + } +} + +func CreateWorkflows_updatestepTool(cfg *config.APIConfig) models.Tool { + tool := mcp.NewTool("get_workflows_updateStep", + mcp.WithDescription("Update the configuration for a workflow extension step."), + mcp.WithString("token", mcp.Required(), mcp.Description("Authentication token. Requires scope: `workflow.steps:execute`")), + mcp.WithString("workflow_step_edit_id", mcp.Required(), mcp.Description("A context identifier provided with `view_submission` payloads used to call back to `workflows.updateStep`.")), + mcp.WithString("inputs", mcp.Description("A JSON key-value map of inputs required from a user during configuration. This is the data your app expects to receive when the workflow step starts. **Please note**: the embedded variable format is set and replaced by the workflow system. You cannot create custom variables that will be replaced at runtime. [Read more about variables in workflow steps here](/workflows/steps#variables).")), + mcp.WithString("outputs", mcp.Description("An JSON array of output objects used during step execution. This is the data your app agrees to provide when your workflow step was executed.")), + mcp.WithString("step_name", mcp.Description("An optional field that can be used to override the step name that is shown in the Workflow Builder.")), + mcp.WithString("step_image_url", mcp.Description("An optional field that can be used to override app image that is shown in the Workflow Builder.")), + ) + + return models.Tool{ + Definition: tool, + Handler: Workflows_updatestepHandler(cfg), + } +}