cursus.mcp.envelope

The result envelope every cursus MCP tool returns.

Tools never raise across the tool boundary and never print. They return a ToolResult — a small, JSON-serializable success/error envelope — so that any agent framework can consume the outcome uniformly. The server adapter and the in-process cursus.mcp.registry.call_tool() both rely on this contract.

exception ToolError(message, code='tool_error', details=None)[source]

Bases: Exception

Raised inside a tool to signal a handled, user-facing failure.

The registry’s invoker catches this and converts it to ToolResult.failure(...), preserving code and details. Use this for expected failures (bad input, not-found, validation) — let genuinely unexpected exceptions propagate so the invoker can wrap them as an internal_error.

class ToolResult(ok, data=None, error=None, code=None, warnings=<factory>, next_steps=<factory>, remedy=None, meta=<factory>)[source]

Bases: object

Uniform tool outcome.

ok

Whether the tool succeeded.

Type:

bool

data

JSON-serializable payload on success (None on error).

Type:

Any | None

error

Human-readable error message on failure (None on success).

Type:

str | None

code

Machine-readable error code on failure (e.g. "not_found", "invalid_input", "internal_error").

Type:

str | None

warnings

Non-fatal messages an agent may surface or reason about.

Type:

List[str]

next_steps

Optional in-band guidance for an agent on a successful result — a list of {"tool", "when", "why"} ("args_hint" optional) entries naming the tool(s) the agent would typically call next. Lets the golden path live on the result instead of in the agent’s prompt.

Type:

List[Dict[str, Any]]

remedy

Optional in-band recovery hint on a failure{"suggested_tools": [...], "fix_action": str} naming the tool(s) or action that typically resolves this error, so the agent does not have to reverse-engineer a remedy from the bare code.

Type:

Dict[str, Any] | None

meta

Optional side-band info (tool name, timings, counts) — never required for correctness.

Type:

Dict[str, Any]

ok: bool
data: Any | None = None
error: str | None = None
code: str | None = None
warnings: List[str]
next_steps: List[Dict[str, Any]]
remedy: Dict[str, Any] | None = None
meta: Dict[str, Any]
classmethod success(data=None, warnings=None, next_steps=None, **meta)[source]
classmethod failure(message, code='tool_error', details=None, warnings=None, remedy=None)[source]
to_dict()[source]

Render to a plain JSON-serializable dict (drops empty optional fields).