Content-Length: 389945 | pFad | http://github.com/coder/coder/pull/19102

7F feat: add MCP tools for ChatGPT by hugodutka · Pull Request #19102 · coder/coder · GitHub
Skip to content

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open

feat: add MCP tools for ChatGPT #19102

wants to merge 2 commits into from

Conversation

hugodutka
Copy link
Contributor

@hugodutka hugodutka commented Jul 30, 2025

Addresses coder/internal#772.

Adds a new /api/experimental/mcp/chatgpt endpoint which exposes new fetch and search tools compatible with ChatGPT, as described in the ChatGPT docs. These tools are exposed in isolation because in my usage I found that ChatGPT refuses to connect to Coder if it sees additional MCP tools.

Screenshot 2025-07-30 at 16 36 56

@hugodutka hugodutka force-pushed the hugodutka/chatgpt-mcp branch from ccc3a6a to 3e42d7a Compare July 30, 2025 14:51
@hugodutka hugodutka marked this pull request as ready for review July 30, 2025 15:03
@hugodutka hugodutka requested a review from ThomasK33 July 30, 2025 15:03
Copy link
Member

@ThomasK33 ThomasK33 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good, just a few small code organization tweaks.
I'd prefer to add a new Register function to the server struct so that we can handle this one edge case instead of refactoring the whole thing.

For anyone looking at this PR: ChatGPT connectors are 'questionable' (ask for my opinion in Slack 😉) and adding a dedicated endpoint makes sense for the sake of dogfood and sanity.

// RegisterTools registers all available MCP tools with the server
func (s *Server) RegisterTools(client *codersdk.Client) error {
// RegisterTools registers MCP tools with the server
func (s *Server) RegisterTools(client *codersdk.Client, tools []toolsdk.GenericTool) error {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we leave the function as it was and add a new function called RegisterChatGPTTools instead?

This would benefit us by allowing us to add exceptions for ChatGPT more easily on the server structure, and keeping the existing MCP endpoint and function calls as they are/will be.

(Also, we can then write a unit test and assert that a ChatGPT MCP server only has those two tools that we expect)

"Authorization": "Bearer " + coderClient.SessionToken(),
}))
require.NoError(t, err)
defer func() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: we should probably run this in a t.Cleanup?

}
}()

ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
ctx, cancel := context.WithTimeout(t.Context(), testutil.WaitLong)

)

// mcpHTTPHandler creates the MCP HTTP transport handler
func (api *API) mcpHTTPHandler() http.Handler {
func (api *API) mcpHTTPHandler(tools []toolsdk.GenericTool) http.Handler {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we could simplify this a bit by making it a boolean called isChatGPT bool, then calling the appropriate Register function (either .RegisterTools() or .RegisterChatGPTTools()).

This also makes the handler less complex.

Comment on lines +17 to +22
func getServerURL(deps Deps) string {
serverURLCopy := *deps.coderClient.URL
serverURLCopy.Path = ""
serverURLCopy.RawQuery = ""
return serverURLCopy.String()
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may want to add a new function to Deps.
Then we could just deps.ServerURL() to get it.


func searchTemplates(ctx context.Context, deps Deps) ([]SearchResultItem, error) {
serverURL := getServerURL(deps)
templates, err := deps.coderClient.Templates(ctx, codersdk.TemplateFilter{})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use the SearchQuery field to parameterize this?

if owner == "" {
owner = "me"
}
workspaces, err := deps.coderClient.Workspaces(ctx, codersdk.WorkspaceFilter{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, I'd just delegate the search query as is to the backend.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: http://github.com/coder/coder/pull/19102

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy