Show HN: RunJS – a C# MCP server to let LLMs generate and run JavaScript safely

3 days ago 1

This project contains an MCP server that can execute JavaScript in an isolated sandbox and return a result from the script.

This is extremely powerful as in many cases, you may want to run JavaScript, but doing it safely is challenging because of the nature of JavaScript and generated code.

The RunJS MCP server uses Jint -- a C# library that embeds a JavaScript runtime into .NET and allows controlling the execution sandbox by specifying:

  • Memory limits
  • Number of statements
  • Runtime
  • Depth of calls (recursion)

This makes it easy to generate and run JavaScript dynamically within your prompt as a tool without risk.

This can unlock a lot of use cases where JavaScript is needed to process some JSON, for example, and return text or run some transformation logic on incoming data.

Here's an example call using the Vercel AI SDK:

const mcpClient = await createMCPClient({ transport: { type: "sse", url: "http://localhost:5000/sse", }, }); const tools = await mcpClient.tools(); const prompt = ` Generate and execute JavaScript that can parse the following JSON The JavaScript should 'return' the value Return only the value of the name property: { "id": 12345, "name": "Charles Chen", "handle": "chrlschn" }` try { const { text } = await generateText({ model: openai("gpt-4.1-nano"), prompt, tools, maxSteps: 10, // 👈 Very, very important or you get no output! }); console.log("Output:", text); } finally { await mcpClient.close(); }

The LLM will generate the following JavaScript:

const jsonString = '{ "id": 12345, "name": "Charles Chen", "handle": "chrlschn" }'; const obj = JSON.parse(jsonString); return obj.name;

And use the RunJS MCP server to execute it 🚀

The project is set up in the following structure:

📁 app 📁 src # A sample client application using Vercel AI SDK .env # 👈 Make your own from the .env.sample .env.sample # Sample .envfile; make a copy as .env 📁 server Program.cs # A .NET MCP server exposing the Jint tool builder-server.sh # Simple script (command) to build the container docker-compose.yaml # Start the Aspire Dashboard container for OTEL Dockerfile # Dockerfile for the .NET server app

Configuring Your Local Environment

You'll need to Install the .NET SDK if you don't have it. These are available for Windows, Linux, and macOS.

Once installed, you can run the following command to start the server:

dotnet run --project server

This starts the MCP server on port 5000. For local use or use in a private network, you do not need to do anything special. To expose your local MCP to an external client (e.g. local MCP and deployed application), you will need to map a proxy.

To use this with the LLM API call from a remote origin, you will need to expose it to OpenAI using a proxy like ngrok or the VS Code Ports tool.

👉 Be sure to set the port as public

Once you've done this, you will need to create a copy of the .env.sample file and as .env and set your OpenAI API key and the URL:

OPENAI_API_KEY=sk-proj-kSZWV-M7.......K_MMv8JZRmIA MCP_ENDPOINT=https://mhjt5hqd-5000.use.devtunnels.ms/sse

If you are only using a local call (like the /app directory):

OPENAI_API_KEY=sk-proj-kSZWV-M7.......K_MMv8JZRmIA MCP_ENDPOINT=http://localhost:5000/sse

From the /app directory, run the following:

cd app npm i npm run app -- "Use your echo tool with my name: <YOUR_NAME_HERE>; write out your response"

This should invoke the .NET MCP endpoint and output your name!

🚨 THERE IS CURRENTLY NO AUTH 🚨

See the workstream here

This is only suitable for running in a private network at the moment.

Why might you use this? If your runtime application is Python, JavaScript, or some other language and you need a fast, easy, secure, controlled context to run generated code.

# To start the server dotnet run --project server # To start the server with hot reload dotnet watch run --project server --non-interactive
cd app npm run app -- "My prompt goes here"

To test this, you can run two types of prompts:

cd app # Just test the echo npm run app -- "Echo my name back to me: Charles" # Generate and execute JavaScript npm run app -- "Generate some JavaScript that will lowercase and return the string 'Hello, World' and execute it. Give me the results; ONLY THE RESULTS" # Something more complex" npm run app -- 'Generate and execute JavaScript that can parse the following JSON and return the value of the name property: { "id": 12345, "name": "Charles Chen", "handle": "chrlschn" }'

If you run the following:

You will also get the Aspire Dashboard at http://localhost:18888 to trace the internal calls to the tools.

Read Entire Article