Margarita turns Markdown scripts into full agentic workflows. Declare variables, call your LLM, and pass results between steps — all in repeatable scripts you can read and understand at a glance.
Why Margarita
Run the same script using Ollama, Copilot (adding more). Your script stays exactly the same.
margarita use ollamaMost AI code harnesses hide the context from you. Margarita gives you complete control. Add only the tools you need. Run Python functions locally and update the context instead of burning tokens on tool calls.
@effect context clearWrite a reusable prompt component and reuse it in your other scripts. Need to change it across your org? Just update it in one spot.
[[ snippets/role.mg is_admin=True permissions=["view"] ]]What you can do
AI agents are now as easy as writing Markdown. Margarita lets you programmatically control the context, tools, and state sent to any model via .mgx files.
Your first .mgx file. Log a message, declare a state variable, write a prompt block, and run the agent — that's all it takes to get started with Margarita.
// Log a message before the agent starts
@effect log "Welcome to Margarita, let's get started!"
// Declare a state variable
@state variableA = "Hello World"
// Build the prompt
<< Why do we create ${variableA} programs? >>
// Run the agent
@effect run
Use @effect run to execute the agent at any point in your .mgx file. Run it multiple times — Margarita renders all accumulated << >> blocks into the prompt before each call.
# assistant.mgx
// 1. Add this to the context
<< You are a helpful assistant. What is the answer to life the universe and everything? >>
// 2. Run the agent
@effect run
// 3. Add more to the context
<< You need to think harder this time? >>
// 4. Run the agent again!
@effect run
Use if var == value: / else: to include or exclude sections of your prompt based on context. Use for item in list: to loop over data.
# access.mg
<< Access level: ${level} >>
if level == "admin":
<< You have full access. >>
else:
<< Read-only mode. >>
# tasks.mg
<< ## My Tasks >>
for task in tasks:
<< - ${task} >>
React-like composability with includes. Write a .mg fragment once and drop it into any script or template.
# components/greeting.mg
<< Hello, ${user}! >>
# report.mg
[[ components/greeting.mg user="Batman" ]]
Values stored by the agent, @effect func, or @effect tools persist for the lifetime of the run — any prompt block can read from state at any point.
# stateful.mgx
@state count = 5
@state user = "Batman"
<<
The agent can get/set state variables using markdown.
Update the count variable to 10 and print out the user variable.
>>
@effect run
Use @effect input to pause execution and prompt the user for a value. The response is stored in state and available to the rest of the script.
# build-assistant.mgx
// Pause and ask the user a question
@effect input "What do you want to build?:" => userInput
// Use the captured input in context
<<
You are a helpful build assistant.
Help the user build: ${userInput}
>>
@effect run
Use @memory var to declare a persistent variable that survives across runs. Values are read on startup and written back at the end — letting you build workflows that remember what happened last time.
# memory-example.mgx
// Declare a memory variable — loaded from persistent storage
@memory var valueA
<<
If valueA is not set, Set `valueA` to "This is a test of memory."
Otherwise write out it's set!
>>
@effect run
The agent has built-in tools — read_file, write_file, search_files, and ask_user. Just tell it what to read or write in your prompt and it handles the rest.
# file-example.mgx
// The agent reads and writes files on its own — no boilerplate needed
<<
Read the file at ./data/notes.txt
Summarise the key points and write the result to ./output/summary.md
>>
@effect run