Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitaa33071

Browse files
committed
merge stop and start command into one
1 parenta3d8896 commitaa33071

File tree

3 files changed

+55
-107
lines changed

3 files changed

+55
-107
lines changed

‎mcp/tools/tools_coder.go

Lines changed: 14 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -273,8 +273,9 @@ func handleCoderListTemplates(deps ToolDeps) mcpserver.ToolHandlerFunc {
273273
}
274274

275275
// Example payload:
276-
// {"jsonrpc":"2.0","id":1,"method":"tools/call", "params": {"name": "coder_start_workspace", "arguments": {"workspace": "dev"}}}
277-
funchandleCoderStartWorkspace(depsToolDeps) mcpserver.ToolHandlerFunc {
276+
// {"jsonrpc":"2.0","id":1,"method":"tools/call", "params": {"name":
277+
// "coder_workspace_transition", "arguments": {"workspace": "dev", "transition": "stop"}}}
278+
funchandleCoderWorkspaceTransition(depsToolDeps) mcpserver.ToolHandlerFunc {
278279
returnfunc(ctx context.Context,request mcp.CallToolRequest) (*mcp.CallToolResult,error) {
279280
ifdeps.Client==nil {
280281
returnnil,xerrors.New("developer error: client is required")
@@ -292,59 +293,22 @@ func handleCoderStartWorkspace(deps ToolDeps) mcpserver.ToolHandlerFunc {
292293
returnnil,xerrors.Errorf("failed to fetch workspace: %w",err)
293294
}
294295

295-
switchworkspace.LatestBuild.Status {
296-
casecodersdk.WorkspaceStatusPending,codersdk.WorkspaceStatusStarting,codersdk.WorkspaceStatusRunning,codersdk.WorkspaceStatusCanceling:
297-
returnnil,xerrors.Errorf("workspace is %s",workspace.LatestBuild.Status)
298-
}
299-
300-
wb,err:=deps.Client.CreateWorkspaceBuild(ctx,workspace.ID, codersdk.CreateWorkspaceBuildRequest{
301-
Transition:codersdk.WorkspaceTransitionStart,
302-
})
303-
iferr!=nil {
304-
returnnil,xerrors.Errorf("failed to start workspace: %w",err)
305-
}
306-
307-
resp:=map[string]any{"status":wb.Status,"transition":wb.Transition}
308-
respJSON,err:=json.Marshal(resp)
309-
iferr!=nil {
310-
returnnil,xerrors.Errorf("failed to encode workspace build: %w",err)
311-
}
312-
313-
return&mcp.CallToolResult{
314-
Content: []mcp.Content{
315-
mcp.NewTextContent(string(respJSON)),
316-
},
317-
},nil
318-
}
319-
}
320-
321-
// Example payload:
322-
// {"jsonrpc":"2.0","id":1,"method":"tools/call", "params": {"name": "coder_stop_workspace", "arguments": {"workspace": "dev"}}}
323-
funchandleCoderStopWorkspace(depsToolDeps) mcpserver.ToolHandlerFunc {
324-
returnfunc(ctx context.Context,request mcp.CallToolRequest) (*mcp.CallToolResult,error) {
325-
ifdeps.Client==nil {
326-
returnnil,xerrors.New("developer error: client is required")
327-
}
328-
329-
args:=request.Params.Arguments
330-
331-
wsArg,ok:=args["workspace"].(string)
296+
transition,ok:=args["transition"].(string)
332297
if!ok {
333-
returnnil,xerrors.New("workspace is required")
298+
returnnil,xerrors.New("transition is required")
334299
}
335-
336-
workspace,err:=getWorkspaceByIDOrOwnerName(ctx,deps.Client,wsArg)
337-
iferr!=nil {
338-
returnnil,xerrors.Errorf("failed to fetch workspace: %w",err)
339-
}
340-
341-
switchworkspace.LatestBuild.Status {
342-
casecodersdk.WorkspaceStatusPending,codersdk.WorkspaceStatusStopping,codersdk.WorkspaceStatusStopped,codersdk.WorkspaceStatusCanceling:
343-
returnnil,xerrors.Errorf("workspace is %s",workspace.LatestBuild.Status)
300+
wsTransition:=codersdk.WorkspaceTransition(transition)
301+
switchwsTransition {
302+
casecodersdk.WorkspaceTransitionStart:
303+
casecodersdk.WorkspaceTransitionStop:
304+
default:
305+
returnnil,xerrors.New("invalid transition")
344306
}
345307

308+
// We're not going to check the workspace status here as it is checked on the
309+
// server side.
346310
wb,err:=deps.Client.CreateWorkspaceBuild(ctx,workspace.ID, codersdk.CreateWorkspaceBuildRequest{
347-
Transition:codersdk.WorkspaceTransitionStop,
311+
Transition:wsTransition,
348312
})
349313
iferr!=nil {
350314
returnnil,xerrors.Errorf("failed to stop workspace: %w",err)

‎mcp/tools/tools_coder_test.go

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -195,27 +195,6 @@ func TestCoderTools(t *testing.T) {
195195
testutil.RequireJSONEq(t,expected,actual)
196196
})
197197

198-
t.Run("coder_stop_workspace",func(t*testing.T) {
199-
// Given: a separate workspace in the running state
200-
stopWs:=dbfake.WorkspaceBuild(t,store, database.WorkspaceTable{
201-
OrganizationID:owner.OrganizationID,
202-
OwnerID:member.ID,
203-
}).WithAgent().Do()
204-
205-
// When: the coder_stop_workspace tool is called
206-
ctr:=makeJSONRPCRequest(t,"tools/call","coder_stop_workspace",map[string]any{
207-
"workspace":stopWs.Workspace.ID.String(),
208-
})
209-
210-
pty.WriteLine(ctr)
211-
_=pty.ReadLine(ctx)// skip the echo
212-
213-
// Then: the response is as expected.
214-
expected:=makeJSONRPCTextResponse(t,`{"status":"pending","transition":"stop"}`)// no provisionerd yet
215-
actual:=pty.ReadLine(ctx)
216-
testutil.RequireJSONEq(t,expected,actual)
217-
})
218-
219198
// NOTE: this test runs after the list_workspaces tool is called.
220199
t.Run("tool_restrictions",func(t*testing.T) {
221200
// Given: the workspace agent is connected
@@ -256,7 +235,29 @@ func TestCoderTools(t *testing.T) {
256235
require.Contains(t,disallowedToolResponse,"not found")
257236
})
258237

259-
t.Run("coder_start_workspace",func(t*testing.T) {
238+
t.Run("coder_workspace_transition_stop",func(t*testing.T) {
239+
// Given: a separate workspace in the running state
240+
stopWs:=dbfake.WorkspaceBuild(t,store, database.WorkspaceTable{
241+
OrganizationID:owner.OrganizationID,
242+
OwnerID:member.ID,
243+
}).WithAgent().Do()
244+
245+
// When: the coder_workspace_transition tool is called with a stop transition
246+
ctr:=makeJSONRPCRequest(t,"tools/call","coder_workspace_transition",map[string]any{
247+
"workspace":stopWs.Workspace.ID.String(),
248+
"transition":"stop",
249+
})
250+
251+
pty.WriteLine(ctr)
252+
_=pty.ReadLine(ctx)// skip the echo
253+
254+
// Then: the response is as expected.
255+
expected:=makeJSONRPCTextResponse(t,`{"status":"pending","transition":"stop"}`)// no provisionerd yet
256+
actual:=pty.ReadLine(ctx)
257+
testutil.RequireJSONEq(t,expected,actual)
258+
})
259+
260+
t.Run("coder_workspace_transition_start",func(t*testing.T) {
260261
// Given: a separate workspace in the stopped state
261262
stopWs:=dbfake.WorkspaceBuild(t,store, database.WorkspaceTable{
262263
OrganizationID:owner.OrganizationID,
@@ -265,9 +266,10 @@ func TestCoderTools(t *testing.T) {
265266
Transition:database.WorkspaceTransitionStop,
266267
}).Do()
267268

268-
// When: the coder_start_workspace tool is called
269-
ctr:=makeJSONRPCRequest(t,"tools/call","coder_start_workspace",map[string]any{
270-
"workspace":stopWs.Workspace.ID.String(),
269+
// When: the coder_workspace_transition tool is called with a start transition
270+
ctr:=makeJSONRPCRequest(t,"tools/call","coder_workspace_transition",map[string]any{
271+
"workspace":stopWs.Workspace.ID.String(),
272+
"transition":"start",
271273
})
272274

273275
pty.WriteLine(ctr)

‎mcp/tools/tools_registry.go

Lines changed: 14 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -155,52 +155,34 @@ Note: Very long-running commands may time out.`), mcp.Required()),
155155
MakeHandler:handleCoderWorkspaceExec,
156156
},
157157
{
158-
Tool:mcp.NewTool("coder_start_workspace",
159-
mcp.WithDescription(`Start a stopped Coder workspace.
160-
Initiates the workspace build process to provision and start all resources.
161-
Only works on workspaces that are currently stopped or failed.
162-
Starting a workspace is an asynchronous operation - it may take several minutes to complete.
158+
Tool:mcp.NewTool("coder_workspace_transition",
159+
mcp.WithDescription(`Start or stop a running Coder workspace.
160+
If stopping, initiates the workspace stop transition.
161+
Only works on workspaces that are currently running or failed.
163162
164-
After calling this tool:
165-
1. Use coder_report_task to inform the user that the workspace is starting
166-
2. Use coder_get_workspace periodically to check for completion
163+
If starting, initiates the workspace start transition.
164+
Only works on workspaces that are currently stopped or failed.
167165
168-
Common errors:
169-
- Workspace already running/starting: No action needed
170-
- Quota limits exceeded: User may have reached resource limits
171-
- Template error: The underlying template may have issues`),
172-
mcp.WithString("workspace",mcp.Description(`The workspace ID (UUID) or name to start.
173-
Can be specified as either:
174-
- Full UUID: e.g., "8a0b9c7d-1e2f-3a4b-5c6d-7e8f9a0b1c2d"
175-
- Workspace name: e.g., "dev", "python-project"
176-
The workspace must be in a stopped state to be started.
177-
Use coder_get_workspace first to check the current workspace status.`),mcp.Required()),
178-
),
179-
MakeHandler:handleCoderStartWorkspace,
180-
},
181-
{
182-
Tool:mcp.NewTool("coder_stop_workspace",
183-
mcp.WithDescription(`Stop a running Coder workspace.
184-
Initiates the workspace termination process to shut down all resources.
185-
Only works on workspaces that are currently running.
186-
Stopping a workspace is an asynchronous operation - it may take several minutes to complete.
166+
Stopping or starting a workspace is an asynchronous operation - it may take several minutes to complete.
187167
188168
After calling this tool:
189-
1. Use coder_report_task to inform the user that the workspace is stopping
169+
1. Use coder_report_task to inform the user that the workspace is stopping or starting
190170
2. Use coder_get_workspace periodically to check for completion
191171
192172
Common errors:
193-
- Workspace already stopped/stopping: No action needed
173+
- Workspace alreadystarted/starting/stopped/stopping: No action needed
194174
- Cancellation failed: There may be issues with the underlying infrastructure
195175
- User doesn't own workspace: Permission issues`),
196-
mcp.WithString("workspace",mcp.Description(`The workspace ID (UUID) or name to stop.
176+
mcp.WithString("workspace",mcp.Description(`The workspace ID (UUID) or name tostart orstop.
197177
Can be specified as either:
198178
- Full UUID: e.g., "8a0b9c7d-1e2f-3a4b-5c6d-7e8f9a0b1c2d"
199179
- Workspace name: e.g., "dev", "python-project"
200-
The workspace must be in a running state to be stopped.
180+
The workspace must be in a running state to be stopped, or in a stopped or failed state to be started.
201181
Use coder_get_workspace first to check the current workspace status.`),mcp.Required()),
182+
mcp.WithString("transition",mcp.Description(`The transition to apply to the workspace.
183+
Can be either "start" or "stop".`)),
202184
),
203-
MakeHandler:handleCoderStopWorkspace,
185+
MakeHandler:handleCoderWorkspaceTransition,
204186
},
205187
}
206188

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp