(singleTenant bool)
| 270 | } |
| 271 | |
| 272 | func createEnvironmentCreateTool(singleTenant bool) *Tool { |
| 273 | // Build arguments dynamically based on single-tenant mode |
| 274 | args := []mcp.ToolOption{ |
| 275 | mcp.WithString("title", |
| 276 | mcp.Description("Short description of the work that is happening in this environment."), |
| 277 | mcp.Required(), |
| 278 | ), |
| 279 | mcp.WithString("from_git_ref", |
| 280 | mcp.Description("Git reference to create the environment from (e.g., HEAD, main, feature-branch, SHA). Defaults to HEAD if not specified."), |
| 281 | ), |
| 282 | } |
| 283 | |
| 284 | // Add allow_replace parameter only in single-tenant mode |
| 285 | if singleTenant { |
| 286 | args = append(args, mcp.WithBoolean("allow_replace", |
| 287 | mcp.Description("If true and an environment already exists for this session, destructively replace it with a new one."), |
| 288 | )) |
| 289 | } |
| 290 | |
| 291 | return &Tool{ |
| 292 | Definition: newRepositoryTool( |
| 293 | "environment_create", |
| 294 | `Creates a new development environment. |
| 295 | The environment is the result of a the setups commands on top of the base image. |
| 296 | Environment configuration is managed by the user via cu config commands.`, |
| 297 | args..., |
| 298 | ), |
| 299 | Handler: func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { |
| 300 | repo, err := openRepository(ctx, request) |
| 301 | if err != nil { |
| 302 | return nil, err |
| 303 | } |
| 304 | title, err := request.RequireString("title") |
| 305 | if err != nil { |
| 306 | return nil, err |
| 307 | } |
| 308 | |
| 309 | // In single-tenant mode, check allow_replace before creating environment |
| 310 | if singleTenantMode, _ := ctx.Value(singleTenantKey{}).(bool); singleTenantMode { |
| 311 | allowReplace := request.GetBool("allow_replace", false) // Default false to prevent accidental environment replacement |
| 312 | |
| 313 | if !allowReplace { |
| 314 | // Check if environment already exists |
| 315 | if currentEnvID, err := getCurrentEnvironmentID(); err == nil { |
| 316 | // Environment exists, return error with info about existing env |
| 317 | return nil, fmt.Errorf("environment_id %s already exists for this session. Tools can be used directly. You can environment_open %s for more information, or set allow_replace=true to destructively replace it", currentEnvID, currentEnvID) |
| 318 | } |
| 319 | } |
| 320 | } |
| 321 | |
| 322 | dag, ok := ctx.Value(daggerClientKey{}).(*dagger.Client) |
| 323 | if !ok { |
| 324 | return nil, fmt.Errorf("dagger client not found in context") |
| 325 | } |
| 326 | |
| 327 | gitRef := request.GetString("from_git_ref", "HEAD") |
| 328 | env, err := repo.Create(ctx, dag, title, request.GetString("explanation", ""), gitRef) |
| 329 | if err != nil { |
no test coverage detected