-
Notifications
You must be signed in to change notification settings - Fork 956
feat: add MCP tools for ChatGPT #19102
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
a61194d
a48445e
50bae9d
ec57659
f86a119
2faad08
4afd149
9f938b9
e50627d
9fef13e
5efa6d9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
package coderd | ||
|
||
import ( | ||
"fmt" | ||
"net/http" | ||
|
||
"cdr.dev/slog" | ||
|
@@ -11,7 +12,15 @@ import ( | |
"github.com/coder/coder/v2/codersdk" | ||
) | ||
|
||
type MCPToolset string | ||
|
||
const ( | ||
MCPToolsetStandard MCPToolset = "standard" | ||
MCPToolsetChatGPT MCPToolset = "chatgpt" | ||
) | ||
|
||
// mcpHTTPHandler creates the MCP HTTP transport handler | ||
// It supports a "toolset" query parameter to select the set of tools to register. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we want to expose toolsets specifically, or do we want to add a simple There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I conceptually prefer toolsets over sources. It feels more appropriate for the client to choose which tools it wants to access, rather than having the server adapt to the client. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Makes sense. Would it be possible to specify multiple toolsets then? Say we split the param on There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That could definitely be a later-stage extension. |
||
func (api *API) mcpHTTPHandler() http.Handler { | ||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||
// Create MCP server instance for each request | ||
|
@@ -23,14 +32,30 @@ func (api *API) mcpHTTPHandler() http.Handler { | |
}) | ||
return | ||
} | ||
|
||
authenticatedClient := codersdk.New(api.AccessURL) | ||
// Extract the original session token from the request | ||
authenticatedClient.SetSessionToken(httpmw.APITokenFromRequest(r)) | ||
|
||
// Register tools with authenticated client | ||
if err := mcpServer.RegisterTools(authenticatedClient); err != nil { | ||
api.Logger.Warn(r.Context(), "failed to register MCP tools", slog.Error(err)) | ||
toolset := MCPToolset(r.URL.Query().Get("toolset")) | ||
// Default to standard toolset if no toolset is specified. | ||
if toolset == "" { | ||
toolset = MCPToolsetStandard | ||
} | ||
|
||
switch toolset { | ||
case MCPToolsetStandard: | ||
if err := mcpServer.RegisterTools(authenticatedClient); err != nil { | ||
api.Logger.Warn(r.Context(), "failed to register MCP tools", slog.Error(err)) | ||
} | ||
case MCPToolsetChatGPT: | ||
if err := mcpServer.RegisterChatGPTTools(authenticatedClient); err != nil { | ||
api.Logger.Warn(r.Context(), "failed to register MCP tools", slog.Error(err)) | ||
} | ||
default: | ||
httpapi.Write(r.Context(), w, http.StatusBadRequest, codersdk.Response{ | ||
Message: fmt.Sprintf("Invalid toolset: %s", toolset), | ||
}) | ||
return | ||
} | ||
|
||
// Handle the MCP request | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might define
Standard
one to be the default empty value, then we don't need to do additional checks later on.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Neat trick, but it feels unintuitive - especially if we add debug logging with toolset names later. I'd be surprised to see this pattern as a reader.