Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions pkg/mcp/instructions_warning.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,20 @@
The Functions MCP server is currently running in **read-only mode**.

**Available operations:**
- Create Functions
- Build Functions
- Configure Functions (envs, labels, volumes)
- Inspect Functions

**Disabled operations:**
- Create Functions
- Build Function images
- Deploy to cluster
- Delete from cluster

These write operations are disabled to prevent unintended cluster modifications.
These write operations are disabled to prevent unintended local or cluster modifications.

## Enabling Write Mode

If the user needs to deploy or delete Functions, you MUST inform them to enable write mode:
If the user needs to create, build, deploy, or delete Functions, you MUST inform them to enable write mode:

1. Close/exit this application completely
2. Set the environment variable: `FUNC_ENABLE_MCP_WRITE=true`
Expand Down
4 changes: 4 additions & 0 deletions pkg/mcp/tools_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ var createTool = &mcp.Tool{
}

func (s *Server) createHandler(ctx context.Context, r *mcp.CallToolRequest, input CreateInput) (result *mcp.CallToolResult, output CreateOutput, err error) {
if s.readonly.Load() {
err = fmt.Errorf("the server is currently in read-only mode; to enable write operations, set FUNC_ENABLE_MCP_WRITE in the server environment and restart the server")
return
}
out, err := s.executor.Execute(ctx, "create", input.Args()...)
if err != nil {
err = fmt.Errorf("%w\n%s", err, string(out))
Expand Down
22 changes: 22 additions & 0 deletions pkg/mcp/tools_create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,25 @@ func TestTool_Create_BinaryFailure(t *testing.T) {
t.Errorf("expected error to include binary output, got: %s", resultToString(result))
}
}

// TestTool_Create_Readonly ensures the create tool rejects requests in readonly mode.
func TestTool_Create_Readonly(t *testing.T) {
client, _, err := newTestPairWithReadonly(t, true) // readonly = true
if err != nil {
t.Fatal(err)
}

result, err := client.CallTool(t.Context(), &mcp.CallToolParams{
Name: "create",
Arguments: map[string]any{"language": "go", "path": "."},
})
if err != nil {
t.Fatal(err)
}
if !result.IsError {
t.Fatal("expected create to be rejected in readonly mode")
}
if !strings.Contains(resultToString(result), "read-only mode") {
t.Errorf("expected readonly error message, got: %s", resultToString(result))
}
}
Loading