AI Skill Hub 推荐使用:MCP-JS 是一款优质的MCP工具。AI 综合评分 7.5 分,在同类工具中表现稳健。如果你正在寻找可靠的MCP工具解决方案,这是一个值得深入了解的选择。
MCP-JS 是一款遵循 MCP(Model Context Protocol)标准协议的 AI 工具扩展。通过 MCP 协议,它可以让 Claude、Cursor 等主流 AI 客户端直接访问和操作外部工具、数据源和服务,实现 AI 能力的无缝扩展。无论是文件操作、数据库查询还是 API 调用,都可以通过自然语言在 AI 对话中直接触发,极大提升生产效率。
MCP-JS 是一款遵循 MCP(Model Context Protocol)标准协议的 AI 工具扩展。通过 MCP 协议,它可以让 Claude、Cursor 等主流 AI 客户端直接访问和操作外部工具、数据源和服务,实现 AI 能力的无缝扩展。无论是文件操作、数据库查询还是 API 调用,都可以通过自然语言在 AI 对话中直接触发,极大提升生产效率。
# 方式一:通过 Claude Code CLI 一键安装
claude skill install https://github.com/r33drichards/mcp-js
# 方式二:手动配置 claude_desktop_config.json
{
"mcpServers": {
"mcp-js": {
"command": "npx",
"args": ["-y", "mcp-js"]
}
}
}
# 配置文件位置
# macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
# Windows: %APPDATA%/Claude/claude_desktop_config.json
# 安装后在 Claude 对话中直接使用 # 示例: 用户: 请帮我用 MCP-JS 执行以下任务... Claude: [自动调用 MCP-JS MCP 工具处理请求] # 查看可用工具列表 # 在 Claude 中输入:"列出所有可用的 MCP 工具"
// claude_desktop_config.json 配置示例
{
"mcpServers": {
"mcp-js": {
"command": "npx",
"args": ["-y", "mcp-js"],
"env": {
// "API_KEY": "your-api-key-here"
}
}
}
}
// 保存后重启 Claude Desktop 生效
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.
run_js returns immediately with an execution ID. Poll status with get_execution, read console output with get_execution_output, and cancel running executions with cancel_execution.console.log, console.info, console.warn, and console.error. Output is streamed to persistent storage during execution and can be read in real-time with paginated access (line-based or byte-based).async/await and Promises via the deno_core event loop.WebAssembly JavaScript API (WebAssembly.Module, WebAssembly.Instance, WebAssembly.validate).import syntax. Packages are fetched from esm.sh at runtime — no npm install needed. (e.g., import { camelCase } from "npm:lodash-es@4.17.21")fs module for Node.js-compatible file operations (read, write, delete, etc.), with every operation checked against a Rego policy before execution.fetch() function for JavaScript following the web standard Fetch API, with every HTTP request checked against an Open Policy Agent policy before execution../examples/sqlite-wasm/build.sh
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).
Install the CLI client separately using install-cli.sh:
curl -fsSL https://raw.githubusercontent.com/r33drichards/mcp-js/main/install-cli.sh | sudo bash
This installs mcp-v8-cli to /usr/local/bin/mcp-v8-cli.
You can also install the CLI via cargo (once the crate is published to crates.io):
cargo install mcp-v8-client
Or download a pre-built binary directly from the GitHub Releases page.
---
Advanced users: If you prefer to build from source, see the Build from Source section at the end of this document.
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 target/release/server. You can use this path in the integration steps above instead of /usr/local/bin/mcp-v8 if desired.
```bash
After installation, you can run the server directly. Choose one of the following options:
Ask Claude or Cursor: "Run this JavaScript: console.log(1 + 2)"
The agent will: 1. Call run_js with code: "console.log(1 + 2)" → receives execution_id 2. Call get_execution with the execution_id → receives { status: "completed" } 3. Call get_execution_output with the execution_id → receives { data: "3\n", total_lines: 1 }
In stateful mode, get_execution also returns a heap content hash — pass it back in the next run_js call to resume from that state.
export MCP_V8_URL=https://my-server.example.com mcp-v8-cli executions list ```
- --print-openapi: Print the OpenAPI JSON specification to stdout and exit. Use this to regenerate openapi.json:
mcp-v8 --print-openapi > openapi.json
--s3-bucket <bucket>: Use AWS S3 for heap snapshots. Specify the S3 bucket name. (Conflicts with --stateless)--cache-dir <path>: Local filesystem cache directory for S3 write-through caching. Reduces latency by caching snapshots locally. (Requires --s3-bucket)--directory-path <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 <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 <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)These options enable Raft-based clustering for distributed coordination and replicated session logging.
--cluster-port <port>: Port for the Raft cluster HTTP server. Enables cluster mode when set. (Requires --http-port or --sse-port)--node-id <id>: Unique node identifier within the cluster (default: node1).--peers <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 <address>: Join an existing cluster by contacting this seed address (host:port). The node registers itself with the cluster leader.--advertise-addr <addr>: Advertise address for this node (host:port). Used for peer discovery and write forwarding. Defaults to <node-id>:<cluster-port>.--heartbeat-interval <ms>: Raft heartbeat interval in milliseconds (default: 100).--election-timeout-min <ms>: Minimum election timeout in milliseconds (default: 300).--election-timeout-max <ms>: Maximum election timeout in milliseconds (default: 500).These options enable a policy-gated fetch() function in the JavaScript runtime. When fetch policies are configured via --policies-json, a fetch(url, opts?) global becomes available. fetch() follows the web standard Fetch API — it returns a Promise that resolves to a Response object. If fetch-header rules are configured, matching headers are applied first, then the resulting request is evaluated by policy.
--fetch-header <RULE>: Inject static headers or dynamic OAuth client-credentials tokens into matching fetch requests. Static format: host=<host>,header=<name>,value=<val>[,methods=GET;POST]. Dynamic format: host=<host>,header=<name>,token_url=<url>,client_id=<id>,client_secret=<secret>[,scope=<scope>][,refresh_buffer_secs=30][,methods=GET;POST]. Can be specified multiple times. Requires fetch to be enabled via --policies-json. See Fetch Header Injection for details.--fetch-header-config <PATH>: Path to a JSON file with fetch header injection rules. Each rule uses either a static headers object or a dynamic auth block. Requires fetch to be enabled via --policies-json. See Fetch Header Injection for details.Example:
mcp-v8 --stateless --http-port 3000 \
--policies-json '{"fetch":{"policies":[{"url":"http://localhost:8181"}]}}'
Pre-load WebAssembly modules that are available as global variables in every JavaScript execution.
--wasm-module <name>=<path>: Pre-load a .wasm file and expose its exports as a global variable with the given name. Can be specified multiple times for multiple modules.--wasm-config <path>: Path to a JSON config file mapping global names to .wasm file paths. Format: {"name": "/path/to/module.wasm", ...}.Both options can be used together. CLI flags and config file entries are merged; duplicate names cause an error.
Example — CLI flags:
mcp-v8 --stateless --wasm-module math=/path/to/math.wasm --wasm-module crypto=/path/to/crypto.wasm
Example — Config file (wasm-modules.json):
{
"math": "/path/to/math.wasm",
"crypto": "/path/to/crypto.wasm"
} mcp-v8 --stateless --wasm-config wasm-modules.json
After loading, the module exports are available directly in JavaScript:
math.add(21, 21); // → 42
Modules with imports (e.g. WASI modules like SQLite) are also supported. When a module has imports, auto-instantiation is skipped and the compiled WebAssembly.Module is exposed as __wasm_<name>. Your JavaScript code can then instantiate it with the required imports:
// __wasm_sqlite is the compiled WebAssembly.Module
var instance = new WebAssembly.Instance(__wasm_sqlite, {
wasi_snapshot_preview1: { /* WASI stubs */ },
});
instance.exports.sqlite3_open(/* ... */);
Self-contained modules (no imports) are auto-instantiated as before — their exports are set directly on <name>, and the compiled Module is also available as __wasm_<name>.
See the SQLite WASM example for a complete working example.
You can configure heap storage using the following command line arguments:
--s3-bucket <bucket>mcp-v8 --s3-bucket my-bucket-name--s3-bucket <bucket> --cache-dir <path>mcp-v8 --s3-bucket my-bucket-name --cache-dir /tmp/mcp-v8-cache--directory-path <path>mcp-v8 --directory-path /tmp/mcp-v8-heaps--statelessmcp-v8 --statelessNote: Only one storage option can be used at a time. If multiple are provided, the server will return an error.
When running with --http-port or --sse-port, the server exposes a plain REST API alongside the MCP transport:
| Endpoint | Method | Description |
|---|---|---|
/api/exec | POST | Submit JS code for async execution |
/api/executions | GET | List all executions |
/api/executions/{id} | GET | Get status + result of an execution |
/api/executions/{id}/output | GET | Read paginated console output |
/api/executions/{id}/cancel | POST | Cancel a running execution |
/swagger-ui | GET | Interactive Swagger UI |
/api-doc/openapi.json | GET | OpenAPI 3.0 specification |
The OpenAPI specification is also committed to the repo root as openapi.json.
cd server
cargo build --release
./target/release/server --print-openapi > ../openapi.json
cp ../openapi.json ../mcp-v8-client/openapi.json
allow if { input.method == "GET" input.url_parsed.host == "api.example.com" startswith(input.url_parsed.path, "/public/") }
The policy input includes:
- `operation`: always `"fetch"`
- `url`: the full URL string
- `method`: HTTP method (e.g. `"GET"`, `"POST"`)
- `headers`: request headers (keys normalized to lowercase)
- `url_parsed`: parsed URL components — `scheme`, `host`, `port`, `path`, `query`
**2. Start the server with fetch policy enabled**
bash mcp-v8 --stateless --http-port 3000 \ --policies-json '{"fetch":{"policies":[{"url":"http://localhost:8181"}]}}'
**3. Use `fetch()` in JavaScript**
javascript const resp = await fetch("https://api.example.com/public/data"); resp.status; // 200 resp.ok; // true await resp.text(); // response body as string await resp.json(); // parsed JSON resp.headers.get("content-type"); // header value
The response object supports:
- Properties: `.ok`, `.status`, `.statusText`, `.url`, `.redirected`, `.type`, `.bodyUsed`
- Methods: `.text()`, `.json()`, `.clone()` (`.text()` and `.json()` return Promises)
- Headers: `.headers.get(name)`, `.headers.has(name)`, `.headers.entries()`, `.headers.keys()`, `.headers.values()`, `.headers.forEach(fn)`
`fetch()` also accepts an options object:
javascript const resp = await fetch("https://api.example.com/data", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ key: "value" }) }); JSON.stringify(await resp.json()); ```
If the OPA policy denies a request, the Promise returned by fetch() is rejected with an error.
Execution differs by transport mode:
Stateful MCP:
1. run_js(code) → { execution_id }
2. get_execution(id) → { status: "running" | "completed" | "failed" | "cancelled" | "timed_out", result, error }
3. get_execution_output(id, line_offset, line_limit) → paginated console output
Stateless MCP:
1. run_js(code) → { output, error? }
Example:
Stateful MCP:
Call run_js with code: "console.log('hello');"
→ { execution_id: "abc-123" }
Call get_execution with execution_id: "abc-123"
→ { status: "completed" }
Call get_execution_output with execution_id: "abc-123"
→ { data: "hello\n", total_lines: 1 }
Stateless MCP:
Call run_js with code: "console.log('hello');"
→ { output: "hello\n" }
You can import npm packages, JSR packages, and URL modules directly in your JavaScript code using ES module import syntax. Packages are fetched from esm.sh at runtime — no npm install or pre-installation step is needed.
Use the npm: prefix followed by the package name and version:
import { camelCase } from "npm:lodash-es@4.17.21";
camelCase("hello world"); // → "helloWorld"
import dayjs from "npm:dayjs@1.11.13";
dayjs("2025-01-15").format("MMMM D, YYYY"); // → "January 15, 2025"
Use the jsr: prefix for packages from the JSR registry:
import { camelCase } from "jsr:@luca/cases@1.0.0";
camelCase("hello world"); // → "helloWorld"
Import directly from any URL that serves ES modules:
import { pascalCase } from "https://deno.land/x/case/mod.ts";
pascalCase("hello world"); // → "HelloWorld"
npm: specifiers are rewritten to https://esm.sh/<package> URLsjsr: specifiers are rewritten to https://esm.sh/jsr/<package> URLshttps:// and http:// URLs are fetched directly./utils.js) resolve against the parent module's URL.ts, .tsx) fetched from URLs are automatically type-stripped before execution- Always pin versions (e.g., npm:lodash-es@4.17.21) for reproducible results - Only packages that ship as ES modules are supported — CommonJS-only packages won't work directly, but esm.sh converts many of them automatically - Imports are fetched over the network at runtime, so the first execution may be slower while modules are downloaded - Top-level await is supported, so you can use import() dynamically as well:
const { default: _ } = await import("npm:lodash-es@4.17.21");
_.chunk([1, 2, 3, 4, 5], 2); // → [[1, 2], [3, 4], [5]]
mcp-v8 --stateless --wasm-module math=./math.wasm
mcp-v8 --stateless \ --wasm-module math=./math.wasm \ --wasm-module physics=./physics.wasm
Or use a JSON config file for many modules:
json { "math": "./math.wasm", "physics": "./physics.wasm" } bash mcp-v8 --stateless --wasm-config wasm-modules.json
**3. Call exports from JavaScript**
The module's exports are available directly on the global variable:
javascript math.add(2, 3); // → 5 math.add(100, 200); // → 300
When multiple modules are loaded, each is its own global:
javascript var sum = math.add(10, 5); // 15 var product = physics.multiply(3, 4); // 12 sum + product; // → 27 ```
mcp-v8 是一个基于 Rust 开发的 Model Context Protocol (MCP) 服务端,它为 Claude 和 Cursor 等 AI Agent 提供了一个高性能的 V8 JavaScript 运行时环境。该项目允许 AI 直接调用 JavaScript 执行能力,并支持通过 S3 或本地文件系统实现持久化的堆快照(heap snapshots),非常适合集成到现代 AI 开发工作流中。
本项目采用异步执行模型,通过 `run_js` 提交任务并获取 `execution_id`,开发者可以利用 `get_execution` 轮询状态,并通过 `get_execution_output` 读取控制台输出。此外,它完整支持 `console.log`、`console.info`、`console.warn` 和 `console.error` 等标准输出,所有日志都会在执行期间流式传输至持久化存储中。
在构建 WASM 模块时需要使用 Emscripten 环境。开发环境建议安装 Rust (推荐使用 nightly toolchain)。如果需要使用 AWS S3 进行堆快照存储,请确保配置好相应的 AWS credentials。
可以通过官方提供的安装脚本快速部署:使用 `curl` 下载并运行 `install.sh` 即可将 `mcp-v8` 安装至 `/usr/local/bin`。若需使用命令行客户端,请单独安装 `mcp-v8-cli`。此外,开发者也可以通过 `cargo install` 直接从 crates.io 安装,或者通过编译源码的方式进行高级自定义部署。
安装完成后,您可以直接启动服务端。对于 AI Agent(如 Claude 或 Cursor),您可以直接下达指令,例如“运行这段 JS:`console.log(1 + 2)`”。Agent 会自动调用 `run_js` 获取 ID,随后通过 `get_execution` 检查状态,并最终通过 `get_execution_output` 获取执行结果。在有状态模式下,系统还会返回相应的 `heap` 数据。
可以通过环境变量 `MCP_V8_URL` 指向远程服务器。服务端提供了丰富的存储选项:使用 `--s3-bucket` 指定 AWS S3 存储快照,或使用 `--directory-path` 指定本地目录。为了降低延迟,配合 `--cache-dir` 可以实现 S3 的写穿透缓存。此外,还支持通过 `--print-openapi` 导出 OpenAPI 规范文件。
当使用 `--http-port` 或 `--sse-port` 模式运行时,服务端会在 MCP 传输层之外暴露一个标准的 REST API。开发者可以通过 `/api/exec` 提交异步执行任务,通过 `/api/executions` 列表查看所有执行记录,并利用 `/api/executions/{id}` 获取特定任务的详情。所有接口均遵循 OpenAPI 规范。
执行工作流根据传输模式的不同而有所区别。在 Stateful MCP 模式下,执行流程为:调用 `run_js` 获取 `execution_id` $\rightarrow$ 使用 `get_execution` 轮询状态 $\rightarrow$ 通过 `get_execution_output` 分页读取控制台输出。在集成方面,支持通过 ES module 语法直接 `import` npm 或 JSR 包,运行时通过 esm.sh 自动获取,无需手动执行 `npm install`。
高质量的MCP工具,提供JavaScript运行时
该工具使用 AGPL-3.0 协议,商用场景请仔细阅读协议条款,必要时咨询法律意见。
AI Skill Hub 为第三方内容聚合平台,本页面信息基于公开数据整理,不对工具功能和质量作任何法律背书。
建议在沙箱或测试环境中充分验证后,再部署至生产环境,并做好必要的安全评估。
⚠️ AGPL 3.0 — 最严格的 Copyleft,网络服务端使用也需开源,SaaS 使用受限。
总体来看,MCP-JS 是一款质量良好的MCP工具,在同类工具中具备一定竞争力。AI Skill Hub 将持续追踪其更新动态,建议收藏备用,结合自身场景选择合适时机引入使用。
| 原始名称 | mcp-js |
| 原始描述 | 开源MCP工具:MCP server that exposes a V8 JavaScript runtime as a tool for AI agents like Cla。⭐43 · Rust |
| Topics | javascriptmcprust |
| GitHub | https://github.com/r33drichards/mcp-js |
| License | AGPL-3.0 |
| 语言 | Rust |
收录时间:2026-06-01 · 更新时间:2026-06-01 · License:AGPL-3.0 · AI Skill Hub 不对第三方内容的准确性作法律背书。
选择 Agent 类型,复制安装指令后粘贴到对应客户端