wxMaxima
Loading...
Searching...
No Matches
Public Member Functions | Static Public Attributes
McpTools Class Reference

Implements the read-only "worksheet context" tools the MCP server exposes to an external AI tool (GH request: "a de facto standard [MCP] AI sidebar that ... gives it access to a worksheet"). More...

#include <McpTools.h>

Public Member Functions

 McpTools (Worksheet *worksheet, Variablespane *variablesPane)
 
void SetConnectionCheck (std::function< bool()> isConnected)
 Lets the owner (McpServer, wired up from wxMaxima – see McpServer::SetConnectionCheck()) plug in a live "is the Maxima process actually connected right now" query.
 
void SetSidebarAccess (std::function< std::vector< McpSidebarInfo >()> list, std::function< bool(const wxString &, bool)> setVisible)
 Lets the owner plug in access to wxMaximaFrame's dockable sidebars, for the same reason SetConnectionCheck() exists: which panes there are and whether each is shown lives on wxMaximaFrame, which a Worksheet or Variablespane pointer cannot reach.
 
nlohmann::json ListTools () const
 The tools/list result: name/description/inputSchema for every tool below.
 
nlohmann::json CallTool (const wxString &name, const nlohmann::json &arguments) const
 Dispatches one tools/call request by tool name. Throws McpToolError.
 
nlohmann::json ListCells () const
 
nlohmann::json ReadCell (const nlohmann::json &arguments) const
 
nlohmann::json ReadWorksheet () const
 
nlohmann::json ReadToc () const
 
nlohmann::json ReadSection (const nlohmann::json &arguments) const
 
nlohmann::json ReadVariables () const
 
nlohmann::json EvaluationStatus () const
 Is Maxima actively evaluating a command right now, and if so: which cell, which exact statement within that (possibly multi-statement) cell, and how long has that specific statement been running? Raised by the maintainer directly: "A way to query if Maxima is evaluating, what cell it works on, what command within that cell and for how long this command already is being evaluated.".
 
nlohmann::json WatchVariable (const nlohmann::json &arguments) const
 
nlohmann::json UnwatchVariable (const nlohmann::json &arguments) const
 
nlohmann::json SearchCells (const nlohmann::json &arguments) const
 Finds every cell whose input and/or output contains pattern (a plain substring by default, or a regular expression with "regex":true), so an AI can jump straight to the relevant cell(s) of a large worksheet instead of reading everything via read_worksheet/list_cells. Read-only, same as every other tool here – it never touches worksheet content.
 
nlohmann::json ListSidebars () const
 Which dockable sidebars exist and which are visible right now.
 
nlohmann::json ShowSidebar (const nlohmann::json &arguments) const
 Show a sidebar, the same as ticking its View -> Sidebars menu entry.
 
nlohmann::json HideSidebar (const nlohmann::json &arguments) const
 Hide a sidebar. See ShowSidebar() for why this counts as a safe write. Refuses to hide the worksheet itself – see McpSidebarInfo::canHide.
 

Static Public Attributes

static constexpr std::size_t MAX_TEXT_LENGTH = 200000
 A cap on how much text a single response ever carries (read_worksheet/ read_section), so a huge worksheet can't produce an unbounded reply.
 
static constexpr std::size_t MAX_SEARCH_MATCHES = 50
 search_cells stops collecting further matches once it hits this many, reporting "truncated" instead – a pathological pattern matching most of a huge worksheet must not turn into an unbounded response either.
 
static constexpr std::size_t OUTPUT_PREVIEW_LENGTH = 2000
 The cap applied to each individual cell's own output when it's one of many being concatenated (ReadWorksheet/ReadSection) – keeps one cell with a huge output (a large matrix, a long list, ...) from crowding out every other cell's info in the same response. read_cell, which targets exactly one cell the caller already chose, is not limited to this – see its output_length/output_from_end arguments.
 

Detailed Description

Implements the read-only "worksheet context" tools the MCP server exposes to an external AI tool (GH request: "a de facto standard [MCP] AI sidebar that ... gives it access to a worksheet").

Every tool here only reads the worksheet, with two narrow exceptions that the maintainer explicitly scoped in as safe: watch_variable/unwatch_variable only change what the Variables sidebar happens to be tracking for display, the same as a user typing a name into that sidebar by hand – they never touch worksheet content, insert/edit/evaluate anything, or have any side effect Maxima itself would notice beyond the pre-existing "query this variable's value" flow the sidebar already triggers on its own schedule. Every other tool cannot mutate anything even in principle: turning a worksheet or a cell into text is all they do. This split is deliberate product scope (confirmed with the maintainer), not an oversight – a write-capable "insert/edit/evaluate" tool surface is a different, far higher-stakes feature this first pass does not implement.

Deliberately free of any networking/JSON-RPC framing (that's McpServer's job) so this can be unit-tested directly against a real, headless Worksheet/Variablespane – see test/unit_tests/test_McpTools.cpp.

Thread safety: none of this is thread-safe, same as every other class that touches a Worksheet/GroupCell/Variablespane. McpServer only ever calls into this from the GUI thread's own event loop (its wxSocketServer runs event-driven on that thread, not on a worker thread), so no locking is needed here – keep it that way if McpServer's transport ever changes.

Member Function Documentation

◆ ListSidebars()

json McpTools::ListSidebars ( ) const

Which dockable sidebars exist and which are visible right now.

Requested by the maintainer alongside show_sidebar/hide_sidebar. Purely a read, like every tool above it: it reports what the window currently looks like and changes nothing.

◆ SetConnectionCheck()

void McpTools::SetConnectionCheck ( std::function< bool()>  isConnected)
inline

Lets the owner (McpServer, wired up from wxMaxima – see McpServer::SetConnectionCheck()) plug in a live "is the Maxima process actually connected right now" query.

McpTools has no way to know this on its own: that state lives on Maxima/MaximaProcessManager, owned by wxMaxima, which a Worksheet/Variablespane pointer alone can't reach – see IsMaximaConnected()'s own comment for why this matters. Left unset (as every existing test in test_McpTools.cpp does, with no live Maxima to ask about) means "assume connected"; only production wiring should ever pass a real check.

◆ SetSidebarAccess()

void McpTools::SetSidebarAccess ( std::function< std::vector< McpSidebarInfo >()>  list,
std::function< bool(const wxString &, bool)>  setVisible 
)
inline

Lets the owner plug in access to wxMaximaFrame's dockable sidebars, for the same reason SetConnectionCheck() exists: which panes there are and whether each is shown lives on wxMaximaFrame, which a Worksheet or Variablespane pointer cannot reach.

Both halves are set together on purpose. A build that could enumerate sidebars but not toggle them (or the reverse) would advertise tools that are only half-functional, and nothing at the tool layer could tell that apart from a genuine failure. Left unset – which is the default, and what every test that doesn't care about sidebars does – all three sidebar tools throw McpToolError saying so, rather than silently reporting an empty list that reads like "this wxMaxima has no sidebars."

◆ ShowSidebar()

json McpTools::ShowSidebar ( const nlohmann::json &  arguments) const

Show a sidebar, the same as ticking its View -> Sidebars menu entry.

This is a write, and only the third one here (after watch_variable/ unwatch_variable). It is in the same category as those two rather than in the category the "no write/evaluate tools" rule exists to keep out: it changes which of wxMaxima's own panes are on screen and nothing else. It cannot touch worksheet content, cannot insert or edit a cell, and cannot cause Maxima to evaluate anything – the blast radius is exactly "the window looks different," which the user can undo with one click and can see has happened.


The documentation for this class was generated from the following files: