Skip to main content
Glama
circuitmeridian

Velocitron Simulator MCP Server

Velocitron browser simulator

The standalone simulator edits, compiles, lays out, and structurally explores .petrinet source in the browser. Its Node process serves the built application, provides bounded Graphviz layout, and—when explicitly enabled—hosts a local MCP endpoint that lets an agent inspect and replace the source open in a live browser page.

The source-control design extends ADR 0021 without moving its seams: the browser remains the source, compiler, diagnostic, revision, and simulation authority. See ADR 0022 for the live-source-control decision.

When started with a workspace root, the server additionally exposes that directory's .petrinet files to the page as opaque bytes — listing, reading, saving, and watching them — while the browser keeps all interpretation, including multi-file composition simulation. See ADR 0024 and File-backed workspace mode below.

Status: 0.1.0 alpha

This 0.1.0 alpha is a serious working release for technical exploration, not a compatibility or production-readiness promise. The application, its APIs, its MCP surface, and its behavior may change without notice. There is no migration, maintenance, support-response, or security-support guarantee.

Do not use the simulator for production, security-sensitive, or otherwise high-consequence workloads. Support is best-effort only.

The simulator consumes the released @velocitron/core npm package, pinned to the exact version 0.1.0. The pin is bumped explicitly per core release; compatibility across other core versions is not promised.

Requirements

  • Node.js 20.19.0 or newer (repository development uses Node 24.15.0 or newer and pnpm 11.13.1).

  • pnpm (via corepack enable; the repository pins pnpm@11.13.1).

  • Graphviz dot, exactly version 15.1.0, on PATH for production layout and the server test suite. The server refuses other Graphviz versions rather than producing unverified geometry; see ADR 0021. MCP source control does not invoke Graphviz or add any other compiler/runtime requirement to Node.

Install the dependencies from the repository root:

corepack enable
pnpm install

Run the simulator

Development

Without MCP source control:

pnpm run dev

Vite prints the browser URL. The simulator compiles source in the browser; the development server supplies the existing layout route.

To enable live source control, set a bearer token before starting the same development command:

VELOCITRON_MCP_TOKEN='replace-with-a-long-random-token' \
  pnpm run dev

Use the loopback URL printed by Vite and append /mcp for the MCP server URL. The live-source routes are disabled when VELOCITRON_MCP_TOKEN is absent; the ordinary browser simulator and layout route continue to work.

Production

Start the production server with MCP source control enabled (run start builds the browser bundle and the Node server first, so it always serves the current sources; run start:prebuilt skips the build and serves the existing dist/):

VELOCITRON_MCP_TOKEN='replace-with-a-long-random-token' \
  pnpm run start

To open a directory of .petrinet files instead of the single hash-persisted editor, pass a workspace root as the first argument (or set VELOCITRON_WORKSPACE, which is also how run dev enables it under Vite):

pnpm run start ./tests/browser/fixtures/workspace

The default application URL is http://127.0.0.1:4173, and the default MCP URL is therefore:

http://127.0.0.1:4173/mcp

PORT may select another port. The MCP-enabled server must remain on a loopback address; do not expose it through HOST=0.0.0.0, a reverse proxy, a tunnel, or a container-published network port. Plain HTTP is acceptable only on loopback.

Connect an MCP client

The server uses Streamable HTTP from @modelcontextprotocol/sdk 1.29.0. It is not a stdio server: configure a URL and an HTTP Authorization header rather than a command to launch.

MCP client configuration formats differ, but the equivalent generic settings are:

{
  "mcpServers": {
    "velocitron-simulator": {
      "url": "http://127.0.0.1:4173/mcp",
      "headers": {
        "Authorization": "Bearer <the VELOCITRON_MCP_TOKEN value>"
      }
    }
  }
}

Some clients call the transport http or streamable-http; some substitute environment variables in header values. In all clients, the load-bearing settings are:

  • Streamable HTTP, not the deprecated HTTP+SSE transport;

  • the exact /mcp URL on the simulator's loopback origin; and

  • Authorization: Bearer ... with the same value passed as VELOCITRON_MCP_TOKEN at server startup.

The v1 transport is stateless. Successful POST operations use the stable SDK's per-request SSE response framing so a disconnected client cancels pending work; this is not a subscription channel. The server does not return or require an MCP Mcp-Session-Id, does not provide resumable streams, and returns HTTP 405 for an unsolicited MCP GET because subscriptions and server-initiated notifications are not implemented. Simulator page identity is instead an explicit tool or resource argument, described below.

VELOCITRON_MCP_TOKEN must be strict UTF-8 and at least 32 bytes; an invalid configured value fails server startup rather than silently disabling MCP. A missing or incorrect request bearer token is an authentication failure. Treat the token as a secret: do not commit it, put it in a share URL, paste it into source, or enable HTTP debug logging that records request headers.

Browser authority and the Node mirror

Each open simulator page generates an opaque sessionId. It is a page-lifetime identifier, not a path, project ID, durable session, or MCP transport session. The browser owns:

  • the exact editor source;

  • browser-local .petrinet compilation and canonical diagnostics;

  • source revision installation;

  • the current contribution state and retained last-valid snapshot; and

  • marking, history, structural firing, rewind, and view state.

Node keeps only an ephemeral in-memory mirror so the page and MCP clients can rendezvous. The mirror is keyed by sessionId, disappears when the server restarts or the page expires, and never reads or writes a .petrinet file. It does not discover projects, call compilePetrinetText, validate DSL, create PN diagnostics, lay out MCP source, or run simulation.

The browser talks to that mirror through a private application long-poll bridge:

  • GET /api/source-control/config discovers whether source control is enabled;

  • POST /api/source-control/poll publishes the page's current snapshot and waits for a pending refresh or complete-source replacement command; and

  • POST /api/source-control/disconnect removes the ephemeral page session on unmount or page close, with idle expiry as a fallback.

Those routes are internal browser/server protocol. They are not MCP resources, tools, or client APIs. Generic MCP clients connect only to /mcp.

Version model

Every accepted source has one complete version identity:

{
  "sessionId": "0e6337b2-e69d-4db0-bf49-c26c74b5409d",
  "revision": 12,
  "sha256": "lowercase SHA-256 of the exact UTF-8 source bytes"
}
  • sessionId prevents using a version from one page against another page.

  • revision increases monotonically within that page lifetime.

  • sha256 binds the version to the exact source bytes, including whitespace, line endings, and Unicode.

Do not treat revision alone as a write precondition and do not normalize source before hashing or replacing it.

MCP resource

Each live page exposes its exact source text at:

velocitron://simulator/{sessionId}/source

The resource MIME type is text/plain; charset=utf-8, and its content is source text only. Use list_simulator_sessions to discover page IDs and read_petrinet_source when an agent also needs the complete version token, source ID, UTF-8 byte count, and browser build status. A session may disappear between listing and reading; list again rather than assuming durable recovery.

The build status is independent of replacement acceptance. Expected states include idle, compiling, awaiting-geometry, invalid, operation-failed, and ready. A status other than ready does not make the source unreadable.

MCP tools

The approved v1 tool surface is deliberately small:

list_simulator_sessions

Lists live-page summaries with source ID, UTF-8 byte count, build status, and complete version. It has no input fields.

read_petrinet_source

Reads one exact current source snapshot.

{
  "sessionId": "opaque page session id"
}

Read this immediately before calculating a replacement. Preserve the returned source exactly unless the intended edit changes it.

replace_petrinet_source

Attempts a complete-source optimistic replacement.

{
  "sessionId": "opaque page session id",
  "expectedVersion": {
    "sessionId": "the same page session id",
    "revision": 12,
    "sha256": "the hash returned by the read"
  },
  "source": "the complete desired .petrinet source"
}

This is replace-if-current, not patch, edit-range, append, merge, or save. All three fields of expectedVersion must match before the command is queued and again before it is delivered. The browser applies the exact replacement text and allocates the next revision; Node hashes the exact published source and returns the resulting complete version after browser acknowledgement. The result status is applied when a new revision was created and unchanged when the submitted source already matched exactly. The server never infers a merge and never silently overwrites a newer editor revision.

MCP clients may use either the resources or the corresponding read tools. Use the typed tools when an agent needs an explicit read-before-write flow; use resources when the client naturally browses contextual state.

Compile success is separate from replacement acceptance

A successful replace_petrinet_source call means only:

  1. the complete expected version matched; and

  2. the replacement was accepted as the page's exact current source.

It does not mean that the source compiles, describes a standalone net, has valid geometry, or can currently be simulated. The browser applies the source first and runs its normal local compile/layout pipeline afterward. This permits normal multi-step editing through temporarily invalid source.

After replacement, call read_petrinet_source again until its browser build status for the accepted version is no longer pending. If it reports invalid, inspect the browser-owned compiler result, prepare another complete source, and replace against the newest version. The last valid canvas may remain visibly retained in the browser, but it is not the current source and MCP never reports it as such.

Conflict recovery

A person may edit the page, or another MCP client may replace it, after a client reads. In that case replace_petrinet_source returns a conflict and the current version. Recover without blind retry:

  1. Call read_petrinet_source again.

  2. Compare the newly returned complete source with the source previously read.

  3. Reconcile the intended change into the new complete document.

  4. Retry replace_petrinet_source with the new complete expectedVersion.

Do not resend the old expected version, drop the hash, or submit only the changed fragment. If the page session no longer exists, list sessions and ask the user which live page to target; a new page has a different sessionId even if it opens identical source.

File-backed workspace mode

Starting the server with a workspace root (CLI argument or VELOCITRON_WORKSPACE) enables workspace mode; without one the mode is entirely absent and the simulator behaves as described above. The design is recorded in ADR 0024.

In workspace mode the page shows a flat file list of every *.petrinet file under the root (recursive; files in subdirectories display their root-relative path; dot-entries, node_modules, and symlinks are skipped). Selecting a file loads it into the editor and simulator. Edits autosave the complete file after a short debounce. External filesystem changes — created, modified, and deleted files — are reflected live: the list updates, an externally modified open file reloads, and a deleted open file keeps its buffer visible with a notice while autosave stops so the file is not recreated. The app offers no file creation, rename, or delete.

Node's role is bytes only. The browser bridge under /api/workspace/ (loopback, same-origin, internal application protocol — not MCP) lists, reads, saves, and watches files; Node never compiles, parses, or otherwise interprets their contents. Change detection rescans and diffs content hashes rather than trusting watch events; self-saves are suppressed from the event stream by hash. Concurrent internal and external writes are last-write-wins, accepted for a loopback single-developer tool.

Workspace mode also enables multi-file composition simulation: when the open file compiles to a composition, the browser resolves each use ref source-relative against the workspace, compiles the referenced nets, merges them with the place-fusion engine from spec/composition.md (ported to @velocitron/core), and simulates the merged standalone net. Nested compositions are not supported. Without a workspace root, composition documents remain unsupported exactly as before.

V1 boundaries

The live-source MCP interface controls source text only. V1 intentionally does not provide:

  • stdio transport;

  • resource subscriptions, server-initiated notifications, or SSE replay;

  • filesystem paths, project discovery, opening/saving files, persistence, or git operations;

  • Node-side .petrinet compilation, validation, diagnostics, or retained snapshots;

  • patches, line/range edits, or server-side merging;

  • marking selection, fire/run, rewind, layout, named-view, or other simulation controls;

  • recovery of page sessions after server restart; or

  • remote or multi-user hosting.

Use ordinary repository tools for filesystem work and the browser UI for simulation controls. Adding any of the deferred surfaces requires a separate contract rather than overloading complete-source replacement.

Feedback and contributions

Open an example net or model a small process of your own, then share what feels clear, awkward, missing, or misleading. Send broad reactions through an existing direct channel with the author. Report reproducible defects through GitHub Issues.

External code contributions and pull requests are not accepted yet. These feedback routes do not create a commitment to review, merge, respond, provide support, or maintain compatibility. See CONTRIBUTING.md and SECURITY.md for the current boundaries.

License and authorship

The Velocitron browser simulator is released under the MIT License.

Matthew R. Scott is the sole author and copyright holder. Henrique Bastos is acknowledged for collaboration toward an interoperable Petri-net specification; that acknowledgment does not indicate shared authorship.

-
license - not tested
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
1Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/circuitmeridian/velocitron-simulator'

If you have feedback or need assistance with the MCP directory API, please join our Discord server