A Rust-based Model Context Protocol (MCP) server that exposes a V8 JavaScript runtime as a tool for AI agents like Claude and Cursor. Supports persistent heap snapshots via S3 or local filesystem, and is ready for integration with modern AI development environments. - V8 JavaScript Execution: Run arbitrary JavaScript code in a secure, isolated V8 engine. - TypeScript Support: Run TypeScript code d
Add this skill
npx mdskills install r33drichards/mcp-jsProduction-ready V8 runtime with excellent storage flexibility, transport options, and clustering
A Rust-based Model Context Protocol (MCP) server that exposes a V8 JavaScript runtime as a tool for AI agents like Claude and Cursor. Supports persistent heap snapshots via S3 or local filesystem, and is ready for integration with modern AI development environments.
Install mcp-v8 using the provided install script:
curl -fsSL https://raw.githubusercontent.com/r33drichards/mcp-js/main/install.sh | sudo bash
This will automatically download and install the latest release for your platform to /usr/local/bin/mcp-v8 (you may be prompted for your password).
Advanced users: If you prefer to build from source, see the Build from Source section at the end of this document.
mcp-v8 supports the following command line arguments:
--s3-bucket : Use AWS S3 for heap snapshots. Specify the S3 bucket name. (Conflicts with --stateless)--cache-dir : Local filesystem cache directory for S3 write-through caching. Reduces latency by caching snapshots locally. (Requires --s3-bucket)--directory-path : Use a local directory for heap snapshots. Specify the directory path. (Conflicts with --stateless)--stateless: Run in stateless mode - no heap snapshots are saved or loaded. Each JavaScript execution starts with a fresh V8 isolate. (Conflicts with --s3-bucket and --directory-path)Note: For heap storage, if neither --s3-bucket, --directory-path, nor --stateless is provided, the server defaults to using /tmp/mcp-v8-heaps as the local directory.
--http-port : Enable Streamable HTTP transport (MCP 2025-03-26+) on the specified port. Serves the MCP endpoint at /mcp and a plain API at /api/exec. If not provided, the server uses stdio transport (default). (Conflicts with --sse-port)--sse-port : Enable SSE (Server-Sent Events) transport on the specified port. Exposes /sse for the event stream and /message for client requests. (Conflicts with --http-port)--heap-memory-max : Maximum V8 heap memory per isolate in megabytes (1–64, default: 8).--execution-timeout : Maximum execution timeout in seconds (1–300, default: 30).--max-concurrent-executions : Maximum number of concurrent V8 executions (default: CPU core count). Controls how many JavaScript executions can run in parallel.--session-db-path : Path to the sled database used for session logging (default: /tmp/mcp-v8-sessions). Only applies in stateful mode. (Conflicts with --stateless)These options enable Raft-based clustering for distributed coordination and replicated session logging.
--cluster-port : Port for the Raft cluster HTTP server. Enables cluster mode when set. (Requires --http-port or --sse-port)--node-id : Unique node identifier within the cluster (default: node1).--peers : Comma-separated list of seed peer addresses. Format: id@host:port or host:port. Peers can also join dynamically via POST /raft/join.--join : Join an existing cluster by contacting this seed address (host:port). The node registers itself with the cluster leader.--advertise-addr : Advertise address for this node (host:port). Used for peer discovery and write forwarding. Defaults to :.--heartbeat-interval : Raft heartbeat interval in milliseconds (default: 100).--election-timeout-min : Minimum election timeout in milliseconds (default: 300).--election-timeout-max : Maximum election timeout in milliseconds (default: 500).After installation, you can run the server directly. Choose one of the following options:
# Use S3 for heap storage (recommended for cloud/persistent use)
mcp-v8 --s3-bucket my-bucket-name
# Use local filesystem directory for heap storage (recommended for local development)
mcp-v8 --directory-path /tmp/mcp-v8-heaps
# Use stateless mode - no heap persistence (recommended for one-off computations)
mcp-v8 --stateless
The HTTP transport uses the Streamable HTTP protocol (MCP 2025-03-26+), which supports bidirectional communication over standard HTTP. The MCP endpoint is served at /mcp:
# Start HTTP server on port 8080 with local filesystem storage
mcp-v8 --directory-path /tmp/mcp-v8-heaps --http-port 8080
# Start HTTP server on port 8080 with S3 storage
mcp-v8 --s3-bucket my-bucket-name --http-port 8080
# Start HTTP server on port 8080 in stateless mode
mcp-v8 --stateless --http-port 8080
The HTTP transport also exposes a plain HTTP API at POST /api/exec for direct JavaScript execution without MCP framing.
The HTTP transport is useful for:
Server-Sent Events (SSE) transport for streaming responses:
# Start SSE server on port 8081 with local filesystem storage
mcp-v8 --directory-path /tmp/mcp-v8-heaps --sse-port 8081
# Start SSE server on port 8081 in stateless mode
mcp-v8 --stateless --sse-port 8081
--stateless)Stateless mode runs each JavaScript execution in a fresh V8 isolate without any heap persistence.
Benefits:
Example use case: Simple calculations, data transformations, or any scenario where you don't need to persist state between executions.
Stateful mode persists the V8 heap state between executions using content-addressed storage backed by either S3 or local filesystem.
Each execution returns a heap content hash (a 64-character SHA-256 hex string) that identifies the snapshot. Pass this hash in the next run_js call to resume from that state. Omit heap to start a fresh session.
Benefits:
Example use case: Building a data structure incrementally, maintaining session state, or reusing expensive computations.
You can tag executions with a human-readable session name by passing the session parameter to run_js. When a session name is provided, the server logs each execution (input heap, output heap, code, and timestamp) to an embedded sled database.
Two additional tools are available in stateful mode for browsing session history:
list_sessions — Returns an array of all session names that have been used.list_session_snapshots — Returns the log entries for a given session. Accepts a required session parameter and an optional fields parameter (comma-separated) to select specific fields: index, input_heap, output_heap, code, timestamp.The session database path defaults to /tmp/mcp-v8-sessions and can be overridden with --session-db-path.
Example workflow:
run_js with code: "var x = 1; x;" and session: "my-project" — the execution is logged.heap hash and session: "my-project" in subsequent calls to continue and log the session.list_sessions to see ["my-project"].list_session_snapshots with session: "my-project" to see the full execution history.claude_desktop_config.json:Stateful mode with S3:
{
"mcpServers": {
"js": {
"command": "mcp-v8",
"args": ["--s3-bucket", "my-bucket-name"]
}
}
}
Stateful mode with local filesystem:
{
"mcpServers": {
"js": {
"command": "mcp-v8",
"args": ["--directory-path", "/tmp/mcp-v8-heaps"]
}
}
}
Stateless mode:
{
"mcpServers": {
"js": {
"command": "mcp-v8",
"args": ["--stateless"]
}
}
}
Add the MCP server to Claude Code using the claude mcp add command:
Stdio transport (local):
# Stateful mode with local filesystem
claude mcp add mcp-v8 -- mcp-v8 --directory-path /tmp/mcp-v8-heaps
# Stateless mode
claude mcp add mcp-v8 -- mcp-v8 --stateless
SSE transport (remote):
claude mcp add mcp-v8 -t sse https://mcp-js-production.up.railway.app/sse
Then test by running claude and asking: "Run this JavaScript: [1,2,3].map(x => x * 2)"
.cursor/mcp.json in your project root:Stateful mode with local filesystem:
{
"mcpServers": {
"js": {
"command": "mcp-v8",
"args": ["--directory-path", "/tmp/mcp-v8-heaps"]
}
}
}
Stateless mode:
{
"mcpServers": {
"js": {
"command": "mcp-v8",
"args": ["--stateless"]
}
}
}
You can also use the hosted version on Railway without installing anything locally:
https://mcp-js-production.up.railway.app/sse1 + 2"run_js tool returns a heap content hash after each execution — pass it back in the next call to resume that session.You can configure heap storage using the following command line arguments:
--s3-bucket
mcp-v8 --s3-bucket my-bucket-name--s3-bucket --cache-dir
mcp-v8 --s3-bucket my-bucket-name --cache-dir /tmp/mcp-v8-cache--directory-path
mcp-v8 --directory-path /tmp/mcp-v8-heaps--stateless
mcp-v8 --statelessNote: Only one storage option can be used at a time. If multiple are provided, the server will return an error.
While mcp-v8 provides a powerful and persistent JavaScript execution environment, there are limitations to its runtime.
async/await or Promises: Asynchronous JavaScript is not supported. All code must be synchronous.fetch or network access: There is no built-in way to make HTTP requests or access the network.console.log or standard output: Output from console.log or similar functions will not appear. To return results, ensure the value you want is the last line of your code.npm install or external packages: You cannot install or import npm packages. Only standard JavaScript (ECMAScript) built-ins are available.setTimeout and setInterval are not available.window, document, or other browser-specific objects.If you prefer to build from source instead of using the install script:
cd server
cargo build --release
The built binary will be located at server/target/release/server. You can use this path in the integration steps above instead of /usr/local/bin/mcp-v8 if desired.
Comparison of single-node vs 3-node cluster at various request rates.
ran on railway gha runners on pr
| Topology | Target Rate | Actual Iter/s | HTTP Req/s | Exec Avg (ms) | Exec p95 (ms) | Exec p99 (ms) | Success % | Dropped | Max VUs |
|---|---|---|---|---|---|---|---|---|---|
| cluster-stateful | 100/s | 99.5 | 99.5 | 44.9 | 196.88 | 416.99 | 100% | 31 | 41 |
| cluster-stateful | 200/s | 199.6 | 199.6 | 23.22 | 79.32 | 131.13 | 100% | 13 | 33 |
| cluster-stateless | 1000/s | 999.9 | 999.9 | 3.82 | 7.72 | 13.09 | 100% | 0 | 100 |
| cluster-stateless | 100/s | 100 | 100 | 3.67 | 5.65 | 8.03 | 100% | 0 | 10 |
| cluster-stateless | 200/s | 200 | 200 | 3.56 | 5.9 | 8.61 | 100% | 0 | 20 |
| cluster-stateless | 500/s | 500 | 500 | 3.42 | 5.85 | 9.2 | 100% | 0 | 50 |
| single-stateful | 100/s | 99.1 | 99.1 | 215.12 | 362.5 | 376.6 | 100% | 32 | 42 |
| single-stateful | 200/s | 97.8 | 97.8 | 1948.82 | 2212.55 | 2960.96 | 100% | 5939 | 200 |
| single-stateless | 1000/s | 977.1 | 977.1 | 60.98 | 482.98 | 602.38 | 100% | 843 | 561 |
| single-stateless | 100/s | 100 | 100 | 3.71 | 5.73 | 8.73 | 100% | 0 | 10 |
| single-stateless | 200/s | 200 | 200 | 3.61 | 5.43 | 7.74 | 100% | 0 | 20 |
| single-stateless | 500/s | 500 | 500 | 4.67 | 8.49 | 27.98 | 100% | 0 | 50 |
| Topology | Rate | P95 (ms) | |
|---|---|---|---|
| cluster-stateful | 100/s | 196.88 | █████████████████████ |
| cluster-stateful | 200/s | 79.32 | █████████████████ |
| cluster-stateless | 100/s | 5.65 | ███████ |
| cluster-stateless | 200/s | 5.9 | ███████ |
| cluster-stateless | 500/s | 5.85 | ███████ |
| cluster-stateless | 1000/s | 7.72 | ████████ |
| single-stateful | 100/s | 362.5 | ███████████████████████ |
| single-stateful | 200/s | 2212.55 | ██████████████████████████████ |
| single-stateless | 100/s | 5.73 | ███████ |
| single-stateless | 200/s | 5.43 | ██████ |
| single-stateless | 500/s | 8.49 | ████████ |
| single-stateless | 1000/s | 482.98 | ████████████████████████ |
single = 1 MCP-V8 node; cluster = 3 MCP-V8 nodes with RaftInstall via CLI
npx mdskills install r33drichards/mcp-jsmcp-v8: V8 JavaScript MCP Server is a free, open-source AI agent skill. A Rust-based Model Context Protocol (MCP) server that exposes a V8 JavaScript runtime as a tool for AI agents like Claude and Cursor. Supports persistent heap snapshots via S3 or local filesystem, and is ready for integration with modern AI development environments. - V8 JavaScript Execution: Run arbitrary JavaScript code in a secure, isolated V8 engine. - TypeScript Support: Run TypeScript code d
Install mcp-v8: V8 JavaScript MCP Server with a single command:
npx mdskills install r33drichards/mcp-jsThis downloads the skill files into your project and your AI agent picks them up automatically.
mcp-v8: V8 JavaScript MCP Server works with Claude Code, Claude Desktop, Cursor, Vscode Copilot, Windsurf, Continue Dev, Gemini Cli, Amp, Roo Code, Goose. Skills use the open SKILL.md format which is compatible with any AI coding agent that reads markdown instructions.