Skip to content

mcp: add func-workflow prompt for guided Function lifecycle - #3737

Closed
thonmay wants to merge 1 commit into
knative:mainfrom
thonmay:feat/mcp-func-workflow-prompt
Closed

thonmay wants to merge 1 commit into
knative:mainfrom
thonmay:feat/mcp-func-workflow-prompt

Conversation

@thonmay

@thonmay thonmay commented May 14, 2026

Copy link
Copy Markdown

Changes

Adds a func-workflow MCP prompt that guides agents through the full Function lifecycle: create, build, and deploy.

Why Option 2 (add a real prompt) over Option 1 (set HasPrompts: false):
Setting the flag to false would be a minimal fix but leaves the capability unused. A guided workflow prompt is directly useful to agents and aligns with the MCP server's purpose of enabling end-to-end agentic usage of Functions.

Prompt behavior:

  • Name: func-workflow
  • Optional language argument to tailor guidance (e.g. go, python, node)
  • Returns step-by-step instructions referencing the real MCP tools (create, build, deploy) and resources (func://languages, func://templates, func://function)
  • HasPrompts: true remains correct now that a prompt is registered

Tests added (3):

  • TestPrompt_Listed — prompt appears in ListPrompts response
  • TestPrompt_Get — prompt returns valid message with create/deploy content
  • TestPrompt_GetWithLanguage — language argument is reflected in output

/kind enhancement

Fixes #3734

Add MCP `func-workflow` prompt for guided Function lifecycle (create, build, deploy)

@knative-prow knative-prow Bot added the kind/enhancement Feature additions or improvements to existing label May 14, 2026
@knative-prow
knative-prow Bot requested review from dsimansk and jrangelramos May 14, 2026 21:47
@knative-prow

knative-prow Bot commented May 14, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: thonmay
Once this PR has been reviewed and has the lgtm label, please assign matejvasek for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found 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 added size/L 🤖 PR changes 100-499 lines, ignoring generated files. needs-ok-to-test 🤖 Needs an org member to approve testing labels May 14, 2026
@knative-prow

knative-prow Bot commented May 14, 2026

Copy link
Copy Markdown

Hi @thonmay. Thanks for your PR.

I'm waiting for a knative member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work.

Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@gauron99

Copy link
Copy Markdown
Contributor

🦴 CAVEMAN REVIEWER HAVE QUESTIONS 🦴

Thank for contribution. Before review, answer these. No answer, no review.

1. Explain

  • In your own words — what this change do and how it work? Not copy from issue, not copy from PR template. YOUR words.
  • This PR include describe tool from mcp: add describe tool for Function inspection #3736 AND prompt. Why bundle both? These separate changes — why one PR?

2. Why

  • Issue mcp: either register prompts or set HasPrompts to false #3734 say two options: set HasPrompts: false OR add real prompt. You pick Option 2. Why? What make static text prompt more useful than just fixing flag?
  • Would agent actually use this prompt in real workflow? Or this just exist so flag not lie?
  • What specific problem this solve that agent can't already do by calling tools directly?

3. Testing

  • You run MCP server and test prompt end-to-end with real agent? Not CI — you, on your machine.
  • Do you screenshot your work? Caveman like see proof it work.

4. Understanding

  • Explain in own words how MCP prompts different from MCP tools. When agent use prompt vs tool?
  • What break if we no merge this?

We welcome all contributors. But change must be understood by author and solve real problem. PRs that no demonstrate this — closed.

@thonmay

thonmay commented May 15, 2026

Copy link
Copy Markdown
Author

1. Explain

Adds func-workflow prompt: guided create → build → deploy message template. Takes optional language arg, returns step-by-step instructions referencing the right tools and resources.

Also includes describe tool from #3736. You're right, separate changes. I'll rebase this to prompt-only, keep describe in #3736.

2. Why

Option 1 (set flag false) = fix the lie, add no value.
Option 2 (add prompt) = fix the lie, add value.

Agent sees 17 tools and several resources. Doesn't know the order, doesn't know func://languages should be checked before create, doesn't know registry is needed on first deploy. The prompt gives that orchestration knowledge in one shot.

MCP clients (Claude Desktop, Cursor) expose prompts to users. User picks "func-workflow" → agent gets a structured plan. Tools are individual actions; prompt is the recipe.

Without it, agent relies on instructions.md (long, may get truncated in some clients).

3. Testing

Ran locally:

  • prompts/list → shows func-workflow with [language] argument
  • prompts/get(language="go") → returns full workflow text with "Use language: go" interpolated

Screenshots attached.

4. Understanding

Tools = model-controlled, agent calls them to DO things.
Prompts = user-controlled, inject structured guidance into conversation.

Agent uses tool when it knows what to do. User invokes prompt when they want guided help.

No merge = HasPrompts: true remains a lie. No workflow guidance for new users.

@thonmay

thonmay commented May 15, 2026

Copy link
Copy Markdown
Author
mcp-test-tools-registered mcp-test-calls

Adds a 'func-workflow' MCP prompt that guides agents through the
full Function lifecycle: create, build, and deploy. Accepts an
optional 'language' argument to tailor the guidance.

This resolves the HasPrompts: true capability flag being advertised
without any prompts registered, which could mislead MCP clients.

Fixes knative#3734

Signed-off-by: Thonmay <mdthoriqulislam384@gmail.com>
@thonmay
thonmay force-pushed the feat/mcp-func-workflow-prompt branch from e68747d to f6c8a57 Compare May 17, 2026 09:09
@lkingland

Copy link
Copy Markdown
Member

/ok-to-test

@knative-prow knative-prow Bot added ok-to-test 🤖 Non-member PR verified by an org member that is safe to test. and removed needs-ok-to-test 🤖 Needs an org member to approve testing labels May 18, 2026
@codecov

codecov Bot commented May 18, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 57.10%. Comparing base (584c11e) to head (f6c8a57).
⚠️ Report is 166 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3737      +/-   ##
==========================================
+ Coverage   57.03%   57.10%   +0.07%     
==========================================
  Files         182      183       +1     
  Lines       21376    21409      +33     
==========================================
+ Hits        12191    12225      +34     
  Misses       7953     7953              
+ Partials     1232     1231       -1     
Flag Coverage Δ
e2e 35.75% <0.00%> (-0.07%) ⬇️
e2e go 31.36% <0.00%> (-0.06%) ⬇️
e2e node 27.20% <0.00%> (-0.05%) ⬇️
e2e python 31.73% <0.00%> (-0.06%) ⬇️
e2e quarkus 27.32% <0.00%> (-0.05%) ⬇️
e2e rust 26.74% <0.00%> (-0.04%) ⬇️
e2e springboot 25.27% <0.00%> (-0.05%) ⬇️
e2e typescript 27.31% <0.00%> (-0.05%) ⬇️
e2e-config-ci 28.11% <0.00%> (-0.05%) ⬇️
integration 17.14% <0.00%> (-0.04%) ⬇️
unit macos-14 45.17% <100.00%> (+0.08%) ⬆️
unit macos-latest 45.17% <100.00%> (+0.08%) ⬆️
unit ubuntu-24.04-arm 45.42% <100.00%> (+0.08%) ⬆️
unit ubuntu-latest 46.12% <100.00%> (+0.08%) ⬆️
unit windows-latest 45.21% <100.00%> (+0.07%) ⬆️

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

☔ View full report in Codecov by Harness.
📢 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.

@knative-prow-robot knative-prow-robot added the needs-rebase Cannot be merged due to conflicts with HEAD. label Aug 10, 2026
@knative-prow-robot

Copy link
Copy Markdown

PR needs rebase.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

Ankitsinghsisodya added a commit to Ankitsinghsisodya/func that referenced this pull request Aug 24, 2026
The onboard prompt ran its local run and invoke before asking for a
registry, on the theory that proving the Function works should not
require one. It does: the default builder is pack, so a local run
builds a container image, and naming that image needs a registry.
Without one the build fails with "registry required" — for exactly the
first-time user the prompt exists to serve, at a step the prompt
forbids skipping past. Registry configuration is now step 4 and the
local run step 5, which passes the gathered registry to run.

Read-only mode omitted the registry step along with deploy and the
remote invoke, yet still rendered "ask the user in step 5" in the
parameters table, asked for a registry in the summary, and closed by
telling the user to re-run deploy, which read-only refuses. The
registry step is no longer omitted — a local build has to name an
image whether or not it is ever pushed — and the remaining
deploy-dependent text is now conditional.

Language and template were validated against hardcoded lists. Which
runtimes and templates exist depends on the installed binary and on
any repositories added with the repository_add tool this same server
exposes, so those lists rejected legitimate values outright. Only
cluster is validated now, being prompt-internal and never passed to
func; the rest are trimmed and passed through with their case intact,
since a fold would corrupt the very repository-supplied names the
lists used to reject. The agent is still told to check them against
func://languages and func://templates.

The deploy step named go and python as the host builder's runtimes. It
now branches on oci.IsSupported, leaving pkg/oci the only place that
list lives.

Also: drop step 3's question about a Function name, there being no
name argument to carry it (the name is the directory basename); drop
the instruction to cd, which nothing depends on now that every tool
call takes an absolute path; and assert table values in tests through
a padding-insensitive match, so realigning the markdown cannot fail
the build.

Relates to knative#3737
knative-prow Bot pushed a commit that referenced this pull request Aug 31, 2026
* feat(mcp): add parameterized 'onboard' prompt

The server advertised prompts capability but registered none. Add the
first: 'onboard', a multi-step workflow driving an agent end-to-end from
an empty directory to a deployed, invocable Function.

The eight steps map onto existing tools and resources: version (with a
kubectl-context check), func://languages, create, run + invoke --target
local + run_stop, registry elicitation, deploy + describe, invoke
--target remote, and a summary read back out of tool output rather than
out of what was requested.

All four arguments (language, template, registry, cluster) are optional.
Supplied values are rendered into the prompt and marked as decided;
omitted ones render as an explicit instruction to ask the user at the
relevant step, since neither a language nor a registry has a sane
default. template defaults to http and cluster to local. Values are
normalized (case, whitespace) and validated, with "cloudevent" resolving
to the "cloudevents" template that actually exists on disk; the registry
keeps its case, being an image reference prefix. Unrecognized values are
rejected rather than rendered, so the agent is never sent off to run a
command that cannot succeed.

The prompt body is an embedded text/template, mirroring how the server's
instructions are embedded. In read-only mode the registry, deploy and
remote-invoke steps are omitted rather than handed to an agent that
would be refused, and the user is told to restart with
FUNC_ENABLE_MCP_WRITE=true.

* chore: re-trigger CI

The lint job failed fetching the golangci-lint JSON schema from
golangci-lint.run (network timeout), not on anything in this change.

* fix(mcp): gather registry before the local run

The onboard prompt ran its local run and invoke before asking for a
registry, on the theory that proving the Function works should not
require one. It does: the default builder is pack, so a local run
builds a container image, and naming that image needs a registry.
Without one the build fails with "registry required" — for exactly the
first-time user the prompt exists to serve, at a step the prompt
forbids skipping past. Registry configuration is now step 4 and the
local run step 5, which passes the gathered registry to run.

Read-only mode omitted the registry step along with deploy and the
remote invoke, yet still rendered "ask the user in step 5" in the
parameters table, asked for a registry in the summary, and closed by
telling the user to re-run deploy, which read-only refuses. The
registry step is no longer omitted — a local build has to name an
image whether or not it is ever pushed — and the remaining
deploy-dependent text is now conditional.

Language and template were validated against hardcoded lists. Which
runtimes and templates exist depends on the installed binary and on
any repositories added with the repository_add tool this same server
exposes, so those lists rejected legitimate values outright. Only
cluster is validated now, being prompt-internal and never passed to
func; the rest are trimmed and passed through with their case intact,
since a fold would corrupt the very repository-supplied names the
lists used to reject. The agent is still told to check them against
func://languages and func://templates.

The deploy step named go and python as the host builder's runtimes. It
now branches on oci.IsSupported, leaving pkg/oci the only place that
list lives.

Also: drop step 3's question about a Function name, there being no
name argument to carry it (the name is the directory basename); drop
the instruction to cd, which nothing depends on now that every tool
call takes an absolute path; and assert table values in tests through
a padding-insensitive match, so realigning the markdown cannot fail
the build.

Relates to #3737

* chore: re-trigger CI
@lkingland

Copy link
Copy Markdown
Member

Thanks @thonmay, and sorry this stalled on our side. An onboard prompt covering the full lifecycle landed via #4021 in the meantime, so I'm closing this as superseded.

@lkingland lkingland closed this Oct 29, 2026
@github-project-automation github-project-automation Bot moved this from New to Done in Functions Traige Oct 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/enhancement Feature additions or improvements to existing needs-rebase Cannot be merged due to conflicts with HEAD. ok-to-test 🤖 Non-member PR verified by an org member that is safe to test. size/L 🤖 PR changes 100-499 lines, ignoring generated files.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

mcp: either register prompts or set HasPrompts to false

4 participants