1. Conduid
  2. Developer Tools
  3. Heimdall
MCP server · Developer Tools

Heimdall

MCP server: Heimdall

Unclaimed Apache-2.0 last commit 8 months ago devtools
52Fair

Scored 6 days ago · breakdown

About Heimdall

Heimdall is an MCP server published by manojlds in the Developer Tools category: mCP server: Heimdall.

The repository has 3 stars and 1 forks, with the last commit 8 months ago. Six months or more without a commit doesn't mean the server is broken, but check the open issues before depending on it in production.

Install

From source
git clone https://github.com/manojlds/heimdall

This server has no ConduID identity, so agent calls to it are not receipted. Pin the version you install and review the source before granting it credentials.

Ask AI

✦

Ask AI about Heimdall

Powered by Claude · Grounded in docs

I know everything about Heimdall. Ask me about installation, configuration, usage, or troubleshooting.

Security checks

Static checks derived from the repository 6 days ago. Heuristics on the source, not an audit.

  • ✓README presentThe repository ships documentation.
  • ✓License declaredUsable under a stated license.
  • ✓Tests presentA test suite exists in the repository.
  • ✓Dependencies pinnedA lockfile pins dependency versions.
  • ✓No dynamic code executionSource scan found no eval, dynamic Function, or shell execution.
  • !Scoped permissionsDoesn't declare a permission scope. Assume it can do anything its process can.

Releases

v0.2.0v0.2.0

README

Heimdall MCP Server

A TypeScript MCP server providing sandboxed Python and Bash execution using Pyodide (Python compiled to WebAssembly) and just-bash.

Named after the Norse god who guards the Bifröst bridge, Heimdall watches over code execution with security and vigilance.

Features

  • 🔒 Secure Sandbox: Python code runs in an isolated WebAssembly environment
  • 🐚 Bash Execution: Run bash commands with 50+ built-in tools (grep, sed, awk, jq, find, etc.)
  • 📁 Virtual Filesystem: Read, write, list, and delete files in a persistent workspace
  • 📦 Package Management: Install pure Python packages via micropip
  • 🔄 Session Persistence: Workspace files persist across executions
  • ⚡ Native Integration: Direct Pyodide and just-bash integration (no subprocess bridge)
  • 🤝 Interoperability: Bash and Python share the same workspace filesystem

Architecture

┌──────────────────────────────────────────────────────────┐
│                   MCP Client (Cursor)                    │
└────────────────────┬─────────────────────────────────────┘
                     │ MCP Protocol (stdio)
┌────────────────────▼─────────────────────────────────────┐
│           TypeScript MCP Server (Node.js)                │
│  • @modelcontextprotocol/sdk                             │
│  • PyodideManager + BashManager                          │
│  • Virtual FS ↔ Host FS sync                             │
├──────────────────────┬──────────────────┬────────────────┤
│   Pyodide (WASM)     │  just-bash (TS)  │  Shared FS     │
│  • Python runtime    │  • Bash simulator│  • ./workspace │
│  • /workspace mount  │  • 50+ commands  │  • Persistence │
└──────────────────────┴──────────────────┴────────────────┘

Prerequisites

  • Node.js >= 18.0.0

Installation

npm install

Usage

Development (with hot reload)

npm run dev

Production

npm run build
npm start

Cursor MCP Configuration

Add to your Cursor settings (~/.cursor/mcp.json or workspace .cursor/mcp.json):

{
  "mcpServers": {
    "heimdall": {
      "command": "node",
      "args": ["dist/server.js"],
      "cwd": "/path/to/heimdall"
    }
  }
}

Or for development with tsx:

{
  "mcpServers": {
    "heimdall": {
      "command": "npx",
      "args": ["tsx", "src/server.ts"],
      "cwd": "/path/to/heimdall"
    }
  }
}

Available Tools

execute_bash

Execute bash commands in the Heimdall environment using just-bash.

Features:

  • 50+ built-in commands: grep, sed, awk, find, jq, curl, tar, etc.
  • Pipes and redirections: |, >, >>, 2>, 2>&1
  • Variables, loops, conditionals, and functions
  • File operations: ls, cat, cp, mv, rm, mkdir, etc.
  • Text processing: grep, sed, awk, cut, sort, uniq, wc, etc.
  • Data tools: jq (JSON), sqlite3 (SQLite), xan (CSV), yq (YAML)

Security:

  • No real processes spawned (TypeScript simulation)
  • Execution limits prevent infinite loops
  • Network access disabled by default
  • Filesystem limited to workspace directory
// Input
{
  command: string;  // Bash command to execute
  cwd?: string;     // Working directory (relative to /workspace)
}

// Output
{
  stdout: string;
  stderr: string;
  exitCode: number;
}

Examples:

# Find Python files
find . -name "*.py" -type f

# Process text files
cat data.txt | grep "pattern" | wc -l

# JSON processing
cat data.json | jq '.users[] | {name, email}'

# Multiple commands
ls -la && cat README.md | head -10

# Text processing pipeline
grep -r "TODO" src/ | sort | uniq

execute_python

Execute Python code in the sandbox. Packages are auto-detected from imports.

Note: Network access is NOT available - Pyodide runs in WebAssembly which provides a security boundary that prevents network requests.

// Input
{
  code: string;           // Python code to execute
  packages?: string[];    // Optional additional packages (auto-detection handles most cases)
}

// Output
{
  success: boolean;
  stdout: string;
  stderr: string;
  result: string | null;  // Last expression value
  error: string | null;
}

Example:

# Packages are auto-detected - no need to specify numpy/pandas!
import numpy as np
import pandas as pd

data = np.array([1, 2, 3, 4, 5])
df = pd.DataFrame({'values': data, 'squared': data ** 2})
print(df)

install_packages

Install Python packages via micropip.

// Input
{
  packages: string[];  // Package names to install
}

// Output
{
  results: Array<{
    package: string;
    success: boolean;
    error: string | null;
  }>;
}

write_file

Write content to a file in the workspace.

// Input
{
  path: string;     // File path relative to workspace
  content: string;  // Content to write
}

read_file

Read a file from the workspace.

// Input
{
  path: string;  // File path relative to workspace
}

list_files

List files in a directory.

// Input
{
  path?: string;  // Directory path (empty for root)
}

// Output
{
  files: Array<{
    name: string;
    isDirectory: boolean;
    size: number;
  }>;
}

delete_file

Delete a file or empty directory.

// Input
{
  path: string;  // File or directory path
}

Available Resources

URI Description
workspace://files Tree listing of workspace contents
workspace://file/{path} Read a specific file
heimdall://info Environment information

Workspace

Files are stored in the workspace/ directory.

Configuration

Customize the server behavior with environment variables:

{
  "mcpServers": {
    "heimdall": {
      "command": "node",
      "args": ["dist/server.js"],
      "cwd": "/path/to/heimdall",
      "env": {
        "HEIMDALL_WORKSPACE": "/custom/workspace/path",
        "HEIMDALL_MAX_FILE_SIZE": "52428800",
        "HEIMDALL_MAX_WORKSPACE_SIZE": "524288000",
        "HEIMDALL_PYTHON_EXECUTION_TIMEOUT_MS": "5000"
      }
    }
  }
}

Available environment variables:

Variable Description Default Format
HEIMDALL_WORKSPACE Path to workspace directory ./workspace Absolute or relative path
HEIMDALL_MAX_FILE_SIZE Maximum size for a single file 10485760 (10MB) Bytes (positive integer)
HEIMDALL_MAX_WORKSPACE_SIZE Maximum total workspace size 104857600 (100MB) Bytes (positive integer)
HEIMDALL_PYTHON_EXECUTION_TIMEOUT_MS Python execution timeout 5000 Milliseconds (positive integer)

Example: To allow 50MB files and 500MB total workspace:

  • HEIMDALL_MAX_FILE_SIZE: 52428800 (50 * 1024 * 1024)
  • HEIMDALL_MAX_WORKSPACE_SIZE: 524288000 (500 * 1024 * 1024)

Security

Network Access

Python code cannot make network requests. Pyodide runs in WebAssembly which provides a security boundary that prevents:

  • HTTP/HTTPS requests from Python code
  • Socket connections
  • Any external network communication initiated by user code

This is enforced by the WASM runtime itself. Code that attempts to make network requests will fail with an error.

How Package Installation Works

Package installation (micropip.install()) works because it uses Pyodide's internal mechanism which operates at the JavaScript/Node.js layer, not Python:

micropip.install("numpy")  →  Pyodide (JS)  →  Node.js fetch()  →  PyPI

This is intentional - packages can be installed via Pyodide's trusted mechanism, but user code cannot make arbitrary network requests.

What Works vs What's Blocked

✅ Available ❌ Blocked
Package installation (micropip) urllib.request.urlopen()
File I/O (workspace) requests.get()
Data processing (numpy, pandas) Socket connections
URL parsing (urllib.parse) External API calls
loadPackagesFromImports() Data exfiltration

Available Packages

Pyodide includes many popular packages:

Pre-installed

  • Standard library (os, sys, json, re, math, etc.)
  • micropip (for installing more packages)

Available via install_packages

  • Data Science: numpy, pandas, scipy, scikit-learn
  • Visualization: matplotlib, seaborn, plotly
  • HTML Parsing: beautifulsoup4, lxml (parsing only, no fetching)
  • Text/NLP: regex, nltk
  • Math: sympy, statsmodels
  • Image: pillow

Limitations

  • No network access (WASM security boundary)
  • Packages with native C/Fortran code must have Pyodide-compatible wheels
  • No multiprocessing or threading
  • Memory constrained by Node.js heap

See Pyodide Packages for full compatibility list.

Project Structure

heimdall/
├── src/
│   ├── server.ts                # Entry point
│   ├── config/
│   │   └── constants.ts         # Configuration and limits
│   ├── core/
│   │   ├── bash-manager.ts      # Bash execution (just-bash)
│   │   ├── pyodide-manager.ts   # Python execution coordinator
│   │   ├── pyodide-worker.ts    # Worker thread for Python
│   │   └── secure-fs.ts         # Secure filesystem wrapper
│   ├── tools/
│   │   ├── bash-execution.ts    # execute_bash tool
│   │   ├── python-execution.ts  # execute_python tool
│   │   └── filesystem.ts        # File operation tools
│   ├── resources/               # MCP resource handlers
│   ├── types/                   # TypeScript interfaces
│   └── utils/                   # Utilities (async-lock, etc.)
├── test/                        # Vitest tests
├── dist/                        # Compiled output
└── workspace/                   # Persistent file storage

Development

Build

npm run build

Test

npm test                 # Run all tests
npm run test:watch       # Watch mode
npm run test:coverage    # With coverage

Validate (before committing)

npm run validate         # Type-check + lint + format + build

Clean

npm run clean

Bash and Python Interoperability

Bash and Python share the same workspace filesystem, enabling powerful workflows:

Example: Bash prepares data, Python analyzes

# Bash: Extract and clean data
cat raw_data.csv | grep -v '^#' | sort > clean_data.csv
# Python: Analyze the cleaned data
import pandas as pd
df = pd.read_csv('/workspace/clean_data.csv')
print(df.describe())

Example: Python generates data, Bash processes

# Python: Generate report data
import json
data = [{"name": "Alice", "score": 95}, {"name": "Bob", "score": 87}]
with open('/workspace/results.json', 'w') as f:
    json.dump(data, f)
# Bash: Extract specific fields
cat results.json | jq '.[] | select(.score > 90) | .name'

Security Considerations

  • ✅ Python runs in WebAssembly sandbox (memory-isolated)
  • ✅ Bash uses just-bash (no real process spawning)
  • ✅ No direct host filesystem access (only workspace)
  • ✅ Execution limits prevent infinite loops and runaway scripts
  • ✅ Limited networking capabilities
  • ⚠️ Workspace files are accessible to all code executions
  • ⚠️ Installed packages persist in the session

Troubleshooting

Slow first execution

Pyodide downloads ~15MB on first run. Subsequent runs use cached files.

Package installation fails

Some packages aren't available in Pyodide. Check compatibility at pyodide.org.

Memory errors

WebAssembly has memory limits. For large datasets, process in chunks. You can increase Node.js heap with:

NODE_OPTIONS="--max-old-space-size=4096" npm start

License

MIT

README fetched from the repository 6 days ago. The original is authoritative.

Questions

About Heimdall

How do I install Heimdall?

No package has been published for this server, so install it from source: clone the repository and follow its README.

Is Heimdall safe to use with an AI agent?

Its trust score is 52 out of 100 (fair). It passes 5 of the 6 static security checks run so far; the failures are listed above. It has no ConduID identity yet, so agent calls to it are not receipted.

Is Heimdall still maintained?

The last commit was 8 months ago. That's long enough that you should check whether the maintainer is responding to issues before depending on it.