Skip to content

Mcp server#278

Merged
aliceinwire merged 7 commits into
kernelci:mainfrom
bhcopeland:mcp-server
Jul 4, 2026
Merged

Mcp server#278
aliceinwire merged 7 commits into
kernelci:mainfrom
bhcopeland:mcp-server

Conversation

@bhcopeland

Copy link
Copy Markdown
Member

No description provided.

@bhcopeland
bhcopeland marked this pull request as draft July 1, 2026 22:06
@bhcopeland

Copy link
Copy Markdown
Member Author
image

Using the MCP + Claude asking mainline to find flaky tests just as an example

@bhcopeland
bhcopeland marked this pull request as ready for review July 2, 2026 10:33
@tales-aparecida
tales-aparecida self-requested a review July 2, 2026 11:16

@tales-aparecida tales-aparecida left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I don't have a maestro token, but code-wise and dashboard read-only endpoints are good!

Comment thread kcidev/subcommands/mcp.py
Comment on lines +47 to +48
server = create_server(cfg, instance, host=host, port=port)
server.run(transport="stdio" if transport == "stdio" else "streamable-http")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggested change
server = create_server(cfg, instance, host=host, port=port)
server.run(transport="stdio" if transport == "stdio" else "streamable-http")
server = create_server(cfg, instance, host=host, port=port)
logging.info("Starting MCP server %s", "via stdio" if transport == "stdio" else f"on {host}:{port}")
server.run(transport="stdio" if transport == "stdio" else "streamable-http")

@tales-aparecida

Copy link
Copy Markdown

There's indeed a lot in common with #277, but I don't know if we can avoid that.

@tales-aparecida

Copy link
Copy Markdown

Finally, you left a few functions uncovered, like dashboard_fetch_commits_history, which would allow to compare checkouts 😅

@tales-aparecida

tales-aparecida commented Jul 2, 2026

Copy link
Copy Markdown

MCP docs testing feedback (docs/mcp.md)1

Tested the documentation against the implementation and exercised the MCP server end-to-end (stdio transport, tool listing, live list_trees and get_summary calls). Findings below.

Missing tool: commit history

kcidev.libs.dashboard has dashboard_fetch_commits_history (hitting /tree/{commit}/commits), but it is not exposed as an MCP tool. This makes it impossible to discover previous commits for a tree/branch through the MCP server - you can only query a commit if you already know its hash. A list_commits tool would enable the natural workflow of comparing results across checkouts.

Unbounded responses crash the MCP connection

Calling list_tests on a heavily-tested tree produces a response large enough to crash the stdio transport. Reproduced by registering the server with Claude Code (claude mcp add kernelci -- kci-dev mcp) and asking it to list tests for mainline:

{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"list_tests","arguments":{"giturl":"https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git","branch":"master","commit":"dc59e4fea9d83f03bad6bddf3fa2e52491777482"}}}

The server disconnects every time with MCP error -32000: Connection closed.

Root cause: The dashboard API for mainline v7.2-rc1 returns {"tests": [...]} with 45,769 entries (~23.8 MB JSON). FastMCP serializes this into a single TextContent block and builds a ~30.9 MB JSON-RPC message. The server-side serialization completes fine in isolation (verified by running the conversion pipeline outside the stdio transport), but the client drops the connection when receiving it. Claude Code enforces a per-tool result size limit (anthropic/maxResultSizeChars) with a hard ceiling of 500,000 characters - the 30.9 MB payload exceeds this by ~60x.

The dashboard list tools (list_tests, list_builds, list_boots) return all results with no pagination. Adding limit/offset parameters (like list_nodes already has) would fix this and make the tools usable on large trees. Even without the crash, responses beyond 500K chars are truncated by the client, so pagination is necessary for correctness too.

serverInfo.version

serverInfo.version in the initialize response shows the mcp SDK version (1.28.1), not the kci-dev version. FastMCP defaults to its own package version. Minor, but could confuse users checking which kci-dev they're running.

What works well

  • pip install kci-dev[mcp], kci-dev mcp, --transport/--host/--port all work as documented
  • The graceful fallback when mcp extra is not installed works (clear error message)
  • Tool annotations are correct: dashboard tools have readOnlyHint: true, action tools have readOnlyHint: false
  • The list_trees -> get_summary workflow described in server instructions works correctly
  • The security warning about HTTP transport having no auth is accurate

Footnotes

  1. Assisted-by: Claude Opus 4.6 noreply@anthropic.com

@bhcopeland

bhcopeland commented Jul 3, 2026

Copy link
Copy Markdown
Member Author

Thanks, @tales-aparecida, for testing. I also noticed a bug with get_nodes (a TypeError, a bug with kcidb though so a good to fix), I'll include fix here but also put it it could be a seperate PR. For the other bits, I'll get them fixed up / added.

@aliceinwire

Copy link
Copy Markdown
Member

There's indeed a lot in common with #277, but I don't know if we can avoid that.

yes, that should be merged and use kci-dev as a library using the new python library api

Signed-off-by: Ben Copeland <ben.copeland@linaro.org>
Signed-off-by: Ben Copeland <ben.copeland@linaro.org>
Signed-off-by: Ben Copeland <ben.copeland@linaro.org>
The node API returns JSON null for a missing node id, which crashed
maestro_get_node with an AttributeError while logging. Raise a
ClickException naming the node instead, so callers report a clean
not-found message.

Signed-off-by: Ben Copeland <ben.copeland@linaro.org>
Signed-off-by: Ben Copeland <ben.copeland@linaro.org>
Signed-off-by: Ben Copeland <ben.copeland@linaro.org>
Signed-off-by: Ben Copeland <ben.copeland@linaro.org>
@bhcopeland

Copy link
Copy Markdown
Member Author

There's indeed a lot in common with #277, but I don't know if we can avoid that.

yes, that should be merged and use kci-dev as a library using the new python library api

Done! :)

@aliceinwire

Copy link
Copy Markdown
Member

There's indeed a lot in common with #277, but I don't know if we can avoid that.

yes, that should be merged and use kci-dev as a library using the new python library api

Done! :)

I think you should use the following instead of recreating a new dashboard/kcidb api
https://github.com/kernelci/kci-dev/blob/main/kcidev/api.py

bisection and checkouts are called through run_command()

By looking your code I just found that we was doing almost the same things but for different purpose

@bhcopeland

bhcopeland commented Jul 3, 2026

Copy link
Copy Markdown
Member Author

There's indeed a lot in common with #277, but I don't know if we can avoid that.

yes, that should be merged and use kci-dev as a library using the new python library api

Done! :)

I think you should use the following instead of recreating a new dashboard/kcidb api https://github.com/kernelci/kci-dev/blob/main/kcidev/api.py

bisection and checkouts are called through run_command()

By looking your code I just found that we was doing almost the same things but for different purpose

Thanks! Yes indeed. For dashboard this is done on my last push (goes through the link you provided)

But, for the other events like get_nodes, trigger_checkout) etc, so maestro events, we'd need to extend KernelCIClient. I think we'd be best off moving send_* over to libs/maestro_common (from subcommand modules), so the API doesn't depend on CLI modules.

The MCP consumes the client for everything, inc dashboard. Also, I'm including any other maestro operations (which weren't in the initial 277, which makes sense, like you say similar things but different purpose. Happy to do that in this pr or do a following pr and get those included? I would probably say a new PR for this work would make sense. Let me know what you think, and happy to go ahead and do that change.

@aliceinwire

aliceinwire commented Jul 3, 2026

Copy link
Copy Markdown
Member

There's indeed a lot in common with #277, but I don't know if we can avoid that.

yes, that should be merged and use kci-dev as a library using the new python library api

Done! :)

I think you should use the following instead of recreating a new dashboard/kcidb api https://github.com/kernelci/kci-dev/blob/main/kcidev/api.py
bisection and checkouts are called through run_command()
By looking your code I just found that we was doing almost the same things but for different purpose

Thanks! Yes indeed. For dashboard this is done on my last push (goes through the link you provided)

But, for the other events like get_nodes, trigger_checkout) etc, so maestro events, we'd need to extend KernelCIClient. I think we'd be best off moving send_* over to libs/maestro_common (from subcommand modules), so the API doesn't depend on CLI modules.

The MCP consumes the client for everything, inc dashboard. Also, I'm including any other maestro operations (which weren't in the initial 277, which makes sense, like you say similar things but different purpose. Happy to do that in this pr or do a following pr and get those included? I would probably say a new PR for this work would make sense. Let me know what you think, and happy to go ahead and do that change.

I'm ok doing this on a different PR and extend KernelCIClient

@bhcopeland

Copy link
Copy Markdown
Member Author

There's indeed a lot in common with #277, but I don't know if we can avoid that.

yes, that should be merged and use kci-dev as a library using the new python library api

Done! :)

I think you should use the following instead of recreating a new dashboard/kcidb api https://github.com/kernelci/kci-dev/blob/main/kcidev/api.py
bisection and checkouts are called through run_command()
By looking your code I just found that we was doing almost the same things but for different purpose

Thanks! Yes indeed. For dashboard this is done on my last push (goes through the link you provided)
But, for the other events like get_nodes, trigger_checkout) etc, so maestro events, we'd need to extend KernelCIClient. I think we'd be best off moving send_* over to libs/maestro_common (from subcommand modules), so the API doesn't depend on CLI modules.
The MCP consumes the client for everything, inc dashboard. Also, I'm including any other maestro operations (which weren't in the initial 277, which makes sense, like you say similar things but different purpose. Happy to do that in this pr or do a following pr and get those included? I would probably say a new PR for this work would make sense. Let me know what you think, and happy to go ahead and do that change.

I'm ok doing this on a different PR and extend KernelCIClient

Okay, sounds good. I'll get writing it over the weekend and will get a PR up soon.

Have a nice weekend!

@aliceinwire

Copy link
Copy Markdown
Member

There's indeed a lot in common with #277, but I don't know if we can avoid that.

yes, that should be merged and use kci-dev as a library using the new python library api

Done! :)

I think you should use the following instead of recreating a new dashboard/kcidb api https://github.com/kernelci/kci-dev/blob/main/kcidev/api.py
bisection and checkouts are called through run_command()
By looking your code I just found that we was doing almost the same things but for different purpose

Thanks! Yes indeed. For dashboard this is done on my last push (goes through the link you provided)
But, for the other events like get_nodes, trigger_checkout) etc, so maestro events, we'd need to extend KernelCIClient. I think we'd be best off moving send_* over to libs/maestro_common (from subcommand modules), so the API doesn't depend on CLI modules.
The MCP consumes the client for everything, inc dashboard. Also, I'm including any other maestro operations (which weren't in the initial 277, which makes sense, like you say similar things but different purpose. Happy to do that in this pr or do a following pr and get those included? I would probably say a new PR for this work would make sense. Let me know what you think, and happy to go ahead and do that change.

I'm ok doing this on a different PR and extend KernelCIClient

Okay, sounds good. I'll get writing it over the weekend and will get a PR up soon.

Have a nice weekend!

you too!

@aliceinwire
aliceinwire merged commit c06a1ab into kernelci:main Jul 4, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants