plain-mcp changelog
0.3.0 (2026-07-10)
What's changed
tools/callarguments are now validated against the tool's advertised input schema before the tool is instantiated. A missing or wrong-typed argument comes back as a clear, model-fixableisErrormessage (e.g.Invalid arguments: 'limit' must be an integer) instead of blowing up insiderun()and being logged as a server exception. Validation covers the schema shapes derived from type hints — primitives,Literal[...]enums,list[T],T | None— and follows JSON Schema semantics (booleans are not integers;5.0is a valid integer). If you hand-write aninput_schemawith richer JSON Schema keywords (oneOf,$ref,pattern, numeric bounds), those pass through unvalidated — check them in__init__orrun()yourself. (04e6309f7b)- Parameters with no annotation,
Any, or an unrecognized type now advertise a permissive empty schema (accepts any JSON value) instead of{"type": "string"}, so clients are no longer steered into sending strings for values that aren't. (04e6309f7b) *args/**kwargsparameters on a tool's__init__are no longer advertised as schema properties — previously a**kwargstool advertised a requiredkwargsproperty that no client could ever satisfy. (04e6309f7b)
Upgrade instructions
- No changes required for tools whose type hints match what clients actually send. If a tool was knowingly accepting schema-mismatched arguments (e.g. a param annotated
intthat clients send as a string), those calls are now rejected before__init__— loosen the annotation (or hand-writeinput_schema) to keep accepting them.
0.2.1 (2026-06-30)
What's changed
- Documentation only: the MCP endpoint examples now use a slashless path (
/mcprather than/mcp/) consistently across the README and theMCPViewdocstring. No code or behavior changes. (0399d8b)
Upgrade instructions
- No changes required.
0.2.0 (2026-06-28)
What's changed
- New
MCPToolErrorexception, exported fromplain.mcp. Raise it from a tool'srun()to signal an expected, caller-facing failure (bad input, not found, forbidden): the message is returned to the client withisError: true— MCP's in-result error channel, so the model can self-correct — and it is not logged as a server exception. Any other exception is still treated as a bug: logged server-side and returned as an opaque "Tool execution failed" (4989aeb). - New optional
annotationsattribute onMCPTool. Set it to a raw MCP-wire-format dict (e.g.{"readOnlyHint": True}) to advertise tool annotation hints; clients like Claude group read-only tools and gate approval on the rest. The dict is emitted verbatim — any current or future spec hint works without aplain.mcpchange — and a tool that sets no annotations carries noannotationsobject at all. Inherited like any class attribute, so a shared base tool can set it once (88588a0). - Documented the typed
self.mcppattern: re-annotatemcpon a per-app base tool or resource (mcp: AppMCP) for typed access to your view'suser,scopes, and other subclass attributes. The full MCP↔OAuth client handshake walkthrough now lives in this README as well (3460d76).
Upgrade instructions
- No changes required. Optionally raise
MCPToolErrorfor expected tool failures, and setannotations = {"readOnlyHint": True}on read-only tools so clients can group and auto-allow them.
0.1.0 (2026-06-26)
Initial release of plain.mcp — build a Model Context Protocol (MCP) server inside a Plain app.
What's changed
MCPView: an MCP server endpoint that exposestoolsandresourcesover the Streamable HTTP transport (JSON-RPC), with declarative or imperative tool/resource registration.- Composable authentication — session auth via
AuthView, a bearer-token check inbefore_request, or OAuth. - Issuer-agnostic OAuth resource-server support: the
OAuthResourceServermixin +TokenInfoseam, an RFC 9728 protected-resource metadata view (MCPProtectedResourceView), and aWWW-Authenticatechallenge, so an endpoint can accept bearer tokens from any issuer (pair withplain.oauthserver). - Implements MCP protocol version 2025-11-25, with version negotiation in
initializeandMCP-Protocol-Versionheader validation.
Upgrade instructions
- No changes required (first release).