Skip to content

Open the shared board's session for clients that never initialize - #23

Merged
emanuele-em merged 1 commit into
emanuele-em:mainfrom
BurnOutTrader:fix/stateless-clients-on-joined-board
Nov 4, 2026
Merged

emanuele-em merged 1 commit into
emanuele-em:mainfrom
BurnOutTrader:fix/stateless-clients-on-joined-board

Conversation

@BurnOutTrader

@BurnOutTrader BurnOutTrader commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #24.

Clients on MCP 2026-07-28 never send initialize. They send server/discover, then name
themselves in every request's _meta. Claude Code 2.1.309 is one such client. rmcp 3.8.0
serves these clients fine on a private board, but on a joined board every tool call returns
The shared board answered 400.

A joined kanzo mcp opens its session on the host by forwarding the client's own
initialize (peer_info()). These clients never sent one, so Kanzo forwards
"params": null. The host answers 400 Bad Request: Session ID is required, and answers the
same to notifications/initialized and to the tools/call.

This change builds that initialize from the request's _meta when the client never sent
one:

  • It uses 2025-11-25, rmcp's LATEST_WITH_INITIALIZE, since 2026-07-28 itself has no
    initialize.
  • It names the client agent when the request gives no name.
  • A client that did send initialize is forwarded exactly as before.

add_comment takes its default author the same way: from _meta on a 2026-07-28 request,
and from initialize otherwise, as before. Over HTTP, rmcp gives a stateless request a
stand-in initialize named rmcp, so a stateless client that gave no name was credited as
rmcp. It is now credited as agent, as it is over stdio.

A joined board still opens one host session per kanzo mcp process, so that session keeps
the name from the process's first call. Clients send the same name on every call, so this
shows only if a client's name changes partway through.

Three new tests run the real server in process:

  • A stateless client's comment, sent through a joined board, reaches the host credited as
    claude-code. On main it gets the 400.
  • A client that sends initialize, and a different name in _meta, is still credited with
    its initialize name.
  • A stateless HTTP client that gives no name is credited as agent.

Two unit tests pin the forwarded initialize: its version, its name and capabilities taken
from _meta, and a client's own initialize passed on unchanged.

I tested it against a board shared from another machine:

  • With Claude Code 2.1.309's own messages replayed, 0.3.0 returns the 400, and this branch
    lists the projects.
  • A client that sends initialize still works.
  • A live Claude Code session's calls succeed once its kanzo mcp runs this build.

No MCP reply changes size.

  • cargo fmt --check, cargo clippy --all-targets -- -D warnings and cargo test pass
  • A board change was tried in a browser, in light and dark mode: not applicable, nothing
    on the board changes
  • The README says what changed for users, if anything did: nothing changes for users

@BurnOutTrader
BurnOutTrader marked this pull request as ready for review November 3, 2026 22:46
@BurnOutTrader
BurnOutTrader marked this pull request as draft November 3, 2026 23:13
Clients on MCP 2026-07-28, like Claude Code 2.1.309, send no initialize:
they name themselves in each request's _meta. A joined kanzo mcp copied
the client's initialize into the one it sends the host, so for these
clients it sent "params": null, the host refused it, and every tool call
came back as "The shared board answered 400."

Build that initialize from the request's _meta when there was none, at
the newest protocol that still has one. add_comment reads its default
author the same way: from _meta on 2026-07-28 requests, which also stops
a stateless HTTP client that gives no name being credited as "rmcp", and
from initialize otherwise, as before.
@BurnOutTrader
BurnOutTrader force-pushed the fix/stateless-clients-on-joined-board branch from 5cbe89b to 4726bbc Compare November 3, 2026 23:20
@BurnOutTrader
BurnOutTrader marked this pull request as ready for review November 3, 2026 23:23
@github-actions

github-actions Bot commented Nov 4, 2026

Copy link
Copy Markdown

Resources

If merged, nothing moves by more than noise.

Agents

main this PR change
Tool list, read every session 2.9 KB 2.9 KB same
Instructions, read every session 325 B 325 B same
Reply to list_projects 59 B 59 B same
Reply to list_tasks (8) 316 B 316 B same
Reply to get_task 433 B 433 B same
Reply to next_task 450 B 450 B same
Reply to add_comment 37 B 37 B same
Reply to update_task 55 B 55 B same
Reply to create_task 42 B 42 B same

Program

main this PR change
Binary 4.78 MB 4.79 MB +11.8 KB (+0.2%)
Crates in Cargo.lock 157 157 same

Memory

main this PR change
Idle board 6.24 MB 6.43 MB +188.4 KB (+3.0%)
Board with 3,000 tasks loaded 11.89 MB 11.96 MB +73.7 KB (+0.6%)
Peak of the board 11.89 MB 11.96 MB +73.7 KB (+0.6%)
kanzo mcp after a session 8.18 MB 8.21 MB +28.7 KB (+0.4%)
Threads when idle 1 1 same

Speed

main this PR change
Start 1.4 ms 1.4 ms same
/api/board with 3,000 tasks 8.6 ms 8.3 ms same

Storage

main this PR change
Empty database 78.6 KB 78.6 KB same
Database with 3,000 tasks 1.26 MB 1.26 MB same
/api/board reply with 3,000 tasks 1.06 MB 1.06 MB same
Board page (HTML, JS, logo) 105.3 KB 105.3 KB same

Measured on GitHub's ubuntu-26.04 runner, median of 3 rounds with the builds taking turns. Changes in bold are past noise: 1% for sizes, 5% for memory, 15% for times. Agents' text is in bytes: add an ANTHROPIC_API_KEY secret to count tokens.

@emanuele-em emanuele-em left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

lgtm

@emanuele-em
emanuele-em merged commit 798fcf7 into emanuele-em:main Nov 4, 2026
10 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.

A joined board answers 400 to clients on MCP 2026-07-28, which never send initialize

2 participants