Repository navigation
Conversation
…epository The wolframcloud.com outage exposed two problems. A Throw with a tag nothing in the paclet catches (the network-failure tag CloudObject throws when the cloud is unreachable, raised by Chatbook's documentation search) unwound through the whole local server, ending its read loop and thus the server process, so a single WolframLanguageContext call disconnected the client. And the SymbolDefinition tool printed Missing[NotAvailable][...] for every definition, because its ReadableForm import failed in the sandbox kernel and the failure was memoized. Server: - Add catchUncaughtThrows, an exception boundary for foreign Throw tags, tagless Throw and Abort, and use it around tool evaluation (the exception becomes the tool's error result, with AgentTools::CloudUnavailable for the cloud tag), around handleMethod in both transports (JSON-RPC internal error), and around tool warmup in the local read loop. - Replace a response that cannot be serialized as JSON with an internal error response instead of ending the server. - Render Failure messages in tool results as plain text instead of box syntax. - Report failures of Chatbook's documentation and Wolfram|Alpha searches with a clear message instead of an opaque internal failure. Resource functions: - Add ResourceFunctions/ with local copies of the Function Repository functions the paclet uses, each wrapped in its own context. importResourceFunction now prefers a local copy (inlining it in MX builds, loading it at first use from source), memoizes only successful imports, and gives a placeholder that fails with AgentTools::ResourceFunctionUnavailable otherwise. BuildMX.wls copies the directory into the build copy and uses the local ASTPattern. - The SymbolDefinition tool falls back to InputForm when ReadableForm is not available. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fx1TKznVhzxdCujbMybQF5
Contributor
There was a problem hiding this comment.
🔵 Needs a closer look
It changes core server execution boundaries and offline build mechanics across multiple critical paths, so it warrants final human review despite strong targeted tests.
Pull request overview
This PR hardens the local/cloud MCP server against cloud outages and makes the paclet buildable offline by eliminating build-time dependency on the Wolfram Function Repository, while preserving existing behavior where possible.
Changes:
- Added a server-wide exception boundary (
catchUncaughtThrows) so foreignThrowtags, taglessThrow,Abort[], and JSON serialization failures no longer terminate the server process. - Implemented offline-capable resource-function importing via a new
ResourceFunctions/directory and updatedimportResourceFunctionto prefer local copies (with retry-on-failure behavior when offline). - Added focused test coverage for both the new exception boundary semantics and the resource-function import/fallback paths.
File summaries
| File | Description |
|---|---|
| Tests/ServerErrorHandling.wlt | New tests for uncaught-throw boundaries, cloud-unavailable tagging, failure text rendering, and JSON serialization fallback behavior. |
| Tests/ResourceFunctions.wlt | New tests ensuring local resource-function copies exist/are wrapped, import resolution works, and fallback behavior is correct when unavailable. |
| Scripts/BuildMX.wls | Copies ResourceFunctions/ into the temp build tree and prefers the local ASTPattern to enable offline MX builds. |
| ResourceFunctions/ASTPattern.wl | Local, packaged copy of the pinned Function Repository definition. |
| ResourceFunctions/ExportMarkdownString.wl | Local, packaged copy of the pinned Function Repository definition. |
| ResourceFunctions/ImportMarkdownString.wl | Local, packaged copy of the pinned Function Repository definition. |
| ResourceFunctions/MessageFailure.wl | Local, packaged copy of the pinned Function Repository definition. |
| ResourceFunctions/ReadableForm.wl | Local, packaged copy of the pinned Function Repository definition. |
| ResourceFunctions/ResourceFunctionMessage.wl | Local, packaged copy of the pinned dependency needed by MessageFailure. |
| ResourceFunctions/README.md | Documents provenance, update workflow, and how offline builds/source loads work with local copies. |
| Kernel/Common.wl | Refactors importResourceFunction to prefer local copies; adds placeholder + retry semantics for unavailable functions; adds dependency-inlining controls. |
| Kernel/CommonSymbols.wl | Exports resourceFunctionAvailableQ for cross-file use. |
| Kernel/Messages.wl | Adds user-facing failure messages for cloud-unavailable tools/searches and uncaught exceptions/aborts. |
| Kernel/Server/Shared.wl | Adds catchUncaughtThrows, request/tool throw handlers, and improves Failure message-to-text rendering to avoid box syntax. |
| Kernel/Server/Server.wl | Exposes new server symbols used by both transports. |
| Kernel/Server/Local.wl | Wraps request handling and warmup in catchUncaughtThrows; adds safe response serialization fallback. |
| Kernel/Server/Cloud.wl | Wraps request handling (including notifications) in catchUncaughtThrows to prevent unwinding in cloud transport too. |
| Kernel/Tools/Context.wl | Converts Chatbook failures into specific, user-facing tool failures for documentation and Wolfram |
| Kernel/Tools/SymbolDefinition.wl | Avoids memoizing ReadableForm failures by returning $Failed and falling back to InputForm formatting. |
| docs/error-handling.md | Documents catchUncaughtThrows and its required placement/usage. |
| docs/building.md | Documents offline builds and how local resource-function copies are used. |
| AGENTS.md | Updates repo architecture documentation to include ResourceFunctions/ and its role. |
Review details
- Files reviewed: 22/22 changed files
- Comments generated: 0
- Review effort level: Lite
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The wolframcloud.com outage exposed two problems in the local MCP server, and it also means the Function Repository is unavailable at build time. This PR makes the paclet fail gracefully without cloud access and makes it buildable without the Function Repository.
What went wrong during the outage
WolframLanguageContextcall ended the server process. Chatbook's documentation search raisedThrow[$Failed, CloudObjectPrivateNetworkCallFailure]; nothing in the paclet catches that tag, so the throw unwound through the read loop, the script ended with exit code 0, and the client saw "Connection closed".SymbolDefinitionprintedMissing[NotAvailable][Unevaluated[...]]for every definition: theReadableFormimport failed in the protected-mode sandbox kernel (which cannot see the local resource cache) and the failure was memoized for the life of the server.Server
catchUncaughtThrows(Kernel/Server/Shared.wl) is an exception boundary for foreignThrowtags, taglessThrow, andAbort. It wraps tool evaluation (the exception becomes the tool's error result, withAgentTools::CloudUnavailablefor the cloud network-failure tag),handleMethodin both transports (JSON-RPC internal error), and tool warmup in the local read loop.Failuremessages in tool results are rendered as plain text; theFailure["Message"]property wraps parameters inShortboxes, which came out as box syntax.AgentTools::DocumentationSearchFailed/AgentTools::WolframAlphaSearchFailedinstead of an opaque internal failure.Resource functions
ResourceFunctions/directory (not declared inPacletInfo.wl, so not part of the built paclet) with a local copy of each Function Repository function the paclet uses, each wrapped inBeginPackage/EndPackagefor its own context.importResourceFunctionprefers a local copy: in MX builds it is inlined exactly like a fetched definition; from source it is loaded at first use. Imports are memoized only on success; otherwise the symbol becomes a placeholder that fails withAgentTools::ResourceFunctionUnavailableand the import is retried next time.Scripts/BuildMX.wlscopies the directory into the temporary build copy and uses the localASTPatternfor its source annotations.SymbolDefinitiontool falls back toInputFormformatting whenReadableFormis not available.Provenance of the local copies (see
ResourceFunctions/README.md)ImportMarkdownString,MessageFailure,ReadableForm: verbatim copies from rhennigan/ResourceFunctions (commit 08ee812); verified identical to the published, pinned versions.ASTPattern,ExportMarkdownString: the repository's development versions are newer than the published 1.0.0 versions, so these were generated from the published definitions (from the local resource cache) to keep behavior identical to current releases.ResourceFunctionMessage(a dependency ofMessageFailure, not in the repository) was generated the same way. These three are stored as definition-list assignments because re-evaluatingf[ args___ ] := ...next to itse: HoldPattern[ f[ ___ ] ] := ...fallthrough merges the two rules.Test plan
Tests/ServerErrorHandling.wlt:catchUncaughtThrowssemantics (normal, tagged, tagless, abort, inner catch, paclet failures unaffected),tools/callwith throwing/aborting tools including the cloud tag, plain failure text, response serialization fallback, context-tool failures.Tests/ResourceFunctions.wlt: local copies exist and are wrapped, imports resolve to the local context, functional smoke tests of every copy, unavailable-placeholder behavior (failure, not memoized), SymbolDefinition fallback.Tools.wlt, resource-object lookups inCreateMCPServer.wlt, search prompts inPrompts.wlt, the usage endpoint inUsageData.wlt); every other file passes.CloudDeployment.wltwas skipped (deploys to the real cloud).WolframLanguageContextnow returns[Error] Documentation search is currently unavailable (...)and the server keeps serving subsequent requests;SymbolDefinitionoutput is correct again.Scripts/BuildMX.wlsandScripts/BuildPaclet.wls --check=falsesucceed offline (the definition-notebook check fails offline on the cloud-dependentPublisherUpdateNotAllowedhint; the CodeInspector is clean on all changed files).🤖 Generated with Claude Code
https://claude.ai/code/session_01Fx1TKznVhzxdCujbMybQF5