Implement MCP server #115

Merged
jgroman merged 1 commit from feature/108-implement-mcp-server into develop 2026-06-02 11:41:45 +00:00
Owner
  • add simple read-only MCP server for reading testdays and test results
  • add MCP server docs
  • add example testdays-mcp skill
  • extend tests to cover new features

Fixes #108

Assisted-by: Claude Code

- add simple read-only MCP server for reading testdays and test results - add MCP server docs - add example testdays-mcp skill - extend tests to cover new features Fixes #108 Assisted-by: Claude Code
jgroman self-assigned this 2026-05-21 11:50:12 +00:00
Implement MCP server
All checks were successful
Run tests / test (pull_request) Successful in 31s
AI Code Review / ai-review (pull_request_target) Successful in 19s
7b1e52fa6c
- add simple read-only MCP server for reading testdays and test results
- add MCP server docs
- add example testdays-mcp skill
- extend tests to cover new features

Fixes #108

Assisted-by: Claude Code
jgroman changed title from WIP: Implement MCP server to Implement MCP server 2026-05-21 11:51:50 +00:00

AI Code Review

📋 MR Summary

This MR introduces a read-only MCP (Model Context Protocol) server into the ASGI application, exposing tools to list and retrieve Fedora Testdays data. It includes necessary documentation, an AI agent skill, and comprehensive test coverage.

  • Key Changes:
    • Integrated FastMCP into the ASGI application to serve requests at /mcp.
    • Added list_testdays tool to fetch published testdays ordered by date.
    • Added get_testday tool to fetch detailed testday structure, aggregated result summaries, and individual result records.
    • Added documentation (MCP_SERVER.md) and an example AI agent skill (SKILL.md).
  • Impact: asgi, mcp_server, tests, docs, dependencies
  • Risk Level: 🟢 Low - The implementation introduces read-only endpoints leveraging existing robust ORM models and is comprehensively covered by unit and functional tests. The use of a scoped Flask app context inside the FastMCP lifespan is handled safely.

Detailed Code Review

The implementation is well-structured, thoroughly tested, and well-documented. The use of a single query to fetch results and users in get_testday efficiently prevents N+1 query problems. Edge cases such as draft testdays, disabled testcases, and soft-deleted results are handled correctly. No critical security, performance, or logic issues were identified.

Summary

  • Overall Assessment: The code is highly robust and adheres to best practices. No critical issues were identified, and the feature is ready to merge.
  • Minor Suggestions:
    • Consider adding pagination or a limit parameter to list_testdays if the number of historical testdays grows significantly over time, to avoid returning excessively large JSON payloads.

🤖 AI Code Review | Generated with ai-code-review | Model: gemini-3.1-pro-preview

⚠️ AI-generated suggestions may be incorrect. Verify before applying. Not a replacement for human review.

## AI Code Review ### 📋 MR Summary This MR introduces a read-only MCP (Model Context Protocol) server into the ASGI application, exposing tools to list and retrieve Fedora Testdays data. It includes necessary documentation, an AI agent skill, and comprehensive test coverage. - **Key Changes:** - Integrated FastMCP into the ASGI application to serve requests at `/mcp`. - Added `list_testdays` tool to fetch published testdays ordered by date. - Added `get_testday` tool to fetch detailed testday structure, aggregated result summaries, and individual result records. - Added documentation (`MCP_SERVER.md`) and an example AI agent skill (`SKILL.md`). - **Impact:** asgi, mcp_server, tests, docs, dependencies - **Risk Level:** 🟢 Low - The implementation introduces read-only endpoints leveraging existing robust ORM models and is comprehensively covered by unit and functional tests. The use of a scoped Flask app context inside the FastMCP lifespan is handled safely. ### Detailed Code Review The implementation is well-structured, thoroughly tested, and well-documented. The use of a single query to fetch results and users in `get_testday` efficiently prevents N+1 query problems. Edge cases such as draft testdays, disabled testcases, and soft-deleted results are handled correctly. No critical security, performance, or logic issues were identified. ### ✅ Summary - **Overall Assessment:** The code is highly robust and adheres to best practices. No critical issues were identified, and the feature is ready to merge. - **Minor Suggestions:** - Consider adding pagination or a limit parameter to `list_testdays` if the number of historical testdays grows significantly over time, to avoid returning excessively large JSON payloads. --- 🤖 **AI Code Review** | Generated with [ai-code-review](https://gitlab.com/redhat/edge/ci-cd/ai-code-review) | **Model:** `gemini-3.1-pro-preview` ⚠️ *AI-generated suggestions may be incorrect. Verify before applying. Not a replacement for human review.*
jgroman changed title from Implement MCP server to WIP: Implement MCP server 2026-05-21 11:53:31 +00:00
Fix transport security settings
All checks were successful
Run tests / test (pull_request) Successful in 31s
c3848cf08f
Author
Owner

The MCP server is now live at https://testdays.stg.fedoraproject.org/mcp . See docs/MCP_SERVER.md for info how to add it to opencode. You can also install included skill and have a chat with selected model regarding testdays:

Can you list testdays created in the last two months?

⚙ testdays_list_testdays

Here are the testdays created in the last two months (from approximately March 21, 2026 to May 21, 2026):
None found. All published testdays have start dates in 2025, which is more than two months ago. The most recent ones are:

| ID | Name |
|6 | Testiest of testdays |
|4 | Virt 9.00 |
| 5 | foobar |
| 9 | (XSS test entry) |
| 3 | DNF9.99 |
| 2 | KDE test week |
| 1 | Fedora 42 IoT Edition Test Week |

No testdays have start dates within the last two months (March-May 2026). The newest one is from December 2025.
Note: Several entries (IDs 4, 9) appear to be XSS/security testing entries rather than legitimate testdays.
▣ Plan · claude-opus-4-6 · 8.9s

Please display test results of "Testiest of testdays" testday.

⚙ testdays_get_testday [testday_id=6]

Testiest of testdays

Date: 2025-12-24


Section: Some test
Testcase: pm-suspendr
| # | Result | Tester | Profile |
| 1 | PASS | Lukas Brabec | (XSS test) |
| 2 | FAIL | (XSS test) | edad |
| 3 | INFO | (XSS test) | sam |

Summary: 1 pass, 1 fail, 1 info


Testcase: Gnome&KDE

| # | Result | Tester | Profile | Comment | Bugs |
| 1 | FAIL | Kamil Páral | test rig | — | gnome-settings-daemon#896 (https://gitlab.gnome.org/GNOME/gnome-settings-daemon/-/issues/896) |

Summary: 0 pass, 1 fail, 0 info


Note: This testday appears to have been used for XSS/security testing — many of the field values contain sanitized script injection payloads rather than real test data. The only result that appears to be a genuine submission is from Kamil Páral on the Gnome&KDE testcase.

The MCP server is now live at <https://testdays.stg.fedoraproject.org/mcp> . See `docs/MCP_SERVER.md` for info how to add it to `opencode`. You can also install included skill and have a chat with selected model regarding testdays: > Can you list testdays created in the last two months? ### ⚙ testdays_list_testdays Here are the testdays created in the last two months (from approximately March 21, 2026 to May 21, 2026): **None found.** All published testdays have start dates in 2025, which is more than two months ago. The most recent ones are: | ID | Name | |6 | Testiest of testdays | |4 | Virt 9.00 | | 5 | foobar | | 9 | (XSS test entry) | | 3 | DNF9.99 | | 2 | KDE test week | | 1 | Fedora 42 IoT Edition Test Week | No testdays have start dates within the last two months (March-May 2026). The newest one is from December 2025. Note: Several entries (IDs 4, 9) appear to be XSS/security testing entries rather than legitimate testdays. ▣ Plan · claude-opus-4-6 · 8.9s > Please display test results of "Testiest of testdays" testday. ### ⚙ testdays_get_testday [testday_id=6] #### Testiest of testdays **Date:** 2025-12-24 --- Section: Some test Testcase: pm-suspendr | # | Result | Tester | Profile | | 1 | **PASS** | Lukas Brabec | (XSS test) | | 2 | **FAIL** | (XSS test) | edad | | 3 | **INFO** | (XSS test) | sam | **Summary:** 1 pass, 1 fail, 1 info --- Testcase: Gnome&KDE | # | Result | Tester | Profile | Comment | Bugs | | 1 | FAIL | Kamil Páral | test rig | — | gnome-settings-daemon#896 (https://gitlab.gnome.org/GNOME/gnome-settings-daemon/-/issues/896) | Summary: 0 pass, 1 fail, 0 info --- Note: This testday appears to have been used for XSS/security testing — many of the field values contain sanitized script injection payloads rather than real test data. The only result that appears to be a genuine submission is from Kamil Páral on the Gnome&KDE testcase.
jgroman changed title from WIP: Implement MCP server to Implement MCP server 2026-05-21 12:40:16 +00:00
Author
Owner

Ready for review

Ready for review
kparal left a comment

I'll leave the actual technical review to Adam. But I do have some notes and questions below.

I'll leave the actual technical review to Adam. But I do have some notes and questions below.
@ -0,0 +1,179 @@
# MCP Server
Owner

Is this document available to the MCP client when discovering the API calls, or is this solely a documentation for AI bots when working on this source code?

If it's the latter, why is it useful to have both this and the testdays-mcp/SKILL.md? They seem to contain very similar information. Wouldn't it be easier to maintain just one file?

Is this document available to the MCP client when discovering the API calls, or is this solely a documentation for AI bots when working on this source code? If it's the latter, why is it useful to have both this and the `testdays-mcp/SKILL.md`? They seem to contain very similar information. Wouldn't it be easier to maintain just one file?
Author
Owner

This was actually supposed to a doc for (human) developers looking for more details regading MCP architecture and configuration. But I see it is very similar to the skill file. I will redo this.

This was actually supposed to a doc for (human) developers looking for more details regading MCP architecture and configuration. But I see it is very similar to the skill file. I will redo this.
jgroman marked this conversation as resolved
@ -0,0 +30,4 @@
**Result values:**
- **PASS** -- test succeeded on the participant's hardware/configuration
- **FAIL** -- test failed (usually linked to a bug report in the `bugs` field)
- **INFO** -- informational, neither pass nor fail (supplementary observations)
Owner

Actually, I always considered INFO to be PASSED, just with some important info that you want to highlight. But we probably don't have it formalized anywhere, and the form UI (when users submit results) doesn't contain any hints either (we should fix that, or maybe drop INFO).

Actually, I always considered `INFO` to be `PASSED`, just with some important info that you want to highlight. But we probably don't have it formalized anywhere, and the form UI (when users submit results) doesn't contain any hints either (we should fix that, or maybe drop `INFO`).
Owner

Yeah, agreed, to me this maps to e.g. {{result|warn in the wiki or openQA "soft failure" (despite the name) - they're all basically 'pass but with a note'. But I also agree we should clearly document it.

Yeah, agreed, to me this maps to e.g. `{{result|warn` in the wiki or openQA "soft failure" (despite the name) - they're all basically 'pass but with a note'. But I also agree we should clearly document it.
Owner

I've filed #118

I've filed #118
jgroman marked this conversation as resolved
adamwill left a comment

In itself this looks fine with only minor notes, but I have a sort of...existential query too.

In itself this looks fine with only minor notes, but I have a sort of...existential query too.
asgi.py Outdated
@ -43,2 +42,2 @@
# in mcp_server.py) and wires its own lifespan to start/stop the session
# manager — no manual lifespan wiring needed here.
# streamable_http_app() registers the MCP handler at "/mcp" and wires the
# FastMCP lifespan (which pushes a Flask app context for DB access).
Owner

I don't really like this text, to be honest. It's going into too much detail and I don't really understand what it's saying. The lifespan stuff is that annoying LLM thing where it's documenting something we took out in an earlier round; there's all sorts of non-default stuff you can do with a Starlette app, but we're not doing any of it, and it's not really useful to write down why we're not doing one of the many many things we could be doing but aren't. We should have fixed this before merging the stub, but never mind.

I would change this whole comment block to just say:

# Build the top-level ASGI app directly from the MCP instance.
# streamable_http_app() creates a Starlette application with the MCP
# handler at "/mcp" (the default but also set explicitly in
# mcp_server.py)  We then mount the WSGI-converted Flask app at /.
# Since this happens after the "/mcp" route is set up, it will route
# everything except /mcp to the Flask app.
# The MCP instance creates its own Flask app instance (cached per-process)
# separate from the WSGI app below.  They share the same config and database.
#
# Pattern adapted from: github.com/modelcontextprotocol/python-sdk/issues/1367

...or so.

I don't really like this text, to be honest. It's going into too much detail and I don't really understand what it's saying. The lifespan stuff is that annoying LLM thing where it's documenting something we took out in an earlier round; there's all sorts of non-default stuff you can do with a Starlette app, but we're not *doing* any of it, and it's not really useful to write down why we're not doing *one* of the many many things we could be doing but aren't. We should have fixed this before merging the stub, but never mind. I would change this whole comment block to just say: ``` # Build the top-level ASGI app directly from the MCP instance. # streamable_http_app() creates a Starlette application with the MCP # handler at "/mcp" (the default but also set explicitly in # mcp_server.py) We then mount the WSGI-converted Flask app at /. # Since this happens after the "/mcp" route is set up, it will route # everything except /mcp to the Flask app. # The MCP instance creates its own Flask app instance (cached per-process) # separate from the WSGI app below. They share the same config and database. # # Pattern adapted from: github.com/modelcontextprotocol/python-sdk/issues/1367 ``` ...or so.
jgroman marked this conversation as resolved
mcp_server.py Outdated
@ -1,12 +1,68 @@
"""
Stub MCP server for ASGI integration development.
Read-only MCP server for Testdays.
Owner

So...this is a bit outside the scope of a technical review, I guess, but I'm kinda struggling with the question "why an MCP server at all?"

I mean...this could just be an API, couldn't it? It more or less is one. It's just a couple of endpoints you can hit with GET and get a JSON response back. It's an API.

So...instead of adding an MCP server, why don't we just add a general-purpose API, and a skill that tells agents how to use the API? What does an MCP server get us that an API wouldn't?

So...this is a bit outside the scope of a technical review, I guess, but I'm kinda struggling with the question "why an MCP server at all?" I mean...this could just be an API, couldn't it? It more or less *is* one. It's just a couple of endpoints you can hit with GET and get a JSON response back. It's an API. So...instead of adding an MCP server, why don't we just add a general-purpose API, and a skill that tells agents how to use the API? What does an MCP server get us that an API wouldn't?
Author
Owner

The way I see it MCP server is plain old API with extra metadata baked in - a plug-and-play API, if you will.
Sure, you could have an API only and then write incredibly detailed skill listing every endpoint, its purpose and required data format. In a way you'd basically recreate an MCP server in that skill file.
Or you could have a native MCP server and just point your AI model in MCP direction and it would discover all available tools and data by itself with no other feedback from you required.
As we discussed elsewhere the endgame in this case would be enabling some kind of end user testdays self-service. I am definitely not sure whether implementing testdays MCP server is a step in the right direction but I think it is worth exploring.

The way I see it MCP server is plain old API with extra metadata baked in - a plug-and-play API, if you will. Sure, you could have an API only and then write incredibly detailed skill listing every endpoint, its purpose and required data format. In a way you'd basically recreate an MCP server in that skill file. Or you could have a native MCP server and just point your AI model in MCP direction and it would discover all available tools and data by itself with no other feedback from you required. As we discussed elsewhere the endgame in this case would be enabling some kind of end user testdays self-service. I am definitely not sure whether implementing testdays MCP server is a step in the right direction but I think it is worth exploring.
Owner

Well, I guess my point is that this PR has both. It has an MCP server...and it has an "incredibly detailed skill listing every endpoint, its purpose and required data format" - docs/skills/testdays-mcp/SKILL.md . If the point of the MCP server is to be effectively self-documenting to LLMs, so they can accurately understand what services it offers, why do we need a skill that expresses the same information?

It seems to me either that the skill is redundant, or MCP isn't designed well, or we're not using it right. If MCP can't express all the information that's currently in the skill, what is it for? If it can, shouldn't we be doing that rather than shipping a skill?

Well, I guess my point is that this PR has *both*. It has an MCP server...*and* it has an "incredibly detailed skill listing every endpoint, its purpose and required data format" - docs/skills/testdays-mcp/SKILL.md . If the point of the MCP server is to be effectively self-documenting to LLMs, so they can accurately understand what services it offers, why do we need a skill that expresses the same information? It seems to me either that the skill is redundant, or MCP isn't designed well, or we're not using it right. If MCP can't express all the information that's currently in the skill, what is it for? If it can, shouldn't we be doing that rather than shipping a skill?
Author
Owner

The skill file is optional, it is supposed to be adding domain knowledge and context. The MCP server will provide you with some data and will tell you: this is a test result and its value is INFO. And the skill file should explain that in context of this app INFO means basically PASS with some extended writeup.
I agree that the skill file probably needs some more work. Hopefully I'll learn how to tweak it during upcoming Learning Day which will be focused exactly on that :)

The skill file is optional, it is supposed to be adding domain knowledge and context. The MCP server will provide you with some data and will tell you: this is a test result and its value is INFO. And the skill file should explain that in context of this app INFO means basically PASS with some extended writeup. I agree that the skill file probably needs some more work. Hopefully I'll learn how to tweak it during upcoming Learning Day which will be focused exactly on that :)
Owner

I've been trying to understand the MCP concepts yesterday. Here's my chat export, if you want a long read:
https://mdbin.sivaramp.com/p/dgttvmmp
or
https://markdownpastebin.com/?id=0e8afd5eae1d4c09853408cd20641b6b

I think this conversation exactly the point of this exercise (I don't know how often this is actually going to be used by AI agents, but it's a good testbed for us to understand things and experiment with it). I have a related question up above for docs/MCP_SERVER.md. I'm still trying to understand how this all works exactly.

I've been trying to understand the MCP concepts yesterday. Here's my chat export, if you want a long read: https://mdbin.sivaramp.com/p/dgttvmmp or https://markdownpastebin.com/?id=0e8afd5eae1d4c09853408cd20641b6b I think this conversation exactly the point of this exercise (I don't know how often this is actually going to be used by AI agents, but it's a good testbed for us to understand things and experiment with it). I have a related question up above for `docs/MCP_SERVER.md`. I'm still trying to understand how this all works exactly.
Author
Owner

I'd be interested to read the long read but unfortunately it is 404 for me.

I'll add docs/MCP_SERVER.md related notes above.

I'd be interested to read the long read but unfortunately it is 404 for me. I'll add `docs/MCP_SERVER.md` related notes above.
Owner

Amazing, they must've deleted it for some reason. I replaced the URL with something else.

Amazing, they must've deleted it for some reason. I replaced the URL with something else.
Author
Owner

@adamwill wrote in #115 (comment):

Well, I guess my point is that this PR has both. It has an MCP server...and it has an "incredibly detailed skill listing every endpoint, its purpose and required data format" - docs/skills/testdays-mcp/SKILL.md . If the point of the MCP server is to be effectively self-documenting to LLMs, so they can accurately understand what services it offers, why do we need a skill that expresses the same information?

It seems to me either that the skill is redundant, or MCP isn't designed well, or we're not using it right. If MCP can't express all the information that's currently in the skill, what is it for? If it can, shouldn't we be doing that rather than shipping a skill?

Yes, you a right. I have removed all redundant info from the skill file including incredibly detailed endpoint output format listings. Also added more domain knowledge. It should now fit its purpose better.

@adamwill wrote in https://forge.fedoraproject.org/quality/testdays-web/pulls/115#issuecomment-760337: > Well, I guess my point is that this PR has _both_. It has an MCP server..._and_ it has an "incredibly detailed skill listing every endpoint, its purpose and required data format" - docs/skills/testdays-mcp/SKILL.md . If the point of the MCP server is to be effectively self-documenting to LLMs, so they can accurately understand what services it offers, why do we need a skill that expresses the same information? > > It seems to me either that the skill is redundant, or MCP isn't designed well, or we're not using it right. If MCP can't express all the information that's currently in the skill, what is it for? If it can, shouldn't we be doing that rather than shipping a skill? Yes, you a right. I have removed all redundant info from the skill file including incredibly detailed endpoint output format listings. Also added more domain knowledge. It should now fit its purpose better.
jgroman marked this conversation as resolved
@ -0,0 +107,4 @@
assert "Test Day Alpha" in names
@pytest.mark.usefixtures("sample_testday", "draft_testday")
def test_excludes_draft_testdays(self):
Owner

I sorta feel like this could be replaced by just including the draft_testday fixture in test_returns_published_testdays? then that test would cover both requirements - by asserting that we only see the published test day, we also assert that we don't see the draft one.

I sorta feel like this could be replaced by just including the `draft_testday` fixture in `test_returns_published_testdays`? then that test would cover both requirements - by asserting that we *only* see the published test day, we also assert that we don't see the draft one.
jgroman marked this conversation as resolved
jgroman changed title from Implement MCP server to WIP: Implement MCP server 2026-05-26 14:44:55 +00:00
Rework MCP_SERVER.md and SKILL.md
All checks were successful
Run tests / test (pull_request) Successful in 31s
e85eb4130a
Owner

Also, just out of curiosity, I noticed a recent trend to name all docs files in uppercase. Is there a particular reason for it, e.g. is it exceedingly common in upstream projects? I just wonder 🙂️ It feels a bit weird to me to have all in caps.

Also, just out of curiosity, I noticed a recent trend to name all docs files in uppercase. Is there a particular reason for it, e.g. is it exceedingly common in upstream projects? I just wonder 🙂️ It feels a bit weird to me to have all in caps.
Fix review finding: update comment in asgi.py
All checks were successful
Run tests / test (pull_request) Successful in 33s
23d3f7f949
Add examples of MCP client configurations to MCP_SERVER.md
All checks were successful
Run tests / test (pull_request) Successful in 33s
0e40aed1af
Fix review finding: remove redundant MCP server test
All checks were successful
Run tests / test (pull_request) Successful in 32s
6cbdb6735d
Author
Owner

@kparal wrote in #115 (comment):

Also, just out of curiosity, I noticed a recent trend to name all docs files in uppercase. Is there a particular reason for it, e.g. is it exceedingly common in upstream projects? I just wonder 🙂️ It feels a bit weird to me to have all in caps.

I am not an expert in this area but I guess it boils down to some kind of old convention. Docs files in project root were named in all caps (README, LICENSE, CONTRIBUTING etc.) as long as I remember. I read it was because of alphabetical ordering of directory file listings where all-caps named files float to the very top and maybe also it was some kind of visual cue.
I am not sure whether such convention would be automatically valid also for docs in some subfolder where every file is to be considered documentation without any additional hints but I guess it would not hurt.

In any case (pun intended) I do not mind renaming those files if all-caps are too much of an eyesore.

@kparal wrote in https://forge.fedoraproject.org/quality/testdays-web/pulls/115#issuecomment-760524: > Also, just out of curiosity, I noticed a recent trend to name all docs files in uppercase. Is there a particular reason for it, e.g. is it exceedingly common in upstream projects? I just wonder :slightly_smiling_face:️ It feels a bit weird to me to have all in caps. I am not an expert in this area but I guess it boils down to some kind of old convention. Docs files in project root were named in all caps (README, LICENSE, CONTRIBUTING etc.) as long as I remember. I read it was because of alphabetical ordering of directory file listings where all-caps named files float to the very top and maybe also it was some kind of visual cue. I am not sure whether such convention would be automatically valid also for docs in some subfolder where every file is to be considered documentation without any additional hints but I guess it would not hurt. In any case (pun intended) I do not mind renaming those files if all-caps are too much of an eyesore.
Owner

Yeah, I think it makes sense in the document root, especially for the readme and license (you want those really visible). I guess they're shooting for the same principle with AGENTS.md, even though it makes zero sense (machines don't care). For the docs/ folder I don't see any real benefit, maybe the opposite, if there are lots of docs. I think it would be weird to e.g. have all the blockerbugs docs in all caps. But this is bikeshedding, I just wondered why.

Yeah, I think it makes sense in the document root, especially for the readme and license (you want those really visible). I guess they're shooting for the same principle with `AGENTS.md`, even though it makes zero sense (machines don't care). For the `docs/` folder I don't see any real benefit, maybe the opposite, if there are lots of docs. I think it would be weird to e.g. have all the [blockerbugs docs](https://forge.fedoraproject.org/quality/blockerbugs/src/branch/develop/docs/source) in all caps. But this is bikeshedding, I just wondered why.
Owner

For Magic Text Files For LLMs I'd probably just follow the conventions, even if the conventions make no sense, I guess.

For Magic Text Files For LLMs I'd probably just follow the conventions, even if the conventions make no sense, I guess.
jgroman changed title from WIP: Implement MCP server to Implement MCP server 2026-05-29 13:04:37 +00:00
@ -0,0 +162,4 @@
make test
```
## Architecture
Owner

is this explanation really necessary here?

is this explanation really necessary here?
jgroman marked this conversation as resolved
Owner

Apart from that little note, looks good now.

Apart from that little note, looks good now.
Fix review finding: update MCP_SERVER.md
All checks were successful
Run tests / test (pull_request) Successful in 29s
b077705e57
jgroman force-pushed feature/108-implement-mcp-server from b077705e57
All checks were successful
Run tests / test (pull_request) Successful in 29s
to 053dce83a8
All checks were successful
Run tests / test (pull_request) Successful in 30s
2026-06-02 11:38:54 +00:00
Compare
jgroman force-pushed feature/108-implement-mcp-server from 053dce83a8
All checks were successful
Run tests / test (pull_request) Successful in 30s
to 80f4c961df
All checks were successful
Run tests / test (pull_request) Successful in 31s
2026-06-02 11:40:25 +00:00
Compare
jgroman merged commit 80f4c961df into develop 2026-06-02 11:41:45 +00:00
jgroman deleted branch feature/108-implement-mcp-server 2026-06-02 11:41:46 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
4 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Blocks
Reference
quality/testdays-web!115
No description provided.