Skip to content

Commit e97a3b6

Browse files
committed
style(bridge,mcp): adopt the lean tool-docstring convention for peek/decisions
Rebase adaptation onto main, which rewrote every tool docstring to drop the Returns: block (the model reads the result shape from the call itself) in favor of a one-line Errors: list of behavioural error codes. peek()/decisions() on both the stdio bridge and the in-process MCP server were still on the old verbose style; bring them in line so the bridge/http parity guard keeps comparing apples to apples. Also consolidates CHANGELOG.md's [Unreleased] section, which after the rebase carried two separate Added headings (one from main, one from this branch) — merged into one, alongside main's existing Fixed and Changed buckets.
1 parent 5692b71 commit e97a3b6

3 files changed

Lines changed: 10 additions & 31 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ and rename that heading to the version when you cut the release.
8888
either abandoning the clear or hanging indefinitely. (`HubConnector.ping`/
8989
`set_status` already existed; only the auto-status wiring around
9090
`_drive_turn` is new.)
91+
- **`docs/operating-cheaply.md`**, on running an agent from a passive,
92+
turn-based MCP host without wasting turns: the cost model, what the peer
93+
queue does and does not guarantee, the three listening strategies, and
94+
when to batch questions.
9195

9296
### Changed
9397

@@ -180,13 +184,6 @@ and rename that heading to the version when you cut the release.
180184
Connected bridges will see `protocol_stale` on their next `join` and re-read
181185
the text once, as designed.
182186

183-
### Added
184-
185-
- **`docs/operating-cheaply.md`**, on running an agent from a passive,
186-
turn-based MCP host without wasting turns: the cost model, what the peer queue
187-
does and does not guarantee, the three listening strategies, and when to batch
188-
questions.
189-
190187
## [2.3.1](https://github.com/obeone/caucus-mcp/compare/v2.3.0...v2.3.1) (2026-08-03)
191188

192189
### Fixed

src/caucus/mcp_bridge.py

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -598,9 +598,7 @@ def ping(peer: str) -> dict[str, object]:
598598
def peek() -> dict[str, object]:
599599
"""Check whether anything is waiting for you without draining it — a cheap "worth a turn?" probe. Requires join.
600600
601-
Returns:
602-
``{"pending": <int>, "last": {"sender", "preview"} | None}``, or the
603-
usual ``not_joined`` gate error.
601+
Errors: ``not_joined``.
604602
"""
605603
gate = _ensure_armed()
606604
if gate is not None:
@@ -886,19 +884,12 @@ def list_forms() -> dict[str, object]:
886884
@mcp.tool()
887885
@_resilient_hub_call
888886
def decisions(limit: int = 20) -> dict[str, object]:
889-
"""List recently settled operator-form decisions, oldest first — catch up without replaying the transcript. Requires join.
890-
891-
Scoped to broadcast decisions plus those addressed to a channel you
892-
currently belong to, same as the audience a channel-scoped answer
893-
would itself have reached over listen().
887+
"""List recently settled operator-form decisions, oldest first — catch up without replaying the transcript. Scoped to broadcast plus channels you belong to. Requires join.
894888
895889
Args:
896890
limit: Maximum number of decisions to return (the most recent ones).
897891
898-
Returns:
899-
``{"decisions": [{"ts", "asker", "title", "status",
900-
"answer_summary"}, ...]}``, the usual ``not_joined`` gate error, or
901-
``{"error": "hub_unreachable", ...}``.
892+
Errors: ``not_joined``.
902893
"""
903894
gate = _ensure_armed()
904895
if gate is not None:

src/caucus/mcp_http.py

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -808,9 +808,7 @@ async def ping(ctx: _Ctx, peer: str) -> dict[str, object]:
808808
async def peek(ctx: _Ctx) -> dict[str, object]:
809809
"""Check whether anything is waiting for you without draining it — a cheap "worth a turn?" probe. Requires join.
810810
811-
Returns:
812-
``{"pending": <int>, "last": {"sender", "preview"} | None}``, or
813-
the usual ``not_joined`` gate error.
811+
Errors: ``not_joined``.
814812
"""
815813
member, gate = await _ensure_armed(ctx)
816814
if gate is not None:
@@ -1081,19 +1079,12 @@ async def list_forms(ctx: _Ctx) -> dict[str, object]:
10811079
@_resilient
10821080
async def decisions( ctx: _Ctx, limit: int = 20
10831081
) -> dict[str, object]:
1084-
"""List recently settled operator-form decisions, oldest first — catch up without replaying the transcript. Requires join.
1085-
1086-
Scoped to broadcast decisions plus those addressed to a channel you
1087-
currently belong to, same as the audience a channel-scoped answer
1088-
would itself have reached over listen().
1082+
"""List recently settled operator-form decisions, oldest first — catch up without replaying the transcript. Scoped to broadcast plus channels you belong to. Requires join.
10891083
10901084
Args:
10911085
limit: Maximum number of decisions to return (the most recent ones).
10921086
1093-
Returns:
1094-
``{"decisions": [{"ts", "asker", "title", "status",
1095-
"answer_summary"}, ...]}``, the usual ``not_joined`` gate error, or
1096-
``{"error": "hub_unreachable", ...}``.
1087+
Errors: ``not_joined``.
10971088
"""
10981089
member, gate = await _ensure_armed(ctx)
10991090
if gate is not None:

0 commit comments

Comments
 (0)