Skip to content

feat: func mcp#3155

Merged
knative-prow[bot] merged 1 commit intoknative:mainfrom
lkingland:push-krlrkrmlkzqt
Nov 6, 2025
Merged

feat: func mcp#3155
knative-prow[bot] merged 1 commit intoknative:mainfrom
lkingland:push-krlrkrmlkzqt

Conversation

@lkingland
Copy link
Copy Markdown
Member

@lkingland lkingland commented Oct 29, 2025

Updates the POC Functions MCP server to be a slightly more mature experimental MCP server.

Enable with FUNC_ENABLE_MCP and start (by configuring one's client LLM) via func mcp start.

@knative-prow knative-prow Bot requested review from dsimansk and nainaz October 29, 2025 07:29
@knative-prow knative-prow Bot added approved 🤖 PR has been approved by an approver from all required OWNERS files. size/XXL 🤖 PR changes 1000+ lines, ignoring generated files. labels Oct 29, 2025
@lkingland lkingland force-pushed the push-krlrkrmlkzqt branch 4 times, most recently from b75b584 to 59f42c0 Compare October 29, 2025 07:44
@codecov
Copy link
Copy Markdown

codecov Bot commented Oct 29, 2025

Codecov Report

❌ Patch coverage is 80.70175% with 77 lines in your changes missing coverage. Please review.
✅ Project coverage is 63.87%. Comparing base (3d1ee5e) to head (d77ff89).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
pkg/mcp/tools_delete.go 50.00% 7 Missing and 5 partials ⚠️
pkg/mcp/mcp.go 85.29% 9 Missing and 1 partial ⚠️
pkg/mcp/resources_help.go 47.05% 8 Missing and 1 partial ⚠️
pkg/mcp/mock/executor.go 0.00% 7 Missing ⚠️
pkg/mcp/tools_deploy.go 81.81% 4 Missing and 2 partials ⚠️
pkg/mock/mcp_server.go 0.00% 6 Missing ⚠️
pkg/mcp/resources_function.go 77.77% 2 Missing and 2 partials ⚠️
pkg/mcp/tools_build.go 85.00% 2 Missing and 1 partial ⚠️
pkg/mcp/tools_config_envs.go 82.35% 2 Missing and 1 partial ⚠️
pkg/mcp/tools_config_labels.go 82.35% 2 Missing and 1 partial ⚠️
... and 7 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3155      +/-   ##
==========================================
+ Coverage   59.35%   63.87%   +4.52%     
==========================================
  Files         134      150      +16     
  Lines       13519    13210     -309     
==========================================
+ Hits         8024     8438     +414     
+ Misses       4552     3783     -769     
- Partials      943      989      +46     
Flag Coverage Δ
e2e-tests 43.01% <13.47%> (+2.81%) ⬆️
integration-tests 58.28% <80.70%> (+5.27%) ⬆️
unit-tests 50.15% <80.70%> (+3.43%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@lkingland lkingland force-pushed the push-krlrkrmlkzqt branch 3 times, most recently from 7330b01 to be3efaf Compare October 29, 2025 11:11
Comment thread .gitignore
/pkg/functions/testdata/default_home/go
/pkg/functions/testdata/default_home/.cache
/pkg/functions/testdata/migrations/*/.gitignore
/pkg/creds/auth.json
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Comment thread Makefile
Comment thread cmd/mcp.go Outdated
Comment thread docs/reference/func_mcp.md Outdated
Comment thread docs/reference/func_mcp_start.md Outdated
@matzew
Copy link
Copy Markdown
Member

matzew commented Oct 30, 2025

I'd group prompts and tools into a package. and if needed, even sub-group the tools.

I'd than do something like https://github.com/containers/kubernetes-mcp-server/blob/main/pkg/toolsets/core/toolset.go#L23 for registering those.

Comment thread pkg/mcp/tools_build.go Outdated
@lkingland lkingland force-pushed the push-krlrkrmlkzqt branch 2 times, most recently from 961dccc to ea28447 Compare October 30, 2025 11:00
Copy link
Copy Markdown
Contributor

@twoGiants twoGiants left a comment

Choose a reason for hiding this comment

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

Hi @lkingland! Great job on the MCP integration 😸 👍

Most of my comments so far are cleanups, refactorings and a few typos. Some are opinions, so you decide if you want to go that route 😸 . Many can probably be done in a follow up.

I finished reviewing up to tools_build_test.go. Not much left. Will submit another after lunch.

Comment thread pkg/mcp/instructions.go Outdated
Comment thread pkg/mcp/instructions.go Outdated
Comment thread pkg/mcp/instructions.go Outdated
Comment thread pkg/mcp/instructions.go
Comment thread pkg/mcp/mcp.go Outdated
Comment thread pkg/mcp/resources.go Outdated
Comment thread pkg/mcp/resources.go Outdated
Comment thread pkg/mcp/resources.go Outdated
Comment thread pkg/mcp/tools.go Outdated
Comment thread pkg/mcp/tools_build.go Outdated
@lkingland
Copy link
Copy Markdown
Member Author

lkingland commented Oct 30, 2025

I'd group prompts and tools into a package. and if needed, even sub-group the tools.

I'd than do something like https://github.com/containers/kubernetes-mcp-server/blob/main/pkg/toolsets/core/toolset.go#L23 for registering those.

The kubernetes-mcp-server toolset registry pattern is good for that use case (dozens of tools across multiple independent domains like Kubernetes, Helm, and Config), but is a bit overly complex here.

  1. No multiple independent tool domains (we have one cohesive domain: Knative Functions)
  2. No need for a plugin system for third-party tools (all our tools are in-tree)
  3. No need for conditional toolset loading (our 8 tools are always loaded)

For our single-domain, static toolset of only 8 tools, explicit registration in New() is simple, without the indirection of init functions, global registries, etc. Lower cognitive load.

I'd say we follow that pattern if our complexity grows 👍

Comment thread docs/mcp-integration/integration.md Outdated
Copy link
Copy Markdown
Contributor

@twoGiants twoGiants left a comment

Choose a reason for hiding this comment

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

Left a few more comments.

Looks all good! I have mostly cleanup comments. Can (not must) all be done in a follow PR and would polish the code a bit. But you make the call 😸

Comment thread pkg/mcp/tools_build.go Outdated
Comment thread pkg/mcp/tools_config_test.go Outdated
Comment thread pkg/mcp/tools_build_test.go Outdated
Comment thread pkg/mcp/tools_build_test.go Outdated
Comment thread pkg/mcp/tools_build_test.go Outdated
Comment thread pkg/mcp/tools_build_test.go
Comment thread pkg/mcp/instructions.go Outdated
Comment thread pkg/oci/testdata/test-links/absoluteLink Outdated
@lkingland lkingland marked this pull request as draft November 4, 2025 06:21
@knative-prow knative-prow Bot added the do-not-merge/work-in-progress 🤖 PR should not merge because it is a work in progress. label Nov 4, 2025
@lkingland
Copy link
Copy Markdown
Member Author

Updates the POC Functions MCP server to be a slightly more mature experimental MCP server.

Converting back to draft, so we can make it slightly more... slightly more mature.

@lkingland lkingland force-pushed the push-krlrkrmlkzqt branch 7 times, most recently from a44f448 to 2594188 Compare November 5, 2025 11:14
@lkingland lkingland marked this pull request as ready for review November 5, 2025 11:18
@knative-prow knative-prow Bot removed the do-not-merge/work-in-progress 🤖 PR should not merge because it is a work in progress. label Nov 5, 2025
@knative-prow knative-prow Bot requested a review from jrangelramos November 5, 2025 11:18
@lkingland lkingland force-pushed the push-krlrkrmlkzqt branch 2 times, most recently from 0c89862 to 2c6a1bf Compare November 5, 2025 11:35
Copy link
Copy Markdown
Contributor

@twoGiants twoGiants left a comment

Choose a reason for hiding this comment

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

Great job on the re-work! Approved 😸 👍.

It's more concise now. The API is condensed.

I have a few comments but they are again just nice-to-haves and should not stop the PR from merging.

Comment thread pkg/mcp/mcp.go
Comment on lines +13 to +15
Name = "func"
Title = "func"
Version = "0.1.0"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Encapsulate non exported.

Suggested change
Name = "func"
Title = "func"
Version = "0.1.0"
bame = "func"
title = "func"
version = "0.1.0"

Comment thread pkg/mcp/mcp.go
Comment on lines +80 to +82
Name: Name,
Title: Title,
Version: Version},
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
Name: Name,
Title: Title,
Version: Version},
Name: name,
Title: title,
Version: version},

Comment thread pkg/mcp/mcp.go
func (s *MCPServer) Start() error {
return server.ServeStdio(s.server)
}
var ErrWriteDisabled = errors.New("server is not write enabled")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Remove unused.

Suggested change
var ErrWriteDisabled = errors.New("server is not write enabled")

Comment thread pkg/mcp/mcp.go
server: mcpServer,
}
cmd := exec.CommandContext(ctx, cmdParts[0], cmdParts[1:]...)
// Commands always execute in current working directory
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It's the default behavior since cmd.Dir is not set. I would either remove the comment or make it more precise:

Suggested change
// Commands always execute in current working directory
// cmd.Dir not set - inherits process working directory which is the current working directory

Comment thread pkg/mcp/mcp_test.go
}

// newTestPairWithReadonly returns a ClientSession and Server with the specified readonly mode.
func newTestPairWithReadonly(t *testing.T, readonly bool) (*mcp.ClientSession, *Server, error) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

newTestPairWithReadonly and newTestPair are nearly identical and can be refactored into one function with logic => newTestPair and newTestPairWithReadonly decorating it and setting readonly.

Comment thread pkg/mcp/resources.go

// resource helpers:

func newErrorResult(uri string, err error) *mcp.ReadResourceResult {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

You could put another helper here which would be used in the other resource_*.go files:

func newSuccessResult(uri, mime string, text []byte) *mcp.ReadResourceResult {
	return &mcp.ReadResourceResult{
		Contents: []*mcp.ResourceContents{
			{
				URI:      uri,
				MIMEType: mime,
				Text:     string(text),
			},
		},
	}
}

Comment thread pkg/mcp/resources_test.go
}
}

func TestResource_Languages(t *testing.T) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This and the next could be one table driven test with two test cases. Would remove the duplication.

Comment thread pkg/mcp/tools_test.go
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is pretty good!

The tools_*_test.go are very similar. This file could have a bit more, like common assertions and common setup. But no need to do now. Could be a good-first-issue.

@knative-prow knative-prow Bot added the lgtm 🤖 PR is ready to be merged. label Nov 6, 2025
@knative-prow
Copy link
Copy Markdown

knative-prow Bot commented Nov 6, 2025

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: lkingland, twoGiants

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@knative-prow knative-prow Bot merged commit 8f447a8 into knative:main Nov 6, 2025
39 checks passed
@lkingland
Copy link
Copy Markdown
Member Author

Left a few more comments.

Looks all good! I have mostly cleanup comments. Can (not must) all be done in a follow PR and would polish the code a bit. But you make the call 😸

Solid suggestions @twoGiants ; I'll add those changes in an update PR.

matejvasek added a commit to openshift-knative/kn-plugin-func that referenced this pull request Nov 6, 2025
picking knative#3155

Signed-off-by: Matej Vašek <mvasek@redhat.com>
Co-authored-by: Luke Kingland <luke@lukekingland.com>
openshift-merge-bot Bot pushed a commit to openshift-knative/kn-plugin-func that referenced this pull request Nov 6, 2025
* fix templates ref

picking knative#2967

Signed-off-by: Matej Vašek <mvasek@redhat.com>
Co-authored-by: David Fridrich <fridrich.david19@gmail.com>

* Revert "fix: MCP use "kn func" not "func" cmd (#1380)"

This reverts commit 38f804e.

Signed-off-by: Matej Vašek <matejvasek@gmail.com>

* mcp refactor

picking knative#3155

Signed-off-by: Matej Vašek <mvasek@redhat.com>
Co-authored-by: Luke Kingland <luke@lukekingland.com>

* fixup: compatibility with Go 1.23

The test context was introduced only in Go 1.24 we need however
compatibility with Go 1.23.

Signed-off-by: Matej Vašek <mvasek@redhat.com>

---------

Signed-off-by: Matej Vašek <mvasek@redhat.com>
Signed-off-by: Matej Vašek <matejvasek@gmail.com>
Co-authored-by: David Fridrich <fridrich.david19@gmail.com>
Co-authored-by: Luke Kingland <luke@lukekingland.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved 🤖 PR has been approved by an approver from all required OWNERS files. lgtm 🤖 PR is ready to be merged. size/XXL 🤖 PR changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants