An Emacs Lisp AI coding agent with multi-agent architecture, permission-based tool access, and LLM integration via gptel.
- Multi-agent system with specialized agents (build, plan, explore, general)
- Permission-based tool access with fine-grained control per agent
- Custom agent support via
.magent/agent/*.mdfiles - LLM integration via gptel supporting Anthropic Claude, OpenAI GPT, and compatible APIs
- 10 built-in tools: file operations, shell, grep, glob, web search, Emacs eval, agent delegation, skill invocation
- Skill system for extending agent capabilities (built-in Emacs skill + custom skills from files)
- Single-request lock for serializing concurrent requests
- Project-scoped session management with conversation history and JSON persistence
- Streaming responses with chunk batching and async fontification
- Markdown-to-Org conversion for rendering assistant output in org-mode
- Context-aware prompting via
magent-dwimwith automatic buffer context attachment
Add the project to your Emacs load path:
(add-to-list 'load-path "/path/to/magent")
(require 'magent)(use-package magent
:load-path "/path/to/magent"
:config
(global-magent-mode 1))Magent delegates all LLM communication to gptel. Configure your provider, model, and API key through gptel:
;; gptel handles provider/model/key configuration
(setq gptel-model 'claude-sonnet-4-20250514)
(setq gptel-api-key "sk-ant-...") ; or use ANTHROPIC_API_KEY env varSee gptel documentation for full provider setup (Anthropic, OpenAI, Ollama, etc.).
Customize with M-x customize-group RET magent RET. Key settings:
| Option | Default | Description |
|---|---|---|
magent-system-prompt | (built-in) | Default system prompt for agents |
magent-buffer-name | "*magent*" | Output buffer name |
magent-auto-scroll | t | Auto-scroll output buffer |
magent-enable-tools | all 10 tools | Globally enabled tools |
magent-project-root-function | nil | Custom project root finder |
magent-max-history | 100 | Max messages in history |
magent-request-timeout | 120 | Timeout in seconds for LLM requests |
magent-default-agent | "build" | Default agent for new sessions |
magent-load-custom-agents | t | Load custom agents from .magent/agent/*.md |
magent-enable-logging | t | Enable logging to *magent-log* buffer |
magent-enable-audit-log | t | Persist compact audit logs for permission and sensitive actions |
magent-assistant-prompt | "ASSISTANT" | Tag text in assistant section headers |
magent-user-prompt | "USER" | Tag text in user section headers |
magent-tool-call-prompt | "tool" | Tag text in tool call lines |
magent-error-prompt | "error" | Tag text in error section headers |
magent-agent-directory | ".magent/agent" | Relative path to custom agent dir |
magent-session-directory | ~/.emacs.d/magent-sessions/ | Base directory for global sessions and per-project session subdirectories |
magent-audit-directory | nil | Override directory for audit JSONL files; defaults to magent-session-directory/audit/ |
magent-grep-program | "rg" | Path to ripgrep binary |
magent-grep-max-matches | 100 | Max matches from grep searches |
magent-bash-timeout | 30 | Timeout in seconds for bash commands |
magent-emacs-eval-timeout | 10 | Timeout in seconds for emacs_eval |
magent-audit-preview-length | 120 | Max width for persisted audit summaries and previews |
magent-include-reasoning | t | Display (t), keep out of the UI (ignore), or discard (nil) reasoning blocks |
magent-auto-context | t | Auto-attach buffer context in magent-dwim |
magent-ui-batch-insert-delay | 0.05 | Delay in seconds for batching streaming chunks |
magent-ui-fontify-threshold | 500 | Character threshold for async fontification |
| Command | Keybinding | Description |
|---|---|---|
magent-dwim | C-c m p | Smart prompt: opens output buffer or prompts for input with auto-context |
magent-diagnose-emacs | C-c m d | Start a structured diagnosis of the current Emacs session |
magent-doctor | C-c m D | Run Magent self-check and diagnose Magent-specific issues |
magent-prompt-region | C-c m r | Send selected region to AI |
magent-ask-at-point | C-c m a | Ask about symbol at point |
magent-clear-session | C-c m c | Clear current session |
magent-show-log | C-c m l | View API request/response log |
magent-clear-log | C-c m L | Clear the log buffer |
magent-ui-toggle-section | C-c m t | Toggle fold/unfold of section at point |
magent-select-agent | C-c m A | Select an agent for this session |
magent-show-current-agent | C-c m i | Show current session’s agent |
magent-list-agents | C-c m v | List all available agents |
magent-toggle-by-pass-permission | M-x | Toggle permission bypass for tool filtering and approval prompts |
In the *magent* output buffer: TAB and S-TAB fold sections, ? opens the transient menu, C-c C-c submits input, and C-g interrupts.
The same bypass state is also exposed as the customize option
magent-by-pass-permission under M-x customize-group RET magent RET.
Magent keeps a single *magent* buffer, but session state is scoped by project:
- In a recognized project, prompts, agent selection, clear, and resume operate on that project’s current session.
- Saved project sessions live under
magent-session-directory/projects/<sha1(project-root)>/. - Outside any project, Magent falls back to the global session behavior and saves directly under
magent-session-directory. - Compact audit logs for permission decisions and sensitive tools are written as daily JSONL files under
magent-session-directory/audit/unlessmagent-audit-directoryis set. magent-resume-sessionshows all sessions grouped by project, with the current project’s group first and global sessions in their own group.
;; Enable the mode
(magent-mode 1)
;; Or globally
(global-magent-mode 1)
;; Send a prompt
M-x magent-dwim
;; Or use keybinding
C-c m pMagent uses a multi-agent architecture where different agents have different capabilities and permissions.
| Agent | Mode | Description |
|---|---|---|
build | primary | Default agent for general coding tasks with full tool access |
plan | primary | Planning agent with restricted file edits (only .magent/plan/*.md) |
explore | subagent | Fast codebase exploration (read/grep/glob/bash only) |
general | subagent | General-purpose subagent for delegated tasks (no delegation) |
compaction | primary (hidden) | Session summarization / conversation compaction |
title | primary (hidden) | Conversation title generation |
summary | primary (hidden) | Pull-request style summary generation |
- primary: User-facing agents that can be selected for sessions
- subagent: Internal agents called by primary agents for subtasks
- all: Can act as either primary or subagent
Each agent has permission rules controlling tool access:
;; Example permission rules in an agent definition
(
(read_file . allow) ; Allow all file reads
(write_file . ((deny "*.env") ; Deny writing to .env files
(deny "*.key") ; Deny writing to .key files
(allow "*"))) ; Allow writing to other files
(bash . ask) ; Ask user before running bash commands
)Permission actions:
allow: Tool is alloweddeny: Tool is blockedask: Prompt the user for confirmation
Create custom agents by adding markdown files to .magent/agent/.
Example: ~.magent/agent/reviewer.md~
---
description: Code review specialist
mode: primary
hidden: false
temperature: 0.3
permissions:
- (read_file . allow)
- (write_file . deny)
- (bash . deny)
- (grep . allow)
- (glob . allow)
---
You are a code review specialist. Analyze code for:
- Bugs and potential issues
- Code style and best practices
- Performance optimizations
- Security vulnerabilities
Provide constructive feedback with specific examples.The YAML frontmatter supports:
description: Short description of the agentmode:primary,subagent, orallhidden: Hide from agent selection UItemperature: Override default temperaturemodel: Override default modelpermissions: List of permission rules
The AI agent has access to these tools (can be customized per agent):
| Tool | Side-effect | Description |
|---|---|---|
read_file | no | Read file contents from the filesystem |
write_file | yes | Write or create a file (auto-creates parent dirs) |
edit_file | yes | Replace exact text in a file (must match once) |
grep | no | Regex search via ripgrep; returns file:line:content |
glob | no | Find files matching a glob pattern |
bash | yes | Execute shell commands (default timeout 30s) |
emacs_eval | yes | Evaluate Emacs Lisp expressions (default timeout 10s) |
delegate | yes | Spawn a nested request using a named subagent |
skill_invoke | no | Invoke tool-type skills |
web_search | no | Search the web via DuckDuckGo |
Tools with side effects prompt the user for confirmation before execution unless permission bypass is enabled with M-x magent-toggle-by-pass-permission or by customizing magent-by-pass-permission.
Tool availability is controlled by:
- Global
magent-enable-toolssetting - Per-agent permission rules
- Entry Point (
magent.el): Definesmagent-modeminor mode with theC-c mkeybinding prefix. Full initialization (agent registry, skills) is lazy – triggered on first command viamagent--ensure-initialized. - Runtime (
magent-runtime.el): Centralizes static initialization and project-local overlay activation for agents, skills, and capabilities. - Agent System: Multi-agent architecture with permission-based tool access:
magent-agent.el: Builds gptel prompts, applies per-agent overrides, callsgptel-requestmagent-agent-registry.el: Agent info struct, built-in agent definitions, and central registrymagent-agent-file.el: Custom agent loader (.magent/agent/*.md)
- Permission System (
magent-permission.el): Rule-based tool access control per agent with file-pattern matching (glob syntax). - Capability System (
magent-capability.el): File-backed capability definitions score each request context and attach matching instruction skills. - FSM (
magent-fsm.el): Finite state machine for the tool-calling loop (INIT -> SEND -> WAIT -> PROCESS -> TOOL -> DONE/ERROR). Currently delegates HTTP to gptel. - LLM Integration (via gptel): All LLM communication is handled by gptel. Provider, model, and API key configuration is managed entirely by gptel.
- Tools (
magent-tools.el): 10 tool implementations registered asgptel-toolstructs, filtered per agent based on permission rules. - Skills (
magent-skills.el): Two skill types –instruction(markdown injected into the system prompt) andtool(invoked viaskill_invoke). The module contains the registry, built-inskill-creatordefinition, file-based skill loading, and interactive inspection commands. Skills load in priority order from: (1) built-inskills/directory bundled with magent, (2) user directory~/.emacs.d/magent-skills/<name>/SKILL.md, (3) project-local.magent/skills/<name>/SKILL.md. - Session (
magent-session.el): Conversation history management with per-project active sessions, global fallback outside projects, and JSON persistence. Thebuffer-contentslot stores raw buffer text for lossless restore. - Audit (
magent-audit.el): Persistent JSONL audit logging for permission prompts and decisions plus sensitive actions such asbash,emacs_eval,write_file,edit_file, anddelegate. Payloads are redacted to metadata and truncated previews. - UI (
magent-ui.el): The*magent*buffer derives fromorg-mode. It uses in-buffer input with* [USER]sections. Tool calls render as#+begin_tool~/~#+end_toolblocks; reasoning blocks as#+begin_think~/~#+end_think. Single-request serialization now lives here viamagent-ui--processingandmagent-ui--enqueue. - Markdown-to-Org (
magent-md2org.el): Converts markdown assistant output to org-mode format for rendering. - File Loader (
magent-file-loader.el): Shared definition loader for agent, skill, and capability files. It includes frontmatter parsing and supports booleans, numbers, quoted strings, and comma-separated lists.
magent/
|-- magent.el # Main entry point and mode definition
|-- magent-config.el # Configuration (customize group, defcustom vars)
|-- magent-runtime.el # Static initialization and project overlay activation
|-- magent-session.el # Session and message history (JSON persistence)
|-- magent-capability.el # Capability registry and prompt-time resolution
|-- magent-audit.el # Audit logging and JSONL persistence
|-- magent-tools.el # Tool implementations (10 gptel-tool structs)
|-- magent-agent.el # Agent logic (gptel integration)
|-- magent-agent-info.el # Compatibility shim for legacy agent-info feature
|-- magent-agent-types.el # Compatibility shim for legacy agent-types feature
|-- magent-agent-registry.el # Agent struct, built-in definitions, and registry
|-- magent-agent-file.el # Custom agent file loader (.magent/agent/*.md)
|-- magent-permission.el # Permission system (allow/deny/ask with glob patterns)
|-- magent-fsm.el # FSM API (dispatches to gptel backend)
|-- magent-fsm-backend-gptel.el # gptel FSM backend implementation
|-- magent-fsm-shared.el # Shared FSM structs, tool wrapping, permission flow
|-- magent-file-loader.el # Shared definition loader and frontmatter parser
|-- magent-md2org.el # Markdown to org-mode converter
|-- magent-skills.el # Skill registry, built-in skills, file loading, and skill commands
|-- magent-ui.el # In-buffer UI and output buffer (org-mode derived)
|-- magent-pkg.el # Package descriptor
|-- prompt.org # Default system prompt
|-- Makefile # Build, test, and clean targets
|-- skills/ # Built-in skills (loaded automatically)
| |-- brainstorming/SKILL.md
| |-- systematic-debugging/SKILL.md
| |-- test-driven-development/SKILL.md
| |-- writing-plans/SKILL.md
| |-- executing-plans/SKILL.md
| |-- subagent-driven-development/SKILL.md
| |-- verification-before-completion/SKILL.md
| |-- git-workflow/SKILL.md
| |-- requesting-code-review/SKILL.md
| |-- receiving-code-review/SKILL.md
| |-- finishing-a-development-branch/SKILL.md
| |-- dispatching-parallel-agents/SKILL.md
| |-- research/SKILL.md
| |-- research-add/SKILL.md
| |-- research-batch/SKILL.md
| |-- research-explore/SKILL.md
| `-- research-report/SKILL.md
`-- test/
`-- magent-test.el # ERT test suite
magent-agent-info: Agent configuration struct (name, description, mode, permissions, prompt, temperature, model, and related settings)magent-session: Conversation state with message list, assigned agent, and history trimmingmagent-fsm: FSM state for the tool-calling loop (state, session, agent, tools, pending-tools, and related fields)magent-skill: Loaded skill definition (name, description, tools, body, dir)
make compile # Byte-compile all Elisp files
make test # Run ERT tests
make clean # Remove compiled .elc filesemacs -Q --batch -L . -L ~/path/to/gptel -f batch-byte-compile magent-foo.elSessions are automatically saved to ~/.emacs.d/magent-sessions/ (configurable). Each session maintains:
- Conversation history
- Assigned agent
- Message metadata
- Raw buffer content for lossless restore
View request and response logs:
(setq magent-enable-logging t)
M-x magent-show-log ; C-c m lM-x magent-list-agents ; List all agents
M-x magent-show-current-agent ; Show current session's agentAPI keys are managed by gptel. Check with:
gptel-api-key ; Should return your API keyThis project is licensed under the GNU General Public License v3.0. See LICENSE for details.
- Inspired by: OpenCode
Contributions are welcome. Please ensure:
- Code follows existing style conventions
- All files byte-compile without warnings
- Documentation is updated for new features
- Project Repository: https://github.com/jamie-cui/magent