mirror of
https://github.com/badlogic/pi-mono.git
synced 2026-11-05 23:37:25 +00:00
Radius's control-plane client now bundles pi-schema, and Vite's license step reads the first entry whose name starts with "license" as the package's license file. Here that entry is pi-schema's LICENSES/ folder, so Vite tries to read a directory as a file and the build fails, which renaming the folder fixes without any Radius-side workaround.
8.8 KiB
8.8 KiB
Changelog
[Unreleased]
Added
- Added
PipeTransport, MCP's stdio transport over a program started by the caller through anMcpPipe(write,closeStdin,close,exited), for example@earendil-works/pi-env'sopenProcess()on another machine.StdioTransportandPipeTransportshare the newline-delimited framing and the stderr tail. - Added MCP OAuth sign-in in two halves (
@earendil-works/pi-mcp/oauth), moved from pi's coding agent:startMcpSignIn()refreshes the stored tokens or returns the authorization URL, andcompleteMcpSignIn()exchanges the code later, possibly in another request with the same state store. The code comes from a loopback callback server (listenForLoopbackSignIn(),waitForLoopbackSignIn()), the application's own callback route, or a pasted redirect URL (responseFromRedirectUrl()). Client ID Metadata Documents (clientMetadataDocuments) and the client name are the caller's. Aborting a sign-in'ssignalalso stopsstartMcpSignIn()while it waits for the refresh lock; a store'swithRefreshLock()throwsMcpRefreshLockBusyErrorwhen another process holds the lock too long, which makesstartMcpSignIn()skip the refresh, while any other lock failure fails the sign-in. Also addedcreateMcpAuthProvider(), which refreshes tokens once across requests and, throughMcpOAuthServerStore.withRefreshLock(), across processes; itsredirectUrloption names a redirect URI the application signs in with, so tokens from a Client ID Metadata Document that lists only an https callback route can be refreshed. Also added therefreshOnlyoption ofauthorizeMcp(), which refreshes without registering a client or replacing a pending authorization'sstateand PKCE verifier. - Added helpers that let applications name and configure MCP tools like pi's coding agent, moved from it:
createMcpToolName()(mcp__<server>__<tool>, sanitized, with a hash suffix for long or colliding names) andmcpNamespace();normalizeMcpInputSchema(), which makes an input schema an object schema;limitMcpContent()andMCP_OUTPUT_MAX_BYTES, which cut model-facing text over 20KB in the middle and optionally save the full text through a caller'sMcpOutputSaver; andvalidateMcpServerConfig(), which validates one entry of themcpServersconfiguration shape (stdio, Streamable HTTP,oauth,enabled,description,timeout), returns the entry tagged with its transport, and keeps the application's own fields for it to check afterwards.isMcpServerOverride()recognizes entries that only override a server defined elsewhere.
Fixed
- The third-party licenses are in
THIRD_PARTY_NOTICES/, renamed fromLICENSES/, which Vite's license notices read as the package's license file, failing browser builds that bundle the package. - Fixed Streamable HTTP
application/jsonresponses bypassingmaxMessageBytes; oversized JSON responses are now cancelled and rejected like oversized SSE events (#11335) - Fixed Streamable HTTP errors reading the whole HTTP error body; only the first 8 KiB kept in the error is read, and the rest is cancelled
[1.5.0] - 2026-11-02
Changed
- README: the
AgentToolwrapping example passes the MCP input schema as plain JSON Schema instead of through TypeBox'sType.Unsafe.
Fixed
- OAuth metadata parsing and
startAuthorization()now accept onlyhttp:andhttps:URLs. Before, a server could supply afile:or custom protocol authorization endpoint (for examplesearch-ms:), which the platform URL handler would launch on sign-in. - Fixed the excerpt of an HTTP error body in Streamable HTTP errors keeping the whole response body alive (#9265)
[1.4.0] - 2026-10-21
[1.3.0] - 2026-10-15
[1.2.0] - 2026-10-12
Breaking Changes
- Changed
CallToolResult.structuredContentfromRecord<string, unknown>tounknown:callTool()now accepts any JSON value as structured content, including arrays andnull, as MCP 2026-07-28 allows, instead of failing with "Invalid MCP tools/call structured content" (#10416)
Fixed
- Fixed
authorizeMcp()exchanging an authorization code whoseissparameter could not be checked because no authorization server metadata was discovered. It now throwsOAuthIssuerMismatchError, whoseexpectedisundefinedin that case (RFC 9207). Reported by @AizenvoltPrime - Fixed
StreamableHttpTransportretrying a request after an authorization refresh even though the caller had already cancelled it or it had timed out, so the server still executed it.McpTransport.send()now takes an optionalsignal, whichMcpClientaborts once a request settles (#10598)
[1.1.0] - 2026-10-07
Added
- Added a
signaloption toauthorizeMcp(),registerClient(), the token request functions, and the discovery functions, which aborts their requests. An aborted refresh no longer falls back to a new authorization (#10565)
Fixed
- Fixed
StreamableHttpTransport.close()callingAuthProvider.token(), which could refresh tokens over the network before the session DELETE and delay closing; the DELETE now reuses the token of the last request (#10565)
[1.0.4] - 2026-10-05
Fixed
- Fixed dynamic client registration failing on OpenID Connect authorization servers with
invalid_redirect_urifor loopback redirect URIs.registerClient()now sendsapplication_type(MCP SEP-837), derived fromredirect_uriswhenOAuthClientMetadata.application_typeis not set:nativefor loopback hosts and custom schemes, otherwiseweb(#10493)
[1.0.3] - 2026-10-05
[1.0.2] - 2026-10-04
[1.0.1] - 2026-10-03
Breaking Changes
OAuthClientProvider.clientMetadataUrlis replaced byclientMetadataDocument(metadata), which returns the document URL and its redirect URI per authorization server, orundefinedto register dynamically. It is called whenever no client information is stored, also when the server does not advertise support, and the document is no longer stored as client information (#10302)
Added
McpOAuthProviderOptions.clientMetadataDocument,OAuthCallbackServerOptions.extraPaths, and apathargument forOAuthCallbackServer.waitForCallbackthat rejects responses on other paths (#10302)
[1.0.0] - 2026-10-01
Added
- Added an
authorizationServerMetadataUrloption toauthorizeMcp()to use a configured authorization server metadata document instead of discovery (#10172). - Added an
issoption toauthorizeMcp(). The authorization code is only exchanged whenissnames the flow's authorization server, or is absent and the server's metadata does not setauthorization_response_iss_parameter_supported(RFC 9207). - Added
stepUpScope(), which combines the scopes of aninsufficient_scopechallenge with the scopes granted so far.
Fixed
- Fixed OAuth token and client registration responses with an empty or
nulloptional field (such as"scope": "") failing withInvalid scopeand similar errors; such fields are now treated as absent (#10266). - Fixed
expires_in: nullin a token response marking the access token as already expired. - Fixed invalid URLs in protected resource metadata aborting OAuth discovery instead of falling back to the MCP server's origin.
- Fixed an empty requested scope, from
scope=""in aWWW-Authenticatechallenge or an emptyscopes_supported, overriding the next scope source. - Fixed list pagination failing with a duplicate cursor error when a server ends pagination with
nextCursor: ""ornull. - Fixed step-up authorization in
adaptOAuthProvider()requesting only the scopes of theinsufficient_scopechallenge. The new token lost the scopes granted before, so other requests failed withinsufficient_scopeagain. Tokens now record their granted scope, which is the requested scope when the token response omitsscope.
[0.99.2] - 2026-09-30
Fixed
- Fixed
StreamableHttpTransportfailing every request on Cloudflare Workers withIllegal invocationby callingfetch, includingUnauthorizedContext.fetch, without a receiver (#10188)
[0.99.1] - 2026-09-29
[0.99.0] - 2026-09-29
Added
- Added a standalone MCP client with JSON-RPC lifecycle, tool discovery and calls, cancellation, progress, roots, stdio and Streamable HTTP transports, and an in-memory testing transport.