MCP server in Analytica
| Release: |
• 4.6 • 5.0 • 5.1 • 5.2 • 5.3 • 5.4 • 6.0 • 6.1 • 6.2 • 6.3 • 6.4 • 6.5 • • 6.6 • 7.0 • 7.1 • 7.2 |
|---|
New in Analytica 7.0
- The feature described here is experimental and for the time being intended for Lumina-internal use. As an experimental feature, it is subject to change.
Implementing an MCP server
A Model Context Protocol (MCP) server exposes tools that can be used by an AI agent such as Claude Code and Gemini CLI. It is possible to implement an MCP server directly in an Analytica model using specially tagged UDFs to implement each tool. It is easy to do so, and can enable AI agents to use or control your Analytica model.
At present, this feature has been created and is being used (or use being explored) internally at Lumina in several ways, including:
- For automation of Quality Assurance testing.
- For end-to-end Assista evaluation (especially when Assista takes actions during its response).
- To enable AI coding tools to more actively control Analytica when developing code, debugging, reproducing UI bugs, etc.
- To interactively use desktop Analytica in coordination with Claude Code, especially on some cases where Claude has access to tools that Assista does not.
The current feature implementation has distinct limitations, and is likely to change as we gain more internal experience with coordinating AI agents and desktop Analytica.
Creating an MCP server
To put desktop Analytica into an MCP-serving mode, you need to launch it with the command line parameter:
Analytica.exe /mcp:«port»
such as
Analytica.exe /mcp:6541
To implement a tool that an AI agent can use, create a User-Defined Function with a description that guides a language model as to when and how to use the tool, and then include the following text somewhere within the description: {@mcpTool}. We usually place this at the very beginning or very end of the description. This tag labels the UDF as an MCP tool.
When you declare parameters, you must declare the data type of each parameter as either Number or Text. The atom qualifier is also recommended but not required. Parameters can be optional and can include default values. At this time, no parameter can be declared as an array, index, object (or other non-evaluated eval mode), or repeated parameter. These may be relaxed later as the implementation becomes more complete.
If your UDF makes use of parameter qualifiers that are not yet supported, it will not be included in the tool/list result.
Configuring the client
To configure the client to use your server, your Analytica process must already be running with your UDFs existing.
Configure the client using a Transport type of "Streamable HTTP" and a URL of "http://localhost:6541/mcp", where the port number matches the port you used for the /mcp:6541 parameter when you launched Analytica.exe.
A convenient testing client is the MCP Inspector which can be run in an installation-free mode. You do have to already have Node.js installed, and then from a command line just run:
npx @modelcontextprotocol/inspector
The testing client UI opens in a browser. After you connect, you should see your exposed UDFs after pressing List tools.
To use your server from Claude Code running on the same computer:
claude mcp add --transport http anamcp http://127.0.0.1:6541/mcp
Remote access and authentication
Some AI platforms connect to MCP servers from the cloud, never from your own computer. In particular, Claude Cowork and all claude.ai custom connectors connect from Anthropic's servers, even when you use the Claude desktop app. To let such a platform drive the model running in your desktop Analytica session, three pieces are needed: a token so that only you can call your tools, a tunnel so your server is reachable from the internet, and the connector configuration on the platform. Analytica's MCP server continues to listen only on localhost — public reachability and TLS come from the tunnel.
The /mcpToken option
Add /mcpToken:«secret» to the launch line to require authentication:
Analytica.exe /mcp:9000 /mcpToken:«secret» "My model.ana"
You choose the secret, and the secret is the token, verbatim — nothing is generated, and the same launch line accepts the same token forever. Pick a long random one, like a password. It must be:
- at least 16 characters long, and
- use only letters, digits, hyphen (
-) and underscore (_) — it has to be safe to embed in a URL path.
A value that violates these constraints shows a warning at startup and the MCP server is not started.
When a token is configured, every request must present it in one of two ways:
- In the URL path (a capability URL) —
http://127.0.0.1:9000/mcp/«secret». This form works with every client, including claude.ai custom connectors, which have no field for custom headers. - As a bearer header —
Authorization: Bearer «secret»on/mcp, for clients that support headers, such as Claude Code.
Requests with a missing or wrong token are rejected (HTTP 401) before anything is parsed or evaluated.
Without /mcpToken, behavior is exactly as before — unauthenticated, for clients on the same computer. As a guardrail, an unauthenticated server refuses (HTTP 403) any request whose Host header names some other machine, i.e. one that arrived through a tunnel or proxy, so you cannot accidentally publish an open endpoint.
Making the server reachable: a tunnel
Run a tunnel agent beside Analytica. It gives you a public https:// hostname, terminates TLS, and forwards to localhost.
For a quick test, cloudflared needs no account:
cloudflared tunnel --url http://localhost:9000
It prints a https://«random-words».trycloudflare.com URL. Note that this hostname changes every run, so it is only suitable for experimenting.
For a permanent setup you want a stable hostname, so the connector is configured once. The simplest option is an ngrok free account, which lets you claim one static domain:
ngrok http --url=«name».ngrok-free.app 9000
Alternatives: a Cloudflare named tunnel (free, but requires owning a domain managed by Cloudflare), or Tailscale Funnel (stable machine hostname, but adds tailnet concepts).
Connecting from claude.ai / Cowork
In claude.ai go to Settings → Connectors → Add custom connector and enter the capability URL:
https://«host»/mcp/«secret»
Leave the OAuth fields empty. The connector lists your tagged UDFs as tools, and you can then use them from a Cowork session or a chat. Calls are evaluated in your running desktop Analytica session, against the live state of your model. If a tool's evaluation raises an Analytica error, the agent receives the full error message and can react to it.
Connecting from Claude Code (remote)
From a different machine, Claude Code uses the bearer-header form:
claude mcp add --transport http anamcp https://«host»/mcp --header "Authorization: Bearer «secret»"
(The capability URL works from Claude Code too.)
Starting everything with one command
A two-line .cmd file starts Analytica and the tunnel together:
start "" "C:\Program Files\Lumina\Analytica 7.2\Analytica.exe" /Automation /mcp:9000 /mcpToken:«secret» "C:\My Models\My model.ana"ngrok http --url=«name».ngrok-free.app 9000
Security notes
- Once tunneled, a tool call is internet-triggered evaluation inside your desktop session. The token is the only thing standing between the internet and your tools — never run a tunnel without
/mcpToken. (The Host-header guardrail refuses tunneled requests when no token is set, but do not rely on it as your only protection.) - Only expose tools you are comfortable having called by whoever holds the URL. Anyone with the capability URL can call them.
- To rotate the token: edit the launch line, restart Analytica, and update the connector URL (or header) on the client side. The old token stops working immediately.
- The token is visible in the process command line to other software on your own computer, and a capability URL can appear in intermediary logs. This is an accepted trade-off of the single-user desktop threat model; rotate the token if in doubt.
- TLS is provided end-to-end by the tunnel; the hop from the tunnel agent to Analytica stays on 127.0.0.1.
Troubleshooting
- claude.ai says "Couldn't register with …'s sign-in service" when adding the connector: the connector received a 401, which claude.ai interprets as an OAuth server. Check that the URL you entered embeds the server's current token (if you rotated the token, the URL must change too), and that Analytica was really started with
/mcpToken. - Everything returns 401: wrong or missing token — compare the URL/header against the
/mcpToken:value in the launch line, character for character. - A second Analytica instance on the same port: only the first instance to bind the port serves it; a second instance launched with the same
/mcp:«port»currently fails to start its server silently while the first keeps answering. If test results look like they come from the wrong instance, check which process owns the port (Get-NetTCPConnection -LocalPort 9000 -State Listenin PowerShell). - Startup warning about /mcpToken: the token violates the length/character constraints above; the server was not started. Fix the token and relaunch.
- The tunnel URL answers but nothing works: make sure the tunnel forwards to the same port as
/mcp:«port», and that the Analytica instance is still running.
Keeping dialogs from blocking the agent
A modal dialog is invisible to an AI agent: if Analytica poses one while serving a tool call, the call simply never returns and the agent cannot tell a blocked process from a slow one. Launch Analytica with the /Automation option alongside /mcp: so that every blocking dialog is answered automatically and the session keeps running:
Analytica.exe /Automation /mcp:6541 MyModel.ana
A model or library can also register a handler with RegisterAutomationModalHandler to decide the answers itself, and to record each dialog so that an {@mcpTool} UDF can report back to the agent what Analytica asked while a tool call ran. See Analytica Command Line/Automation.
Limitations
There are currently many limitations. These contribute to the experimental status of the feature. These may be progressively relaxed in the future.
- Not namespace aware - make sure your tools are in scope from the main model and names not ambiguous.
- Only a subset of Function Parameter Qualifiers currently supported:
- Only Number and Text parameters
- Array parameters, index parameters, and other evaluation models other than Context are not supported.
- Repeated parameters not supported.
- No array abstraction on calls.
- Prior to Analytica 7.2, can only be used by AI agents running on localhost. In 7.2, remote agents are supported — see Remote access and authentication above.
- Does not proactively push notification to clients when changes to the
tools/listoccur. (But you can interactively debug and refine your tools, you clients just need to re-read the tool list. Claude Code needs to be restarted to have in reread). - Prior to Analytica 7.2, there is no authentication on the connection: once your server is running, any process on localhost could potentially connect and call your tools. In 7.2, use
/mcpTokento require a token on every request. - If a UDF with the
{@mcpTool}tag uses parameter qualifiers that aren't yet supported, it is quietly excluded from the tool list, but it does not report this to you, nor does it report what qualifier is not supported.