Connects Claude to the Simple language toolchain with stdio transport. Exposes code intelligence (likely LSP-style queries), debugging hooks, build and test execution, and version control operations for a self-hosted language that combines Python-like syntax with compiler-integrated testing, borrow checking, and baremetal execution paths. Reach for this when working with Simple codebases that span its unusually broad surface: the repo includes a staged compiler, interpreter, SPipe BDD tests, SDoctest executable docs, LLVM and VHDL backends, and hardware test flows with QEMU and remote baremetal lanes. The MCP server presumably wraps Simple's native tooling (compiler driver, test runner, architecture linting) so Claude can navigate source layers, run verification suites, and interact with the SDN-backed project databases that store tests and traceability metadata.
Simple is a self-hosted language and toolchain that combines a readable Python-like surface with compiler-integrated testing, documentation, architecture rules, and baremetal-oriented execution paths.
The repo is unusually broad: language, compiler, interpreter, loader, test runner, doc generation, traceability tooling, SDN-backed project databases, editor tooling, and hardware-oriented test flows all live together.
Quick Navigation: Distinctive Features | Feature Status | Quick Start | Language Basics | Examples | Editor Plugins | Documentation
m{}, loss{}, and nograd{} are implemented syntax with parsing, evaluation, five rendering backends (text, debug, Unicode, LaTeX, Markdown), and editor integration (query/LSP hover, VSCode highlighting/preview, Neovim inline Unicode preview with conceal). The autograd path is complete for the promoted torch-backed C/LLVM scope.UITestClient drives both the web backend and the TUI-web proxy through a shared handle_test_request handler, verified by a cross-surface contract suite. Contract: doc/04_architecture/shared_ui_contract.mdImplemented and safe to advertise:
Implemented, but best described with qualifiers:
llvm-lib and llvm backend row is now explicitly stable or unsupported, with no ambiguous middle states. rust-llvm remains a bootstrap-only seed path outside the public family claimcommon, nogc_sync_mut, nogc_async_mut, gc_async_mut, nogc_async_mut_noalloc) with compiler boundary enforcement, interpreter warnings, and target preset mapping. Support matrix: doc/04_architecture/runtime_family_support_matrix.mdImplemented with bounded scope:
m{} / loss{} / nograd{} are complete for the promoted torch-backed C/LLVM scope, including backward, detached-input failure, and nograd{} restore semantics. Other backends remain deferredexecution, within, attr), deterministic before/after/around advice, compile-time weaving as the default backend, and scoped runtime interception. Support matrix: doc/05_design/aop_support_matrix.mdImplemented:
simple lint, simple verify quality). All public-facing proof suites (SFFI, T32 hardware, compiler/runtime/system) now pass the gate. Remaining debt is only in deferred OS/GPU/experimental areas — all active surfaces are clean.See doc/report/unique_features.md for the evidence-backed audit.
Simple organizes its standard library into runtime families based on allocation, mutation, and concurrency requirements:
| Family | Allocation | Mutation | Async | Use Case |
|---|---|---|---|---|
common | heap (default) | immutable | no | Pure functions, math, text, encoding |
nogc_sync_mut | heap/arena/pool | mutable | no | File I/O, networking, FFI, databases |
nogc_async_mut | heap | mutable | yes | Async I/O, threads, actors, generators |
gc_async_mut | GC-managed | mutable | yes | GPU/CUDA, ML pipelines |
nogc_async_mut_noalloc | stack only | mutable | yes | Baremetal, embedded, RTOS |
The compiler enforces family boundaries: importing a GC module from a no-GC context produces a diagnostic warning. Target presets (Baremetal, Hosted, EmbeddedWithHeap) automatically restrict module resolution to compatible families.
For advanced use: nogc_async_immut provides persistent data structures with lock-free concurrency.
See Runtime Family Support Matrix for full contracts, and Known Limitations for current caveats.
What you get:
Use a source checkout for the current beta. It also initializes the example and tooling submodules used by the docs and tests:
git clone --recurse-submodules https://github.com/ormastes/simple.git
cd simple
export PATH="$PWD/bin:$PATH"
simple --version
For an existing checkout:
git submodule sync --recursive
git submodule update --init --recursive
Note: Rust remains present as the bootstrap seed and host substrate. Product compiler, library, and tool work should stay in Simple source wherever the repo can express it; do not read "pure Simple" as "there is no Rust source in this checkout" today.
Snapshot generated 2026-04-23 from existing tracked .spl, .rs, .c, .h, .s, .S, and .asm files. Blank lines and comment-only lines are excluded; examples/ code is included; vendored and third-party source is excluded.
| Language | Files | Non-comment LOC | src/ LOC | examples/ LOC | test/ LOC | Other LOC |
|---|---|---|---|---|---|---|
| Simple | 13,286 | 1,780,334 | 887,121 | 158,796 | 712,254 | 22,163 |
| Rust | 1,633 | 411,106 | 409,852 | 11 | 0 | 1,243 |
| C | 158 | 73,854 | 14,953 | 58,859 | 36 | 6 |
| Assembly | 60 | 4,758 | 1,554 | 3,173 | 31 | 0 |
| Total | 15,137 | 2,270,052 | 1,313,480 | 220,839 | 712,321 | 23,412 |
Only needed if you want to modify the runtime:
scripts/setup/setup.shs
bin/simple build bootstrap
Direct commands behind the wrapper:
src/compiler_rust/target/bootstrap/simple --version
bin/simple build bootstrap
sha256sum bootstrap/simple_stage2 bootstrap/simple_stage3
See doc/02_requirements/app/build/bootstrap.md and doc/03_plan/compiler/bootstrap/pure_simple_bootstrap_stage2_remaining_2026-05-04.md for the current bootstrap flow and remaining pure-Simple self-hosting notes.
simple build --release --features=vulkan
# hello.spl
>>> fn main() -> i64:
... 0 # Entry point, returns exit code
# Run it
simple hello.spl
echo $? # Prints: 0
The simple command works like Python:
Usage:
simple Start interactive REPL
simple <file.spl> Run source file
simple <file.smf> Run compiled binary
simple -c "code" Run code string; statement snippets print only program output
simple compile <src> [-o <out>] Compile to SMF
simple watch <file.spl> Watch and auto-recompile
Build System (Self-Hosting):
simple build Build the project (debug)
simple build --release Release build (optimized)
simple build --bootstrap Bootstrap build (minimal 9.3MB)
simple build test Run all tests
simple build coverage Generate coverage reports
simple build lint Run linter (clippy)
simple build fmt Format code (rustfmt)
simple build check Run all quality checks
simple build clean Clean build artifacts
simple build --help Show all build options
Options:
-h, --help Show help
-v, --version Show version
-c <code> Run code string
--gc-log Enable verbose GC logging
--gc=off Disable garbage collection
# Interactive REPL
simple
>>> 1 + 2
3
>>> x = 10
>>> x * 5
50
>>> exit
# Run a program
echo "main = 42" > hello.spl
simple hello.spl
echo $? # Exit code: 42
# Compile to binary
simple compile hello.spl
simple hello.smf # Run the compiled binary
# Watch mode (auto-recompile on changes)
simple watch app.spl
# Variables - immutable by default, mutable with var
>>> x = 10
>>> x
10
>>> var y = 20
>>> y
20
>>> PI = 3.14159
>>> PI
3.14159
# Type inference works automatically
>>> count = 100
>>> count
100
# Basic types inferred
>>> a = 42
>>> a
42
>>> pi = 3.14159
>>> flag = true
>>> flag
true
# String interpolation default
>>> name = "world"
>>> msg = "Hello, {name}!"
>>> print msg
Hello, world!
# If/else with indentation
>>> var x = 5
>>> if x > 0:
... print "positive"
... elif x < 0:
... print "negative"
... else:
... print "zero"
positive
# Loops
>>> for i in 0..3:
... print i
0
1
2
>>> while x > 3:
... x = x - 1
>>> x
3
>>> fn add(a: i64, b: i64) -> i64:
... a + b # Implicit return
>>> fn greet(greeting: text):
... print "Hello, {greeting}!"
# Function calls
>>> sum = add(1, 2)
>>> sum
3
>>> greet("Alice")
Hello, Alice!
# Lambdas with backslash
>>> double = \x: x * 2
>>> nums = [1, 2, 3, 4, 5]
>>> evens = nums.filter(\x: x % 2 == 0)
>>> evens
[2, 4]
# Structs (value types)
struct Point:
x: f64
y: f64
p = Point(x: 1.0, y: 2.0)
# Classes (reference types)
class Person:
name: text
age: i64
fn greet():
print "Hi, {self.name}!"
alice = Person(name: "Alice", age: 30)
alice.greet()
# Arrays - short form (no val)
>>> nums = [1, 2, 3, 4, 5]
>>> first = nums[0]
>>> first
1
# Collection methods
>>> count = nums.len()
>>> count
5
# Dictionary (short form)
>>> scores = {"alice": 100, "bob": 85}
>>> alice_score = scores["alice"]
>>> alice_score
100
# Filter with lambda
>>> odds = nums.filter(\x: x % 2 == 1)
>>> odds
[1, 3, 5]
>>> big_nums = nums.filter(\x: x > 3)
>>> big_nums
[4, 5]
# Tuples
>>> pair = (1, "hello")
>>> num = pair.0
>>> num
1
>>> msg = pair.1
>>> msg
"hello"
# List comprehensions
>>> squared = [x * x for x in 0..5]
>>> squared
[0, 1, 4, 9, 16]
>>> evens = [x for x in nums if x % 2 == 0]
>>> evens
[2, 4]
Type-safe units prevent mixing incompatible values:
# Define measurement unit families with postfix syntax
unit length(base: f64):
mm = 0.001, cm = 0.01, m = 1.0, km = 1000.0
unit velocity(base: f64) = length / time:
mps = 1.0, kmph = 0.2777777777777778, mph = 0.44704
# The standards-backed catalog records km/h canonically as kilometre / hour
# with exact factor 5/18 relative to m/s.
# Define nominal wrappers with postfix syntax
newunit UserId: i64 as uid
newunit OrderId: i64 as oid
# Usage with postfix literals
height = 175_cm # Length type
width = 10_cm + 5_mm # Auto-converts to same base
speed = 200_kmph # Velocity type
distance = 42_km # Length type
# Type safety - compile error:
# bad = height + speed # Error: can't add Length + Velocity
# Semantic IDs prevent mix-ups
user = 42_uid # UserId
order = 100_oid # OrderId
# wrong: UserId = 100_oid # Error: OrderId ≠ UserId
# Computed units
travel_time = distance / speed # Returns Time type
print("ETA: {travel_time.to_min()} minutes")
enum Shape:
Circle(radius: f64)
Rectangle(width: f64, height: f64)
Square(side: f64)
Triangle(base: f64, height: f64)
# Pattern matching with case syntax
fn area(s: Shape) -> f64:
match s:
case Circle(r):
3.14159 * r * r # Implicit return
case Rectangle(w, h):
w * h
case Square(side):
side * side
case Triangle(b, h):
0.5 * b * h
# Preferred arrow syntax (shorter)
fn perimeter(s: Shape) -> f64:
match s:
| Circle(r) -> 2.0 * 3.14159 * r
| Rectangle(w, h) -> 2.0 * (w + h)
| Square(side) -> 4.0 * side
| Triangle(a, b, c) -> a + b + c
# Pattern matching with nil (not None)
fn get_radius(opt: Option<f64>) -> f64:
match opt:
| Some(r) -> r
| nil -> 0.0 # Use nil instead of None
Simple macros are contract-first and LL(1) parseable - the IDE can provide autocomplete without expanding the macro:
# Macro declares what it introduces in the contract header
macro define_counter(NAME: Str const) -> (
returns result: (init: Int, step: Int),
intro counter_fn: enclosing.class.fn "{NAME}Counter"(start: Int) -> Int
):
const_eval:
const init = 0
const step = 1
emit counter_fn:
fn "{NAME}Counter"(start: Int) -> Int:
start + step
# Usage - IDE knows about UserCounter before expansion
class Demo:
define_counter!("User")
fn run() -> Int:
self.UserCounter(10) # Autocomplete works!
Built-in macros:
# Print with formatting
println!("Hello, {name}!") # Print with newline
print!("Value: {x}") # Print without newline
# Debug output with source location
dbg!(expression) # Prints: [file:line] expression = value
# Assertions
assert!(condition) # Panic if false
assert_eq!(a, b) # Panic if a != b
assert_ne!(a, b) # Panic if a == b
# Collections
nums = vec![1, 2, 3, 4, 5] # Create vector
formatted = format!("x={x}") # Format string without printing
# Panic with message
panic!("Something went wrong: {err}")
Const-unrolled macro (generate multiple functions):
# Generate accessor functions for each axis
macro gen_axes(BASE: Str const, N: Int const) -> (
intro axes:
for i in 0 .. N:
enclosing.class.fn "{BASE}{i}"(v: Vec[N]) -> Int
):
emit axes:
for i in 0 .. N:
fn "{BASE}{i}"(v: Vec[N]) -> Int:
v[i]
# Usage: generates x(), y(), z() accessors
class Point3D:
gen_axes!("axis_", 3) # Creates axis_0, axis_1, axis_2
Predicate-based pointcuts with compile-time weaving as the default execution model:
# Before advice — runs before matching functions
on pc{ execution(* handle_request(..)) } use log_entry before priority 10
# After advice — runs after successful return
on pc{ execution(* save(..)) & attr(audited) } use audit_write after_success priority 20
# Around advice — wraps function with proceed() contract
on pc{ within(services.*) } use trace_around around priority 50
# Architecture rules — enforce layer dependencies at compile time
forbid pc{ within(hal.*) } "HAL cannot depend on services"
allow pc{ within(services.*) } "Services can use HAL"
Supported selectors: execution(*), within(*), attr(*) with & (AND), | (OR), ! (NOT) operators.
Advice kinds: before, after_success, after_error, around (proceed exactly-once).
Ordering: priority (descending) > specificity > lexicographic name.
Zero overhead: no weaving metadata when no aspects are defined.
Runtime interception: scoped, opt-in only, disabled in release builds.
See AOP Support Matrix for the full contract.
Simple Data Notation - a minimal, token-efficient format for config files:
# app.sdn - Application configuration
app:
name: MyService
version: 2.1.0
server:
host: 0.0.0.0
port: 8080
workers: 4
# Inline arrays and dicts
features = [auth, logging, metrics]
database = {driver: postgres, host: localhost, port: 5432}
# Named tables - compact tabular data
rate_limits |endpoint, requests, window|
/api/login, 5, 60
/api/search, 100, 60
/api/upload, 10, 300
Load SDN in Simple:
config = sdn::load("app.sdn")
print("Server port: {config.server.port}")
Executable examples are part of the maintained test surface. Simple supports both demonstration blocks and verified sdoctest blocks, with sdoctest intended for examples that must run and match output.
>>> factorial(5)
120
>>> factorial(0)
1
## Stack data structure with LIFO semantics
struct Stack:
items: [i64]
var s = Stack(items: [])
s.items.push(1)
s.items.push(2)
print s.items.len() # 2
Run SDoctest examples:
simple test --sdoctest README.md # Run verified examples in Markdown/docs
simple test --sdoctest src/math.spl # Run file-local doctest examples
simple test --sdoctest --tag slow # Filter by tag
--doctest is still accepted as a compatibility alias, but --sdoctest is the clearer name for the implemented path.
->)# The -> operator calls a method and assigns result back
var data = load_data()
data->normalize() # data = data.normalize()
data->filter(min: 0) # data = data.filter(min: 0)
# Chaining
data->normalize()->filter(min: 0)->save("out.txt")
import std.gpu
# GPU kernel style 1: #[gpu] with explicit bounds check
#[gpu]
fn vector_add_kernel(a: []f32, b: []f32, result: []f32):
idx = gpu.global_id(0) # Global thread index
if idx < len(result):
result[idx] = a[idx] + b[idx]
# GPU kernel style 2: @simd with auto bounds handling
@simd
fn vector_scale(data: []f32, scale: f32):
val i = this.index() # Global linear index (same as gpu.global_id())
data[i] = data[i] * scale # Bounds auto-handled
# Host function - runs on CPU
fn main():
device = gpu.Device()
# Allocate and upload data
a = [1.0, 2.0, 3.0, 4.0]
b = [5.0, 6.0, 7.0, 8.0]
buf_a = device.alloc_buffer(a)
buf_b = device.alloc_buffer(b)
buf_result = device.alloc_buffer<f32>(4)
# Launch kernel
device.launch_1d(vector_add_kernel, [buf_a, buf_b, buf_result], 4)
# Download results
device.sync()
result = device.download(buf_result)
# result = [6.0, 8.0, 10.0, 12.0]
GPU Thread Indexers:
#[gpu]
fn matrix_multiply(A: []f32, B: []f32, C: []f32, N: u32):
# Multi-dimensional indexing
val row = gpu.global_id(0) # First dimension
val col = gpu.global_id(1) # Second dimension
# Thread group (workgroup) info
val local_row = gpu.local_id(0) # Index within workgroup
val group_row = gpu.group_id(0) # Workgroup index
# Alternative @simd style
# val(row, col) = this.index() # Tuple for 2D
# vallocal_idx = this.thread_index()
# valgroup_idx = this.group_index()
if row < N and col < N:
var sum = 0.0_f32
for k in 0..N:
sum += A[row * N + k] * B[k * N + col]
C[row * N + col] = sum
GPU Examples: See examples/gpu/vulkan/ for vector add, matrix multiply, reduction, and image blur.
| Topic | Description | Link |
|---|---|---|
| Docs Hub | Numbered documentation index | doc/README.md |
| Language Spec | Executable and generated specs | doc/06_spec/README.md |
| Guides | Practical how-to guides | doc/07_guide/README.md |
| Plans | Implementation roadmap | doc/03_plan/README.md |
| Research | Design explorations | doc/01_research/README.md |
| Architecture | System design principles | doc/04_architecture/README.md |
| Tracking | Bugs, tests, and todo tracking | doc/08_tracking/README.md |
| Reports | Session and milestone reports | doc/09_report/README.md |
| Deep Learning | Neural networks and GPU computing | doc/07_guide/deep_learning/deep_learning.md |
Getting Started:
Language Reference:
GPU Computing:
Development:
step(...), inline scenarios, capture, and generated manual styleAdvanced Features:
Simple ships multiple deep learning examples across pure-Simple, model-training, and GPU-oriented flows:
Pure Simple Neural Networks:
# XOR neural network training
bin/simple examples/pure_nn/xor_training_example.spl
# Linear regression (learns y = 2x + 1)
bin/simple examples/pure_nn/simple_regression.spl
# Iris flower classification
bin/simple examples/pure_nn/iris_classification.spl
MedGemma Korean Fine-Tuning:
# Progressive LoRA training to prevent catastrophic forgetting
bin/simple examples/medgemma_korean/run_all.spl
CUDA Programming:
# Direct CUDA C API - multi-GPU, streams, events
bin/simple examples/cuda/basic.spl
See Deep Learning Guide for current documentation.
The examples/ directory contains additional working examples:
| Example | Description |
|---|---|
cli_demo.spl | Command-line argument parsing |
file_async_basic.spl | Async file I/O operations |
ui_todo_app.spl | Cross-platform UI application |
vulkan_triangle.spl | GPU rendering with Vulkan |
async_tcp_echo_server.spl | Async TCP networking |
Run an example:
bin/simple examples/cli_demo.spl
Feature and system documentation is generated from executable SSpec .spl
scenarios. SPipe is the related runner/docgen process; SSpec is the authoring
style: write readable step("...") actions, keep executable assertions in the
same scenario, and let docgen render compact manual steps with folded source.
use std.spec.*
describe "Dashboard actions":
# @inline
it "operator has an authenticated session":
step("Open the sign-in page")
step("Submit valid credentials")
it "operator reviews dashboard actions":
# @include("operator has an authenticated session")
step("Open the actions panel")
expect("actions").to_equal("actions")
Generated manual:
1. Open the sign-in page
2. Submit valid credentials
3. Open the actions panel
- Expected: "actions" equals `actions`
Given_*, When_*, and Then_* helper naming is legacy style. Use
step("...") for new SSpec manuals. See the
SSpec Scenario Manual Guide.
Generated docs land in the numbered documentation tree, primarily under doc/06_spec/, so the checked examples stay close to the current spec artifacts.
Simple’s current language references are split between the guide tree for user-facing explanations and the spec tree for executable or generated reference material.
Current Reference Documents:
Quick Grammar Reference:
# Top-level
program ::= statement*
# Statements
statement ::= function_def | class_def | struct_def | enum_def
| import_stmt | export_stmt | expr_stmt
# Expressions (Pratt parser)
expr ::= literal | identifier | binary_op | unary_op
| call | index | field_access | lambda
| if_expr | match_expr | block
# Types
type ::= identifier | array_type | tuple_type | fn_type
| optional_type | result_type | generic_type
# Literals
literal ::= integer | float | string | bool | array | dict | tuple
The current spec and guide material is organized under the numbered documentation tree:
Core Language:
Advanced Features:
Testing & Tooling:
GPU & Platform:
See doc/README.md, doc/06_spec/README.md, and doc/07_guide/README.md for the current documentation entry points.
simple/
├── bin/ # CLI entry points
│ ├── simple # Main CLI (shell wrapper)
│ └── release/ # Pre-built release binaries
│ └── simple # Pre-built runtime (33 MB)
│
├── src/ # Simple source code (100% Simple)
│ ├── app/ # Applications
│ │ ├── cli/ # Main CLI dispatcher
│ │ ├── build/ # Self-hosting build system
│ │ ├── mcp/ # MCP server (Model Context Protocol)
│ │ ├── lsp/ # Language server protocol
│ │ ├── io/ # SFFI wrappers (file, process, etc.)
│ │ └── ... # 50+ tool modules
│ ├── lib/ # Libraries
│ │ ├── database/ # Unified database (BugDB, TestDB, etc.)
│ │ └── pure/ # Pure Simple DL (tensor, autograd, nn)
│ ├── std/ # Standard library
│ │ ├── src/ # Library source
│ │ └── test/ # Library tests
│ └── compiler/ # Compiler infrastructure
│ ├── backend/ # Code generation
│ ├── inference/ # Type inference
│ └── parser/ # Parser and treesitter
│
├── examples/ # Example programs
│ ├── pure_nn/ # Deep learning examples
│ └── gpu/vulkan/ # GPU computing examples
│
├── test/ # Test suites
│ ├── integration/ # Integration tests
│ ├── system/ # System tests
│ └── intensive/ # Intensive feature tests
│
├── doc/ # Documentation
│ ├── spec/ # Language specifications
│ ├── guide/ # User guides
│ ├── design/ # Design documents
│ └── report/ # Session reports
│
└── src/verification/ # Lean 4 formal verification
# Debug build
simple build
# Release build
simple build --release
# With GPU support
simple build --release --features=vulkan
# Bootstrap build (minimal 9.3MB)
simple build --bootstrap
Full-suite snapshot (2026-02-14): 4,067/4,067 passing
Simple uses a broad test strategy spanning spec tests, SDoctest, coverage, and system lanes. The counts below are from the linked 2026-02-14 report:
# All tests (4,067 tests in 17.4 seconds)
simple test
# Run specific test file
simple test path/to/spec.spl
# With verbose output
simple test --verbose
# Coverage reports
simple build coverage
Test Coverage:
Performance:
Performance Profiles:
See doc/09_report/session/full_test_suite_results_2026-02-14.md for detailed test analysis.
# Check before commit (fmt + lint + test)
simple build check
# Full check (includes coverage + duplication)
simple build check --full
# Format code
simple build fmt
# Lint
simple build lint
Simple ships with MCP servers, LSP servers, and Claude Code plugins — all written in Simple.
The Simple MCP server exposes repo-native tools for code diagnostics, VCS, build, test, debug, and related workflows. For current registration details, use the repo scripts and guide docs rather than relying on hardcoded counts here.
# From a repo checkout — register with Claude Code
claude mcp add simple-mcp -- \
/absolute/path/to/simple/bin/simple \
/absolute/path/to/simple/src/app/mcp/main.spl
# Or use the project .mcp.json (auto-detected by Claude Code)
sh config/mcp/install.shs
The simple-mcp Claude plugin is a repo-checkout plugin. Install it from a
Simple repository checkout; it is not a standalone portable runtime bundle.
claude plugin marketplace add tools/claude-plugin/marketplace
claude plugin install simple-mcp@simple-local
The plugin launches bin/simple_mcp_server from the repository root.
The Simple language server provides completions, hover, go-to-definition, diagnostics, and semantic tokens for .spl / .shs files.
# From a repo checkout
claude plugin marketplace add tools/claude-plugin/marketplace
claude plugin install simple-lsp@simple-local
Binary full path: bin/simple run src/app/lsp/main.spl
cd /path/to/simple
# 1. MCP server
sh config/mcp/install.shs
# 2. LSP plugin
claude plugin marketplace add tools/claude-plugin/marketplace
claude plugin install simple-lsp@simple-local
Once the MCP server and LSP plugin are installed, try these prompts in Claude Code:
> "Run the linter on src/app/cli/main.spl and fix any warnings"
> "Show me all unused variables in the compiler frontend"
> "Run the unit tests for the SDN parser"
> "Build the project in release mode and show the result"
> "What does the function `parse_expression` in the parser do?"
> "Find all TODO items in the codebase"
> "Check the doc coverage for the standard library"
> "Debug why test/01_unit/lib/common/value_spec.spl is failing"
Full-featured extension with Tree-sitter highlighting, LSP integration, and math block support.
cd src/app/vscode_extension
npm install && npm run compile && npm run package
code --install-extension simple-language-0.1.0.vsix
Key features:
m{}, loss{}, nograd{} with nested brace supportdescribe/it/context/sdoctest blocksSee src/app/vscode_extension/README.md for full documentation.
-- lazy.nvim
{ "nicholasgasior/simple.nvim", ft = "simple", opts = {} }
-- Or from project checkout
vim.opt.rtp:prepend("/path/to/simple/src/app/nvim_plugin")
require("simple").setup()
Key features:
frac(1,2) -> (1)/(2), alpha -> α, sqrt(x) -> √(x))See src/app/nvim_plugin/README.md for full documentation.
MCP servers, CMM language server, and CLI tools for Lauterbach TRACE32 debuggers. See examples/10_tooling/trace32_tools/README.md for full documentation.
The repo-managed container flow is headless and uses t32mciserver. It does
not ship bundled TRACE32 GUI compatibility libraries; vendor runtime files must
come from your local /opt/t32 installation.
Primary lifecycle wrapper:
scripts/t32q.shs build
scripts/t32q.shs on
scripts/t32q.shs wait
scripts/t32q.shs ping
scripts/t32q.shs reopen
scripts/t32q.shs off
GUI container reopen path:
scripts/t32q.shs gui-on
scripts/t32q.shs gui-reopen
scripts/t32q.shs off
gui-on uses the Docker/Podman TRACE32 GUI path with host X11 forwarding, so
it requires a real host X11 session (DISPLAY, /tmp/.X11-unix, and usually
XAUTHORITY). For quick diagnostics use:
scripts/t32q.shs doctor
Hello-world firmware smoke:
scripts/t32_semihost_hello.shs --board stm32wb
scripts/t32_semihost_hello.shs --board stm32h7
scripts/t32_semihost_hello.shs --board stm32wb --build-only
These TRACE32 MCP servers are not installed by the default project MCP setup. Register them manually only if you actively use TRACE32 tooling.
cd /path/to/simple
# T32 MCP — controls live TRACE32 debug sessions (23 tools)
claude mcp add t32-mcp -- \
/absolute/path/to/simple/bin/simple \
/absolute/path/to/simple/examples/10_tooling/trace32_tools/t32_mcp/main.spl
# T32 LSP MCP — CMM script analysis, no hardware needed (6 tools)
claude mcp add t32-lsp-mcp -- \
/absolute/path/to/simple/bin/simple \
/absolute/path/to/simple/examples/10_tooling/trace32_tools/t32_lsp_mcp/main.spl
Binary full paths:
bin/simple run examples/10_tooling/trace32_tools/t32_mcp/main.splbin/simple run examples/10_tooling/trace32_tools/t32_lsp_mcp/main.splclaude plugin marketplace add tools/claude-plugin/marketplace
claude plugin install cmm-lsp@simple-local
Binary full path: bin/simple run examples/10_tooling/trace32_tools/cmm_lsp/mod.spl --lsp
> "Parse this CMM script and check for errors: config/t32/stm32h7_gdb_start.cmm"
> "Connect to TRACE32 on localhost:20000 and read the CPU registers"
> "Show me all labels and macros defined in my CMM script"
> "Convert this GUI PRACTICE script to CLI batch mode"
> "Check if my CMM script has any undefined macros or unreachable code"
> "Set a breakpoint at main, run to it, and show local variables"
> "What TRACE32 commands are available for memory access?"
> "Auto-complete suggestions for 'Data.LOAD' in my CMM script"
See CLAUDE.md for development guidelines and AGENTS.md for AI agent instructions.
Documentation Structure:
Apache License 2.0. See LICENSE.
Bundled third-party runtime components and redistribution notices are listed in THIRD_PARTY_NOTICES.md.
Release packages also include THIRD_PARTY_NOTICES.md.
Official Documentation:
Quick References:
Development: