Categories &

Functions List

Function Reference: devtools.mcp

devtools: devtools.mcp ()

Serve the Model Context Protocol on standard input and output.

devtools.mcp () reads newline-delimited JSON-RPC messages from standard input, answers each one, writes the answer to standard output, and returns only when standard input reaches end of file. It is the entry point a host launches; it is not meant to be called at an interactive prompt, where it would take the terminal.

Both protocol eras are served. A client that opens with per-request metadata is answered under revision 2026-07-28 and statelessly; a client that opens with an initialize handshake is answered under revision 2025-11-25 for the life of the process. The choice is made by the first request and the tools are the same in either case.

The read-only tool set is served here. This server evaluates no code, runs no user function, and writes nothing, which is the property that lets a user grant it blanket permission. Evaluation lives behind a separate entry point and a separate configuration entry, so that it cannot be reached by a host configured for this one.

Configure a host to launch it with:

 
 octave-cli -q --no-init-file --eval "pkg load devtools; devtools.mcp ()"

Do not shorten that command. --no-init-file is the load-bearing flag: it skips ~/.octaverc, whose output would arrive before this function exists, and a single byte written there corrupts the stream for the whole session. Measured on 11.2.0, --eval already makes the run non-interactive so that no banner is written either way and -q changes nothing today; it is kept because nothing else guards that output if a future release prints one. Use devtools.selftest to check a configuration before suspecting the host.

On Windows, name octave-cli.exe in full. A host spawns the command with no shell, so a bare octave-cli resolves only where the interpreter is already on PATH, which a Windows installation does not guarantee and a configuration file cannot arrange. Where it is not, the process never starts and writes nothing at all, which reads exactly like the corrupted stream above and is nothing to do with it.

This server sees the packages its own launch command loads, and no others. The command above loads only devtools, so octave_which will not find a function from statistics unless it is named:

 
 --eval "pkg load devtools statistics datatypes; devtools.mcp ()"

Loading every installed package instead would run each one’s PKG_ADD, which is other people’s code executing at startup, and this server’s whole claim is that it runs none.

Tools

Five tools are served, all of them read-only:

octave_which
where a name resolves, its kind, its owning package, what it shadows, and whether it is installed rather than loaded.
octave_help
the help text for a function, class, method or operator, answered from the documentation caches where one holds the entry, so that a function in an installed package this server has not loaded is answered too.
octave_search
which functions match a description, when the name is not known.
octave_pkg
which packages are installed, at which versions, and which are loaded.
octave_registry
which packages anywhere in the Octave Packages index provide a name, from a dated snapshot carried in this package.

One resource is offered, octave://environment: version, platform, load path size and the packages this server loaded. The version and the platform are also stated in the server’s instructions, sent once when a client connects, so that no request pays for them.

Everything diagnostic goes to standard error, which the protocol reserves for exactly that purpose and which a client may capture, forward or ignore.

One deviation is worth stating. This loop reads, answers and writes in one thread, so a notifications/cancelled arriving for a request already being answered cannot be seen until that answer has been written. The protocol asks that no further message be sent for a cancelled request and this implementation cannot honour it. The tools served here return in milliseconds, so the window is small, but it is real.

See also: devtools.mcpEval, devtools.selftest

Source Code: devtools.mcp