Skip to content

Execution Engine

Status: v0.1 — simulateBytecode, runTransaction, runBlock, capability registry, provenance.

The mcp-execution-engine is a pure TypeScript library: stateless EthereumJS v10 simulations with no HTTP, MCP transport, or payments. The gateway (Step 3+) depends on it one-way.

Repository: feelyourprotocol/mcp-execution-engine (v0.1.0). Consumed by mcp-gateway via LocalTaskProcessor.

End-user tool semantics: Describe Capabilities, Run Bytecode, Run Transaction, Run Block, Coverage, Guarantees.

Design principles

  • Query shapes, not library APIs — the MCP surface exposes generic verbs (simulate, transaction, block, generate, probe); the engine returns structured results.
  • Fork = capability set(baseHardfork, eips[]) à la carte; named forks (osaka baseline, amsterdam preview) are catalog capabilities (summary, advertised EIPs, shapes).
  • Provenance on every result — engine version, fork config, advertised or explicit EIP maturity metadata, stability rollup, human caveat.
  • Boundaries — raw bytecode or impersonated transaction fields plus constructed prestate; no Solidity compile; no archive node; no multi-block historical backtesting.

See also Design Principles.

Public API (v0.1)

ExportRole
simulateBytecode(input)Run bytecode under a fork config; optional opcode trace
runTransaction(input)Run a value-bearing transaction (paid gas, receipt logs)
runBlock(input)Run 1–8 txs as a lab block (header snapshot + per-tx receipts)
describeCapabilities()Registry snapshot — named fork capabilities + runnable EIP modules (opcodes, encoding, no demos)
listEipModules()Live EIP module list (source of the catalog)
buildCommon(config)Resolve (baseHardfork, eips[]) → EthereumJS Common

Input / output

typescript
// SimulateBytecodeInput
{
  bytecode: string
  accounts?: { address: string; balance?: string; code?: string; storage?: { slot: string; value: string }[] }[]
  fork?: { baseHardfork: string; eips?: number[] }
  gasLimit?: string
  trace?: boolean
}

// SimulateBytecodeResult — gasUsedScope: 'call-frame'
// Optional stateGasSpilled when Amsterdam spills EIP-8037 state gas into the frame.

// RunTransactionInput
{
  from: string
  to: string
  value?: string
  data?: string
  code?: string
  accounts?: { address: string; balance?: string; code?: string; storage?: { slot: string; value: string }[] }[]
  fork?: { baseHardfork: string; eips?: number[] }
  gasLimit?: string
}

// RunTransactionResult — gasUsedScope: 'transaction'
// gasUsed is paid tx gas. Amsterdam may include txRegularGas / txStateGas.

// RunBlockInput
{
  transactions: { from: string; to: string; value?: string; data?: string; code?: string; gasLimit?: string }[]
  header?: { slotNumber?: string; number?: string; timestamp?: string }
  accounts?: { address: string; balance?: string; code?: string; storage?: { slot: string; value: string }[] }[]
  fork?: { baseHardfork: string; eips?: number[] }
}

// RunBlockResult — gasUsedScope: 'block'
// header.gasUsed is the generated header field (Amsterdam may be the 8037 state-gas dimension).
// Paid gas / logs live on transactions[].

Ceilings (guardrails)

LimitValue
Max gas limit30_000_000
Default gas limit1_000_000
Max bytecode size24_576 bytes
Max trace steps10_000
Max transactions per lab block8

Registered capabilities (live)

EIPNatureRunnableShapes
8024new-capabilityyessimulate
7843new-capabilityyesblock
7708new-capabilityyestransaction, simulate
7883repricingyessimulate
7951new-capabilityyessimulate
8037new-exec-modelyestransaction, simulate
8038repricingyessimulate, transaction

Only runnable modules appear in describeCapabilities().eips. Named forks appear in namedForks with advertised relatedEips. Wallet / receipt questions use transaction; opcode / precompile questions use simulate; header slot / multi-tx questions use block. A generic Amsterdam run uses the same verbs with empty eips[].

Amsterdam in EthereumJS v10 already bundles EIP-8024 and EIP-7843 — eips: [8024] / eips: [7843] are not pre/post toggles. Use osaka baseline vs amsterdam preview for those comparisons.

Development

See Quality.

Changelog

Execution Engine Changelog
  1. v0.1.112026-09-16Named forks are catalog capabilities; generic-run provenance lists advertised modules.
  2. v0.1.92026-09-14Boundaries: isolated lab / constructed prestate; historical backtesting still out.
  3. v0.1.82026-09-14EIP-8038 state-access module; accounts[].storage seed; SSTORE via runTransaction.
  4. v0.1.72026-09-10EIP-7843 SLOTNUM module — runBlock header.slotNumber; catalog row live.
  5. v0.1.62026-09-10runBlock lab verb — header snapshot, per-tx receipts, optional slotNumber.
  6. v0.1.52026-09-08runTransaction (VM tx path); paid gas, 8037 dimensions, 7708 receipt logs.
  7. v0.1.42026-09-08Simulate result: gasUsedScope plus messageCall approxTxGasUsed (21000 + call-frame).
  8. v0.1.32026-08-27Osaka mainnet baseline fork; baselineForkId and EIP comparison pairs in probe.
  9. v0.1.22026-08-27Removed compareVariants — agents call simulateBytecode twice to diff.
  10. v0.1.12026-08-27EIP module catalog (8024 opcodes/encoding only); stub EIPs and demo scenarios removed.
  11. v0.1.02026-07-20Initial engine — simulateBytecode, registry, provenance, compareVariants composer, seed presets.

Use = end-user reference. Internals = architecture and operations. Each section carries its own micro-changelog.