codecalc
The codecalc server provides a comprehensive suite of MCP tools for AI models to execute code, perform exact/symbolic math, solve logic problems, manage sessions, and analyze code—all within a sandboxed, resource-limited environment.
Code Execution: Run code in 31 languages (Python, Node, Go, Rust, C, C++, etc.) with CPU/memory/output/timeout limits and network blocking (
execute_code,execute_code_stream). Stream partial output, compare execution across languages (compare_execution), and list available languages (list_languages).Sessions & Workspaces: Start persistent sessions with stateful REPLs (Python/Node) or workspace directories (
session_start,session_stop,session_list). Manage files (session_files,session_read_file,session_write_file), run multi-file programs (session_run), list artifacts (session_artifacts), and install packages (install_package).Symbolic Mathematics: Evaluate, integrate, differentiate, simplify, and solve equations with sympy (
evaluate_expression,simplify_expression,solve_expression,limit_expression). Check algebraic equivalence (algebraic_equiv) and solve systems of linear equations (solve_linear).Exact Arithmetic & Programmer Tools: Perform exact rational arithmetic (
calc_exact), compare thresholds (compare_threshold), calculate percentages (percentage). Analyze bits (bit_analysis,bitop), convert bases (base_repr,radix_convert), inspect floats (float_repr), check integer widths (int_widths).Statistics & Probabilities: Compute mean, median, stdev, CV (
calc_stats), percentiles (percentiles), and hash collision probabilities (collision_probability).Logic & SMT: Generate truth tables for boolean expressions (
truth_table) and check SMT-LIB2 satisfiability with Z3 (z3_check).Code Analysis & Optimization: Estimate Big-O complexity via tree-sitter or benchmarking (
analyze_complexity,benchmark). Translate code between languages with verification (translate_code), optimize code with proof and speedup requirements (optimize_code), extract functions (extract_function), and compare edge cases (compare_edge_cases).Units, Constants & Time: Convert dimensional units (
convert_units,list_units), look up physical constants (physical_constants), convert data sizes (data_sizes), humanize durations (human_duration), and convert epoch timestamps (epoch_time).Runtime Management: Check runtime versions and available updates (
runtimes_status), update language runtimes (update_runtimes).LLM-Assisted Operations: Fetch documentation from Context7 (
context7_docs). Translate, optimize, and compare code using LLM gateway when configured.
Enables running Bun JavaScript/TypeScript code with sandboxing, resource limits, and stdout/stderr capture.
Enables compiling and running C++ code with sandboxing, resource limits, and output capture.
Enables running Deno TypeScript/JavaScript code with sandboxing, resource limits, and output capture.
Enables running Elixir code with sandboxing, resource limits, and output capture.
Enables running Erlang code with sandboxing, resource limits, and output capture.
Enables compiling and running Fortran code with sandboxing, resource limits, and output capture.
Enables running Haskell code with sandboxing, resource limits, and output capture; scaffolds a temporary Nix project.
Enables compiling and running Kotlin code with sandboxing, resource limits, and output capture.
Enables running Lua code with sandboxing, resource limits, and output capture.
Enables running Perl code with sandboxing, resource limits, and output capture.
Enables running PHP code with sandboxing, resource limits, and output capture.
Enables running Python code with sandboxing, resource limits, output capture, and a persistent REPL session.
Enables running Ruby code with sandboxing, resource limits, and output capture.
Enables compiling and running Rust code with sandboxing, resource limits, and output capture.
Enables running SQLite SQL scripts with sandboxing, resource limits, and output capture.
Enables compiling and running Swift code with sandboxing, resource limits, and output capture.
Enables running TypeScript code (via the TypeScript compiler) with sandboxing, resource limits, and output capture.
Enables compiling and running Zig code with sandboxing, resource limits, and output capture.
Enables running Zsh shell scripts with sandboxing, resource limits, and output capture.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@codecalcwhat is 0.1 + 0.2 exactly?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
codecalc — universal code & logic calculator for AI models
Run code in 31 languages, evaluate symbolic math, solve logic problems, and measure complexity — all exposed as MCP tools any AI model or agent can call.
Architecture (language-per-strength)
Layer | Language | Why |
Executor core ( | Rust | Sandbox + rlimits + process-group kill + JSON CLI. No |
Logic layer ( | Python | sympy (symbolic math, equation solving) and z3 (SMT) have no Rust equivalents |
MCP server ( | Python | the official |
Python orchestrates; Rust executes; sympy/z3 reason. Each layer does what it's best at. The Rust binary is preferred automatically; a pure-Python executor is the fallback if the binary is missing.
Related MCP server: MCP Coding Agents
Older-computer support
target-cpu=generic— no modern instruction-set requirementsStatic musl builds run on any Linux regardless of glibc version:
bin/codecalc-exec-x86_64-musl(421K),bin/codecalc-exec-aarch64-musl(453K)Size-optimized profile (
opt-level="z", LTO, panic=abort, stripped) — measured, not assumed: against an otherwise identicalopt-level=3build,zcame out 1.02 ± 0.26 times faster on the executor's own path (i.e. no detectable difference) while being 16% smaller. The executor spends its time in syscalls, not arithmetic, so there was nothing for a higher optimisation level to speed up.Lazy sympy/z3 imports: server starts in ~40ms, not ~600ms
The fork-bomb measurement is taken once, and only when it is needed. Sizing
RLIMIT_NPROCmeans reading/proc/<pid>/statusfor every process on the machine. That walk used to run during argument parsing and again for every step: a C compile-and-run opened 1767 status files on a 590-process box to answer one question three times, and--lang notalanguagepaid the full cost to produce a one-line error. Measured lazily and cached, an error costs 1.1ms instead of 13.3ms and a compiled run 78ms instead of 104ms.list_languagesprobes runtime availability and reports which languages actually work on the machine (graceful degradation on minimal installs)
Build the Rust core
cd executor
cargo build --release # native
cargo zigbuild --release --target x86_64-unknown-linux-musl # static x86_64 (uses zig)
cargo zigbuild --release --target aarch64-unknown-linux-musl # static arm64
# Copy the executable AND its --no-net shim together. build.rs rebuilds the
# shim whenever blocknet.c changes, but the executor looks for it beside the
# BINARY, so installing only the binary leaves the previous shim in place — and
# a stale shim silently enforces the old policy while every "is it there?"
# check still passes. Copy both or neither.
cp target/release/codecalc-exec target/release/blocknet.so ../bin/Requires: Rust 1.97+, a C compiler for the --no-net shim (the build warns and
carries on without one; --no-net then reports itself in unenforced rather
than pretending), and cargo-zigbuild
for the static cross-builds (zig is used as the linker; no x86_64 GCC needed).
MCP tools (48) + MCP resources
Every session file is also exposed as an MCP resource:
codecalc://session/<session_id>/files/<path> — images render inline for the
model, text returns as text, other files download.
Exact arithmetic & programmer-mode: exact rationals, threshold checks, bit analysis, binary64 introspection.
Tool | Description |
| EXACT arithmetic: |
| Exact threshold verdict with shortfall: |
| Exact share and percentage of PART/TOTAL (rationals accepted) |
| mean, median, sample stdev, CV (CV > 0.2 = noise swamps the effect) |
| p50/p90/p95/p99 by nearest-rank AND interpolation; warns n<100 |
| Birthday-bound hash collision: 1e5 items/32 bits ≈ 0.69, 1e6/64 ≈ 2.7e-8 |
| Byte sizes both ways: KiB/MiB (binary) AND KB/MB (decimal) |
| Humanised duration + per-day/per-30d rates |
| Epoch s/ms/µs/ns → ISO 8601 UTC, implausible readings suppressed |
| hex/oct/bin + two's complement at WIDTH + signed-overflow detection |
| Any base 2..36, fractions included, non-termination flagged ( |
| What binary64 actually stores: exact value, raw bits, ULP, neighbours, representable-or-not |
| Which i8..i64/u8..u64 hold N + wrapped values; 2^53 JS/JSON caveat |
| popcount, bit length, trailing zeros, next pow2, alignment padding |
| Programmer mode: and/or/xor/nand/nor/xnor/not/shl/shr/sar/rol/ror at 8/16/32/64, unsigned+signed+hex+oct+bin; shr vs sar distinction; shift-overflow flagged |
| Are |
| Solve roots/crossovers: |
| Asymptotic limits: |
| Simplified + factored + expanded forms |
Core tools
Tool | Description |
| 31 languages with extension, compile flag, runtime availability |
| Run code in any language → stdout/stderr/exit_code/verdict (OK/TLE/MLE/OLE/RTE)/cpu_ms/peak_memory_kb; per-call limits ( |
| Like execute_code but reports progress + partial output while running |
| Persistent session; python3/node get a stateful REPL worker (variables/imports persist across calls), other languages a workspace dir |
| Session lifecycle |
| Workspace file tools, jailed to the session dir; |
| Multi-file programs: execute an entry file that imports other session files (helper.py, data/...) in the workspace |
| List files created by executed code (results, images, CSVs) |
| Install packages (uv pip/npm/gem/go/cargo...) into a session or shared cache |
| Port code between languages with verification: LLM translates, executor runs both versions on the same test inputs, accepted only if outputs match (one retry with diff feedback) |
| Optimize code with proof: LLM proposes, executor verifies correctness AND measures speedup (same sizes, min-of-repeats); accepted only if correct AND measurably faster, else retried or honestly rejected |
| Pull a named function + its dependency closure (imports, referenced helpers) into a standalone program and run it (ast-exact for python3, best-effort elsewhere) |
| Run the same logic in N languages on edge-case inputs (empty, zero, negative, float precision) and flag behavioral divergence |
| Fetch up-to-date library docs from context7 ( |
| Dimensional unit conversion via sympy: length, mass, time, speed, energy, power, force, pressure, temperature (°C/°F/K), volume, area, data, frequency |
| 22 physical constants with values (c, h, N_A, k_B, G, g, m_e, R, ...) |
| All 140+ unit aliases for convert_units |
| Symbolic math: |
| Boolean algebra: |
| SMT-LIB2 satisfiability + model |
| Systems of equations: |
| Static Big-O estimate from code structure, parsed with tree-sitter (every supported language). Reports |
| Empirical Big-O: runs code at increasing N, fits growth curve |
| Same code across N languages side-by-side |
| Non-mutating update check: current vs latest for every language runtime, which package manager owns it, and the command that would run |
| Update runtimes. Dry-run by default ( |
Runtime self-update
Every language is mapped to its package manager, and codecalc can update its own runtimes:
Manager | Languages | Update command |
mise | python3, node, bun, deno, ruby, go, erlang, elixir, gleam, zig, java, kotlin, sqlite, duckdb, gradle |
|
rustup | rust (stable/nightly toolchains) |
|
swiftly | swift |
|
apt | c, c++, fortran, csharp, php, perl, lua, tcl, r, jq, bash, zsh |
|
npm | typescript/tsc |
|
uv | mojo |
|
nix | haskell (on-demand) | nothing persistent |
runtimes_status is always safe. update_runtimes refuses to mutate unless
apply=True is passed explicitly — and it only touches the package manager
that owns each language (never the Rust sandbox, which has no update powers).
Run the server
cd /path/to/codecalc && .venv/bin/python -m codecalc.server
# stdio transport — register with any MCP clientPoint an MCP client at it:
{ "mcpServers": { "codecalc": { "command": "/path/to/codecalc/.venv/bin/python",
"args": ["-m", "codecalc.server"],
"env": {
"PYTHONPATH": "/path/to/codecalc",
"CODECALC_RUNTIME_PATH": "/path/to/mise/shims:/usr/local/bin:/usr/bin:/bin"
} } } }MCP protocol
Protocol revision 2026-07-28, on the official mcp SDK 2.0. Not fastmcp:
fastmcp 3.x pins mcp>=1.24,<2.0 and so cannot reach this revision at all.
Verifying that is less obvious than it looks. mcp.types.LATEST_PROTOCOL_VERSION
reads 2026-07-28 regardless of what a given connection negotiated, and the
same server answers on either protocol depending only on how you connect:
client | negotiated | cache hints |
|
| dropped |
|
| applied |
So tests/test_mcp_protocol.py asserts the negotiated value from a real
connection. The legacy path still works — backward compatibility is a feature —
it just must not be mistaken for the new protocol.
Worth noting for anyone reading the spec's headline change: 2026-07-28 removes
protocol-level sessions, and directs servers needing cross-call state to use
"explicit, server-minted handles passed as ordinary tool arguments". That is
exactly what codecalc's session_id already is.
Configuration
All optional. codecalc runs with none of these set.
Variable | Default | What it does |
| the server's own | The |
|
| Override the sandbox binary. Without one, codecalc falls back to a pure-Python executor — |
|
| Where session workspaces live. |
|
| Fork-bomb guard. |
| (unset) | Escape hatch: pin |
| (unset — the two LLM tools report themselves unconfigured) | An OpenAI-compatible |
| (unset) | Bearer token for that gateway, if it needs one. |
|
| Model name passed to the gateway. |
| (unset) | Opt in to an LLM second opinion on |
Both backends resolve CODECALC_RUNTIME_PATH identically, and
scripts/check_parity.py fails CI if the Rust and Python copies of that
contract ever drift — including if a machine-specific home directory finds its
way back into the default.
Test
Each file is a standalone script that prints one PASS/FAIL line per
assertion and exits non-zero if any failed — no test runner, no plugins.
cd /path/to/codecalc
# everything
for f in tests/test_*.py; do PYTHONPATH=. .venv/bin/python "$f" || break; done
for f in scripts/*.py; do PYTHONPATH=. .venv/bin/python "$f" || break; done
# or individually
PYTHONPATH=. .venv/bin/python tests/test_smoke.py # every language, via the Rust executor
PYTHONPATH=. .venv/bin/python tests/test_mcp_all.py # every tool over MCP stdio, answers checked
PYTHONPATH=. .venv/bin/python tests/test_executor_sweep.py # sandbox regressions18 test files and 5 gate scripts, 689 assertions, none skipped on a machine
with the full toolchain. Four of the files are regression suites named after the
sweep that produced them — test_bug_sweep, test_executor_sweep,
test_python_sweep, test_network_modules — and each one's docstring states
the defect it locks out and how it was reproduced, because a regression test
whose reason has been forgotten is the first one deleted.
Two rules the suite holds itself to, learned from breaking both:
Assert the value, not the shape. Three of these files once had no assertions at all: they called tools, printed the output and exited 0. They caught a crash and never a wrong answer — a
runtimes_statustotal replaced with-999passed, printingtotal = -999.Don't pin what varies.
benchmarkandcompare_executionrank by measured time, so their winner moves under load; their structure is asserted and their timing is not.runtimes_statusis checked against itself — the summary must agree with the data it summarises — so it holds on any machine rather than describing this one.
Platform support
Linux, macOS and Windows. The three do not offer the same primitives, and the
executor reports which ones it could not apply in an unenforced array on
every result rather than letting a caller assume they all held.
Guarantee | Linux | macOS | Windows |
Wall-clock timeout | yes | yes | yes |
Kill the whole process tree |
|
|
|
Fork-bomb guard |
|
| Job |
Memory ceiling |
| reported unenforced¹ | Job |
CPU-time ceiling |
|
| Job |
Open-file ceiling |
|
| reported unenforced |
Output cap | yes | yes | yes (on read) |
|
|
| reported unenforced |
Stateful sessions | yes | yes | yes |
¹ Darwin accepts setrlimit(RLIMIT_AS) but does not enforce address space the
way Linux does, so setting it would buy an illusion.
² Dynamically-linked programs only — a statically linked binary (Go, by default)
ignores it.
⁴ Applied via JOB_OBJECT_LIMIT_PROCESS_TIME, which Windows has supported
since XP — this was reported as cpu_limit_unavailable_on_windows until
2026-08-08, and the table said the same, so code and docs agreed with each other
and disagreed with Windows. It is not identical to RLIMIT_CPU and the
difference is reported rather than glossed: it counts user-mode time only, so
a process burning kernel time is not capped by it, and the system checks
periodically rather than immediately. Runs on Windows carry
cpu_limit_counts_user_time_only_on_windows in unenforced to say so.
³ Weaker still on macOS, in two ways. SIP and the hardened runtime strip
DYLD_INSERT_LIBRARIES for protected and hardened-signed binaries (most signed
interpreters), and dyld interposing does not reach calls made inside the
shared cache where libSystem lives — a program's own connect() is intercepted,
a system framework opening a connection internally is not. Treat macOS no_net
as a speed bump, never as isolation.
Windows' ActiveProcessLimit is scoped to the job, which makes it a
genuinely better fork-bomb guard than RLIMIT_NPROC's uid-wide budget — the
failure mode that broke 14 of 31 runtimes on Linux cannot occur there.
Two things degrade rather than fail on a given platform: languages whose runtime
is absent (list_languages reports available: false), and the shell-wrapper
languages — bash, zsh, csharp, gleam, haskell — which need a POSIX
shell and so are unavailable on Windows unless one is installed.
Sandbox guarantees
Fresh temp dir per run, deleted on exit (source + binaries + outputs). The deletion is identity-checked: the directory's device and inode are recorded at creation and re-checked before removal, because executed code runs with that directory as its cwd and can rename another one into its place. A caller-supplied
--workdiris a session workspace and is never deleted.rlimits: CPU (timeout+8s), address space 2TiB (V8/JVM need huge VA), file size 256MiB, 256 FDs, core dumps off
The timeout is a total budget: compile and run share it, so
--timeout 10cannot take twenty seconds.duration_msis the run alone;compile_msandtotal_msare reported separately.Wall-clock timeout kills the whole process group (SIGKILL). So does SIGTERM to the executor —
PR_SET_PDEATHSIGreaches only the direct child, so a group kill is what covers its descendants, and the executor is the only participant that knows the group id.Output capped at 64KiB per stream, on every path including stateful sessions. Exceeding it is reported as
OLE, and the file-size rlimit is kept strictly above the cap so that overflow stays detectable — tying the two together turned a truncated 4MB output into a silentverdict: OK.Fork-bomb guard via
RLIMIT_NPROC, sized from the measured ambient task count plus headroom rather than a fixed number. This is a mitigation, not isolation: the budget is shared with every other process your user owns, so concurrent executions draw on the same pool. cgroup v2pids.maxis the real per-sandbox answer and needs delegated cgroup access a stdio MCP server cannot assume — reach for it when this moves behind a container.no_netblocks the network, not every socket: it refusesAF_INETandAF_INET6and forwards everything else, soAF_UNIXlocal IPC keeps working.No network namespace isolation (single-host tool; containerize for untrusted code)
Sessions
A session is a persistent workspace; python3 and node additionally get a
long-lived REPL worker so variables and imports survive between calls. What that
does and does not buy you:
workspace session | stateful worker | |
Fresh sandboxed process per call | yes | no — one worker serves every call |
| applied | reported in |
| per call | applied once, at worker start |
Output cap + | yes | yes |
Per-call wall clock | yes | yes — a worker that blows it is killed |
A worker cannot take a per-call rlimit after the fact, and --no-net is decided
at exec time. Rather than accept those arguments and drop them, the result lists
them in unenforced — the same field the executor already uses to say "asked
for, not applied". Omit session_id, or use a workspace session, when a ceiling
has to be real.
The worker protocol does not share a file descriptor with executed code, and
every response carries the id of the request it answers. Both matter: sys.stdout
is a Python-level rebind that a subprocess writes straight past, and a corrupted
stream that is not resynchronised returns every later call the previous call's
result — a well-formed answer to a different question.
Language list
python3, node, bun, deno, typescript, ruby, php, perl, lua, tcl, r, elixir, erlang, bash, zsh, mojo, swift, c, cpp/c++, rust, go, fortran, zig, java, kotlin, csharp, gleam, haskell, sqlite, jq, awk — 31 runtimes.
codecalc does not install any of them. It runs whatever is already on
CODECALC_RUNTIME_PATH, and list_languages probes each one and reports which
actually resolved, so a minimal machine degrades to the subset it has rather
than failing opaquely.
Notes
Java uses single-file source launch (JEP 330). Kotlin compiles to a jar.
csharp/gleam/haskell scaffold a temp project (dotnet new / gleam new / nix-shell).
benchmarkuses the stdin-N contract: code reads N from stdin, work sized by N.
CI
Five workflows, each documented inline with what it gates and — where a tool was considered and rejected — why it is not there.
Workflow | Gates |
| clippy |
|
|
|
|
|
|
|
|
Two conventions run through all of them, both borrowed from harder-won experience:
Actions are pinned by commit SHA and downloaded tools by SHA-256. A tag is mutable; a digest is not.
Every scan asserts it scanned something. A linter pointed at a renamed directory, a dependency scanner with no lockfile to read, and a clean repo all produce the same output — exit 0. Each gate counts its inputs first and fails if the count is implausible.
Licence
Apache-2.0. See LICENSE.
Contributions require a DCO sign-off (git commit -s); dco.yml enforces it.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Alicense-quality-maintenanceA lightweight and fast MCP server that enables AI agents to efficiently discover and execute tools through progressive disclosure, minimizing context consumption while supporting safe code execution in external environments.Last updated13
- Alicense-qualityCmaintenanceA transport-agnostic MCP server that integrates multiple AI coding agents (Claude Code, Gemini, and Codex) with built-in tools for command execution, calculations, and streaming capabilities. Supports both STDIO and HTTP transports for flexible deployment.Last updated71MIT

multivon-mcpofficial
AlicenseAqualityAmaintenanceMCP server that gives AI coding agents direct access to evaluation tools.Last updated22Apache 2.0- AlicenseAqualityDmaintenanceMCP server that gives small LLMs verified symbolic-math & logic tools.Last updated62Apache 2.0
Related MCP Connectors
Hosted MCP server to manage a restaurant menu from AI agents - 39 tools over the DuckHub API.
An MCP server that gives your AI access to the source code and docs of all public github repos
A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/The-40-Thieves/codecalc'
If you have feedback or need assistance with the MCP directory API, please join our Discord server