Edict
   
<a href="https://glama.ai/mcp/servers/Sowiedu/Edict"><img width="380" height="200" src="https://glama.ai/mcp/servers/Sowiedu/Edict/badge" /></a>
A programming language designed for AI agents. No parser. No syntax. Agents produce AST directly as JSON.
Edict is a statically-typed, effect-tracked programming language where the canonical program format is a JSON AST. It's purpose-built so AI agents can write, verify, and execute programs through a structured pipeline ā no text parsing, no human-readable syntax, no ambiguity.
Agent (LLM)
ā produces JSON AST via MCP tool call
ā
Schema Validator āāā invalid? ā StructuredError ā Agent retries
ā
Name Resolver āāāāāā undefined? ā StructuredError + candidates ā Agent retries
ā
Type Checker āāāāāāā mismatch? ā StructuredError + expected type ā Agent retries
ā
Effect Checker āāāāā violation? ā StructuredError + propagation chain ā Agent retries
ā
Contract Verifier āā unproven? ā StructuredError + counterexample ā Agent retries
(Z3/SMT) ā
Code Generator (pure-JS WASM encoder) ā WASM ā Execute
Features
- JSON AST ā Programs are JSON objects, not text files. No lexer, no parser.
- Structured errors ā Every error is a typed JSON object with enough context for an agent to self-repair.
- Type system ā
Int,Float,String,Bool,Array<T>,Option<T>,Result<T,E>, records, enums, refinement types. - Effect tracking ā Functions declare
pure,reads,writes,io,fails. The compiler verifies consistency. - Contract verification ā Pre/post conditions verified at compile time by Z3 (via SMT). Failing contracts return concrete counterexamples.
- WASM compilation ā Verified programs compile to WebAssembly via a pure-JS encoder and run in Node.js.
- MCP interface ā All tools exposed via Model Context Protocol for direct agent integration.
- Schema migration ā ASTs from older schema versions are auto-migrated. No breakage when the language evolves.
Execution Model
Edict compiles to WebAssembly and runs in a sandboxed VM. This is a deliberate security decision ā not a limitation:
- No ambient authority ā compiled WASM cannot access the filesystem, network, or OS unless the host explicitly provides those capabilities via the pluggable
EdictHostAdapterinterface - Compile-time capability declaration ā the effect system (
io,reads,writes,fails) lets the host inspect what a program requires _before_ running it - Runtime enforcement ā
RunLimitscontrols execution timeout, memory ceiling, and filesystem sandboxing - Defense-in-depth ā agent-generated code that runs immediately needs stronger isolation than human-reviewed code. The effect system + WASM sandbox + host adapter pattern provides exactly that
Host capabilities available through adapters: filesystem (sandboxed), HTTP, crypto (SHA-256, MD5, HMAC), environment variables, CLI arguments. New capabilities are added by extending EdictHostAdapter.
Quick Start
For AI Agents (MCP)
The fastest way to use Edict is through the MCP server ā it exposes the entire compiler pipeline as tool calls:
npx edict-lang # start MCP server (stdio transport, no install needed)
Or install locally:
npm install edict-lang
npx edict-lang # start MCP server
Two calls to get started: edict_schema (learn the AST format) ā edict_check (submit a program). See MCP Tools for the full tool list.
For Development
npm install
npm test # 2675 tests across 136 files
npm run mcp # start MCP server (stdio transport)
Docker
Run the Edict MCP server in a container ā no local Node.js required:
# stdio transport (default ā for local MCP clients)
docker run -i ghcr.io/sowiedu/edict
# HTTP transport (for remote/networked MCP clients)
docker run -p 3000:3000 -e EDICT_TRANSPORT=http ghcr.io/sowiedu/edict
Supported platforms: linux/amd64, linux/arm64.
Browser
Run the Edict compiler entirely in the browser ā no server required:
| Bundle | Size | Phases | Use case | |---|---|---|---| | edict-lang/browser | 318 KB | 1ā3 (validate, resolve, typecheck, effects, lint, patch) | Lightweight checking | | edict-lang/browser-full | ~14 MB | 1ā5 (+ WASM codegen, Z3 contracts, WASM execution) | Full compile & run |
import { compileBrowser, runBrowserDirect } from 'edict-lang/browser-full';
const result = compileBrowser(astJson);
if (result.ok) {
const run = await runBrowserDirect(result.wasm);
console.log(run.output); // "Hello, World!"
}
Note: ESM modules require HTTP serving. Use
npx serve .or any static server āfile://won't work.
See examples/browser/index.html for a working example.
QuickJS (Sandboxed Environments)
The Edict compiler also runs inside QuickJS WASM ā useful for sandboxed runtimes, edge workers, or embedding in other WASM applications:
| Bundle | Size | Phases | Slowdown vs Node.js | |---|---|---|---| | dist/edict-quickjs-check.js | 373 KB | 1ā3 (validate, resolve, typecheck, effects) | ~3.7x | | dist/edict-quickjs-full.js | 932 KB | 1ā5 (check + WASM compile) | ~3.7x |
import { EdictQuickJS } from "edict-lang/quickjs";
const edict = await EdictQuickJS.createFull(); // phases 1-5
const result = edict.compile(ast);
if (result.ok) {
console.log(result.wasm); // Uint8Array of valid WASM
}
edict.dispose();
Note:
quickjs-emscriptenis an optional peer dependency ā install it alongsideedict-langto useEdictQuickJS. For fs-free environments, passbundleSourcedirectly instead of loading from disk.
See docs/quickjs-feasibility-report.md for full benchmarks and recommendations.
MCP Tools
| Tool | Description | |---|---| | edict_schema | Returns the full AST JSON Schema ā the spec for how to write programs | | edict_version | Returns compiler version and capability info | | edict_examples | Returns 41 example programs as JSON ASTs (includes schema snippet) | | edict_validate | Validates AST structure (field names, types, node kinds) | | edict_check | Full pipeline: validate ā resolve names ā type check ā effect check ā verify contracts | | edict_compile | Compiles a checked AST to WASM (returns base64-encoded binary) | | edict_run | Executes a compiled WASM binary, returns output and exit code | | edict_patch | Applies targeted AST patches by nodeId and re-checks | | edict_errors | Returns machine-readable catalog of all error types | | edict_lint | Runs non-blocking quality analysis and returns warnings | | edict_debug | Execution tracing and crash diagnostics | | edict_compose | Combines composable program fragments into a module | | edict_explain | Explains AST nodes, errors, or compiler behavior | | edict_export | Packages a program as a UASF portable skill | | edict_import_skill | Imports and executes a UASF skill package | | edict_generate_tests | Generates tests from Z3-verified contracts | | edict_replay | Records and replays deterministic execution traces | | edict_deploy | Compiles and deploys an Edict program to edge runtimes (Cloudflare Workers) | | edict_invoke | Invokes a deployed Edict WASM service via HTTP | | edict_invoke_skill | Invokes a UASF skill package directly | | edict_package | Packages a compiled program as a deployable skill bundle | | edict_support | Returns diagnostics and environment info for troubleshooting |
MCP Resources
| URI | Description | |---|---| | edict://schema | The full AST JSON Schema | | edict://schema/minimal | Minimal schema variant for token-efficient bootstrap | | edict://examples | All example programs | | edict://errors | Machine-readable error catalog | | edict://schema/patch | JSON Schema for the AST patch protocol | | edict://guide | Agent bootstrap guide for MCP-first onboarding | | edict://support | Diagnostics and environment info |
Example Program
A "Hello, World!" in Edict's JSON AST:
{
"kind": "module",
"id": "mod-hello-001",
"name": "hello",
"imports": [],
"definitions": [
{
"kind": "fn",
"id": "fn-main-001",
"name": "main",
"params": [],
"effects": ["io"],
"returnType": { "kind": "basic", "name": "Int" },
"contracts": [],
"body": [
{
"kind": "call",
"id": "call-print-001",
"fn": { "kind": "ident", "id": "ident-print-001", "name": "print" },
"args": [
{ "kind": "literal", "id": "lit-msg-001", "value": "Hello, World!" }
]
},
{ "kind": "literal", "id": "lit-ret-001", "value": 0 }
]
}
]
}
The Agent Loop
The core design: an agent submits an AST ā the compiler validates it ā if wrong, returns a StructuredError with enough context for the agent to self-repair ā the agent fixes it ā resubmits.
// 1. Agent reads the schema to learn the AST format
const schema = edict_schema();
// 2. Agent writes a program (may contain errors)
const program = agentWritesProgram(schema);
// 3. Compile ā returns structured errors or WASM
const result = edict_compile(program);
if (!result.ok) {
// 4. Agent reads errors and fixes the program
// Errors include: nodeId, expected type, candidates, counterexamples
const fixed = agentFixesProgram(program, result.errors);
// 5. Resubmit
return edict_compile(fixed);
}
// 6. Run the WASM
const output = edict_run(result.wasm);
Architecture
src/
āāā ast/ # TypeScript interfaces for every AST node
āāā validator/ # Schema validation (structural correctness)
āāā resolver/ # Name resolution (scope-aware, with Levenshtein suggestions)
āāā checker/ # Type checking (bidirectional, with unit types)
āāā effects/ # Effect checking (call-graph propagation)
āāā contracts/ # Contract verification (Z3/SMT integration)
āāā codegen/ # WASM code generation (pure-JS encoder)
ā āāā codegen.ts # IR ā WASM module orchestration
ā āāā compile-ir-expr.ts # IR expression compilation
ā āāā compile-ir-*.ts # Specialized IR compilers (calls, data, match, scalars)
ā āāā runner.ts # WASM execution (Node.js WebAssembly API)
ā āāā host-adapter.ts # EdictHostAdapter interface + platform adapters
ā āāā closures.ts # Closure capture and compilation
ā āāā hof-generators.ts # Higher-order function WASM generators
ā āāā wasm-encoder.ts # Pure-JS WASM binary encoder (replaced binaryen)
ā āāā wasm-interpreter.ts # Pure-JS WASM interpreter (no WebAssembly API needed)
ā āāā recording-adapter.ts # Execution recording for replay
ā āāā replay-adapter.ts # Deterministic replay from recorded traces
ā āāā string-table.ts # String interning for WASM memory
āāā ir/ # Mid-level IR (lowering, optimization)
āāā builtins/ # Builtin registry and domain-specific builtins
āāā compact/ # Compact AST format (token-efficient for agents)
āāā compose/ # Composable program fragments
āāā deploy/ # Edge deployment scaffolding (Cloudflare Workers)
āāā incremental/ # Incremental checking (dependency graph + diff)
āāā lint/ # Non-blocking quality warnings
āāā patch/ # Surgical AST patching by nodeId
āāā migration/ # Schema version migration (auto-upgrade older ASTs)
āāā skills/ # Skill packaging and invocation
āāā mcp/ # MCP server (tools + resources + prompts)
āāā errors/ # Structured error types
tests/ # 2675 tests across 136 files
examples/ # 41 example programs (āāāāā difficulty in README)
schema/ # Auto-generated JSON Schema
Type System
| Type | Example | |---|---| | Basic | Int, Int64, Float, String, Bool | | Array | Array<Int> | | Option | Option<String> | | Result | Result<String, String> | | Record | Point { x: Float, y: Float } | | Enum | Shape = Circle { radius: Float } \| Rectangle { w: Float, h: Float } | | Refinement | { i: Int \| i > 0 } ā predicates verified by Z3 | | Function | (Int, Int) -> Int |
Effect System
Functions declare their effects. The compiler enforces:
- A
purefunction cannot call aniofunction - Effects propagate through the call graph
- Missing effects are detected and reported
Effects: pure, reads, writes, io, fails
Contract Verification
Pre/post conditions are verified at compile time using Z3:
{
"kind": "post",
"id": "post-001",
"condition": {
"kind": "binop", "id": "binop-001", "op": ">",
"left": { "kind": "ident", "id": "ident-result-001", "name": "result" },
"right": { "kind": "ident", "id": "ident-x-001", "name": "x" }
}
}
Z3 either proves unsat (contract holds ā
) or returns sat with a concrete counterexample the agent can reason about.
Contributing
We welcome contributions from agents and humans alike. See CONTRIBUTING.md for setup instructions, coding standards, and the PR workflow.
Looking for a place to start? Check issues labeled good first issue.
Roadmap
See ROADMAP.md for the full development plan, FEATURE_SPEC.md for the language specification, and Crystallized Intelligence for how agents store and reuse verified WASM skills.
Support
Edict is free and open source under the MIT license. If your agents find it valuable, consider sponsoring its development.






