|
1 | 1 | package cmd |
2 | 2 |
|
3 | 3 | import ( |
4 | | - "log" |
| 4 | + "fmt" |
| 5 | + "os" |
| 6 | + "strconv" |
5 | 7 |
|
6 | 8 | "github.com/spf13/cobra" |
7 | 9 | "knative.dev/func/pkg/mcp" |
| 10 | + |
| 11 | + fn "knative.dev/func/pkg/functions" |
8 | 12 | ) |
9 | 13 |
|
10 | | -func NewMCPServerCmd() *cobra.Command { |
| 14 | +func NewMCPCmd(newClient ClientFactory) *cobra.Command { |
11 | 15 | cmd := &cobra.Command{ |
12 | 16 | Use: "mcp", |
13 | | - Short: "Start MCP server", |
| 17 | + Short: "Model Context Protocol (MCP) server", |
14 | 18 | Long: ` |
15 | 19 | NAME |
16 | | - {{rootCmdUse}} mcp - start a Model Context Protocol (MCP) server |
| 20 | + {{rootCmdUse}} mcp - Model Context Protocol (MCP) server |
17 | 21 |
|
18 | 22 | SYNOPSIS |
19 | | - {{rootCmdUse}} mcp [flags] |
20 | | -
|
| 23 | + {{rootCmdUse}} mcp [command] [flags] |
21 | 24 | DESCRIPTION |
22 | | - Starts a Model Context Protocol (MCP) server over standard input/output (stdio) transport. |
23 | | - This implementation aims to support tools for deploying and creating serverless functions. |
24 | | - |
25 | | - Note: This command is still under development. |
| 25 | + The Functions Model Context Protocol (MCP) server can be used to give |
| 26 | + agents the power of Functions. |
| 27 | +
|
| 28 | + Configure your agentic client to use the MCP server with command |
| 29 | + "{{rootCmdUse}} mcp start". Then get the conversation started with |
| 30 | +
|
| 31 | + "Let's create a Function!". |
| 32 | +
|
| 33 | + By default the MCP server operates in read-only mode, allowing Function |
| 34 | + creation, building, and inspection, but preventing deployment and deletion. |
| 35 | + To enable full write access (deploy and delete operations), set the |
| 36 | + environment variable FUNC_ENABLE_MCP_WRITE=true. |
| 37 | +
|
| 38 | + This is an experimental feature, and using an LLM to create and deploy |
| 39 | + code running on your cluster requires careful supervision. Functions is |
| 40 | + an inherently "mutative" tool, so enabling write mode for your LLM is |
| 41 | + essentially giving (sometimes unpredictable) AI the ability to create, |
| 42 | + modify, deploy, and delete Function instances on your currently connected |
| 43 | + cluster. |
| 44 | +
|
| 45 | + The command "{{rootCmdUse}} mcp start" is meant to be invoked by your MCP |
| 46 | + client (such as Claude Code, Cursor, VS Code, Windsurf, etc.); not run |
| 47 | + directly. Configure your client of choice with a new MCP server which runs |
| 48 | + this command. For example, in Claude Code this can be accomplished with: |
| 49 | + claude mcp add func func mcp start |
| 50 | + Instructions for other clients can be found at: |
| 51 | + https://github.com/knative/func/blob/main/docs/mcp-integration/integration.md |
| 52 | +
|
| 53 | +AVAILABLE COMMANDS |
| 54 | + start Start the MCP server (for use by your agent) |
26 | 55 |
|
27 | 56 | EXAMPLES |
28 | 57 |
|
29 | | - o Run an MCP server: |
30 | | - {{rootCmdUse}} mcp |
| 58 | + o View this help: |
| 59 | + {{rootCmdUse}} mcp --help |
| 60 | +`, |
| 61 | + } |
| 62 | + |
| 63 | + cmd.AddCommand(NewMCPStartCmd(newClient)) |
| 64 | + |
| 65 | + return cmd |
| 66 | +} |
| 67 | + |
| 68 | +func NewMCPStartCmd(newClient ClientFactory) *cobra.Command { |
| 69 | + cmd := &cobra.Command{ |
| 70 | + Use: "start", |
| 71 | + Short: "Start the MCP server", |
| 72 | + Long: ` |
| 73 | +NAME |
| 74 | + {{rootCmdUse}} mcp start - start the Model Context Protocol (MCP) server |
| 75 | +
|
| 76 | +SYNOPSIS |
| 77 | + {{rootCmdUse}} mcp start [flags] |
| 78 | +
|
| 79 | +DESCRIPTION |
| 80 | + Starts the Model Context Protocol (MCP) server. |
| 81 | +
|
| 82 | + This command is designed to be invoked by MCP clients directly |
| 83 | + (such as Claude Code, Claude Desktop, Cursor, VS Code, Windsurf, etc.); |
| 84 | + not run directly. |
| 85 | +
|
| 86 | + Please see '{{rootCmdUse}} mcp --help' for more information. |
31 | 87 | `, |
32 | 88 | RunE: func(cmd *cobra.Command, args []string) error { |
33 | | - return runMCPServer(cmd, args) |
| 89 | + return runMCPStart(cmd, args, newClient) |
34 | 90 | }, |
35 | 91 | } |
| 92 | + // no flags at this time; future enhancements may be to allow configuring |
| 93 | + // HTTP Stream vs stdio, single vs multiuser modes, etc. For now |
| 94 | + // we just use a simple gathering of options in runMCPServer. |
36 | 95 | return cmd |
37 | 96 | } |
38 | 97 |
|
39 | | -func runMCPServer(cmd *cobra.Command, args []string) error { |
40 | | - s := mcp.NewServer() |
41 | | - if err := s.Start(); err != nil { |
42 | | - log.Fatalf("Server error: %v", err) |
43 | | - return err |
| 98 | +func runMCPStart(cmd *cobra.Command, args []string, newClient ClientFactory) error { |
| 99 | + // Configure write mode |
| 100 | + writeEnabled := false |
| 101 | + if val := os.Getenv("FUNC_ENABLE_MCP_WRITE"); val != "" { |
| 102 | + parsed, err := strconv.ParseBool(val) |
| 103 | + if err != nil { |
| 104 | + return fmt.Errorf("FUNC_ENABLE_MCP_WRITE shuold be a boolean (true/false, 1/0, etc). Received %q", val) |
| 105 | + } |
| 106 | + writeEnabled = parsed |
44 | 107 | } |
45 | | - return nil |
| 108 | + |
| 109 | + // Configure 'func' or 'kn func'? |
| 110 | + rootCmd := cmd.Root() |
| 111 | + cmdPrefix := rootCmd.Use |
| 112 | + |
| 113 | + // Instantiate |
| 114 | + client, done := newClient(ClientConfig{}, |
| 115 | + fn.WithMCPServer(mcp.New(mcp.WithPrefix(cmdPrefix)))) |
| 116 | + defer done() |
| 117 | + |
| 118 | + // Start |
| 119 | + return client.StartMCPServer(cmd.Context(), writeEnabled) |
| 120 | + |
46 | 121 | } |
0 commit comments