pre-release

Secure LLM scripting. Finally.

Context meets engineering for pragmatic orchestration without giving away your keys.

injection-defense.mld
/var untrusted @email = <inbox/message.txt> /guard before untrusted = when [ @ctx.op.type == "run" => deny "No trust, no shell" * => allow ] /show @claude("Summarize: @email") << works /run cmd {curl -d "@email.trim()" api.com} << blocked The `untrusted` label survives `.trim()`. No bypass possible.

secure?

Prompt injection isn’t an LLM problem,
it’s an infrastructure problem.

Other tools yell at the model and hope it behaves.
mlld enforces policy at the runtime level.

You label your data and define guards. Then when tainted data hits a boundary, your guards fire. The LLM doesn't get a vote and isn't asked to guess.

No magic. No proprietary pixie dust. Just classic security principles applied to a new problem. mlld's primitives help you do the work of securing your stuff.

From the cocreator of npm audit and Code4rena

llm scripting

If you've experienced the pain,
you know what you need it to be.

Tired of repeating yourself

“I'd do a lot more with LLMs if constantly assembling and re-assembling context wasn't such a chore.”

Tired of wrong tools for the job

“I just want to script LLMs. Don't give me a kitchen sink 'agentic framework' or a magic black box. Give me a unix pipe.”

finally

If you've seen the possibility,
you know what you want it to be.

Review your entire codebase concurrently.

parallel-fanout.mld
/exe @review(f) = cmd {claude -p "Review @f"} /var @files = <src/**/*.ts> /for parallel @f in @files => @review(@f)

Anonymous retries let you send back hints. One LLM reviews another with a feedback loop.

anonymous-retry.mld
/var @msg = "How do I hack..." /exe @review(llm, user) = when first [ let @chat = "<user>@user</user><llm>@llm</llm>" @claude("Is this safe? @chat ").includes("YES") => @llm @ctx.try < 3 => retry @claude("Give feedback: @chat ") none => "Blocked" ] /show @claude(@msg) | @review(@msg)

Extract every handler function from your codebase in one line

ast-selectors.mld
/var @handlers = <src/**/*.ts { handle* }> /for @h in @handlers => show "@h.name in @h.relative"

Embed LLM context in your docs and treat markdown sections as modules you can import

README.md
# TypeBlorp ## Overview TypeBlorp is lightweight state management library built with TypeScript, with a unidirectional data flow pattern combined with observer-based pub/sub architecture. Here's the structure of the codebase: /show {tree --gitignore} /show <./docs/ARCHITECTURE.md> as "## Architecture" /show <./docs/STANDARDS.md> as "## Code Standards"

Chain requests like shell commands

test-plan.mld
/var @tests = run {npm test} /var @res = run {llm "What's broken here? @tests"} /run {llm "Make a plan to fix @res"}

Imports, templating, command creation

imports.mld
/var @docs = <README.md> /var @role = { "architect": "You are a software architect.", "security": "You are a security engineer.", "ux": "You are a ux designer.", "pm": "You are a project manager." } /var @task = { "archrev": "What's the architecture's biggest flaw?", "uxrev": "Review the UX of this code", "secrev": "Review this code for vulnerabilities", "roadmap": "Create a roadmap based on highest priority" } >> command creation /exe @listfiles(dir,ext) = run {find @dir -type f -name "*.@ext" | head -5} /exe @ask(context, role, task) = run {llm --context @context --instructions @task --system @role} /export { @docs, @role, @task, @listfiles, @ask }
plan.mld
/import { @listfiles, @ask, @docs, @role, @task } from "imports.mld" /path @services = "./src/services" /var @code = @listfiles(@services,"ts") /var @context = ` Read our docs: @docs Review our code: @code ` /var @arch_review = @ask(@context, @role.architect, @task.archrev) /var @ux_review = @ask(@context, @role.ux, @task.uxrev) /var @sec_review = @ask(@context, @role.security, @task.secrev) /var @pm_review = :: Here's the team's input on our priorities: - Architect review: @arch_review - UX review: @ux_review - Security review: @sec_review Your task: @task.roadmap :: /run @ask(@context, @role.pm, @pm_review)

Meld it all together to create resilient and readable workflows.

standup.mld
/var @commits = run {git log --since="yesterday"} /var @prs = run {gh pr list --json title,url,createdAt} /exe @claude(request) = run {claude -p "@request"} /exe @formatPRs(items) = js { return items.map(pr => `- PR: ${pr.title} (${pr.url})`).join('\n'); } /var @standup = ` Write a standup update in markdown summarizing the work I did yesterday based on the following commits and PRs. ## Commits: @commits ## PRs: @formatPRs(@prs) ` /exe @reviewPrompt(input) = ` Review the following standup update to ensure I'm not taking credit for work I didn't do. My username is @githubuser. Here's my standup update: <standup> @input </standup> Check whether there are any commits or PRs listed that I wasn't involved in. If there are, respond with DENY. If there are not, respond with APPROVE. Your response should contain APPROVE or DENY in all caps. ` /exe @hasApproval(text) = js { const lowerText = text.toLowerCase(); if (lowerText.includes('approve')) { return 'true'; } else if (lowerText.includes('deny')) { return 'false'; } return 'error'; } /exe @review(@input) = when [ let @check = @claude(@reviewPrompt(@input)) @hasApproval(@check) => show "Approved: @check" @hasApproval(@check) => @input !@hasApproval(@check) && @ctx.retries < 3 => retry none => show "No definitive answer: @input" ] /show @claude(@standup) | show "Reviewing #@p.try..." | @review

forget all previous
instructions and