Repository navigation
MCP servers
Connect Model Context Protocol servers over stdio, streamable HTTP or WebSocket.
malac can use tools from any Model Context Protocol server. Each server is a [mcp.<name>] table in your configuration. malac connects to all enabled servers when a tab loads (or when a run in its own process starts), and their tools join the built-in ones. In the daemon, identical servers are started once and shared by the tabs that use them.
# A local server over stdio
[mcp.files]
command = "npx"
args = ["-y", "@modelcontextprotocol/server-filesystem", "${HOME}/notes"]
env = { DEBUG = "0" }
# A remote server over streamable HTTP
[mcp.github]
url = "https://api.githubcopilot.com/mcp/"
headers = { Authorization = "Bearer ${GITHUB_TOKEN}" }
# A server over WebSocket, with a bearer token from the environment
[mcp.tools]
url = "wss://tools.example.com/mcp"
token_env = "TOOLS_TOKEN"The transport follows from the keys:
| Keys | Transport |
|---|---|
command (+ args, env) |
stdio: malac starts the process |
url starting with http:// or https://
|
streamable HTTP |
url starting with ws:// or wss://
|
WebSocket |
| Key | Type | Default | Meaning |
|---|---|---|---|
command |
string | none | Program to start for a stdio server |
args |
array of strings | [] |
Its arguments |
env |
table | {} |
Extra environment variables for it |
url |
string | none | Endpoint of a remote server |
headers |
table | {} |
Extra HTTP headers |
token_env |
string | none | Variable whose value is sent as a bearer token |
enabled |
bool | true |
Set false to keep the entry but not connect |
prefix |
bool | true |
Name tools <server>__<tool>
|
${VAR} is expanded from the environment in command, args, env and headers.
With prefix = true (the default), tools are named <server>__<tool>, for example github__create_issue. Names are limited to letters, digits, _ and -, as provider APIs require; other characters become _.
Tools that the server marks as read-only are Safe and never ask. All other MCP tools are Execute tools: they ask in ask and edits mode. Allow a whole server with a tool-name rule:
[permissions]
allow = ["github__*"]
deny = ["github__delete_*"]MCP tools have no argument key, so only rules without parentheses match them.
If a server sends instructions when it connects, they are added to the system prompt.
malac mcp● github (41 tools)
✗ files
<why it could not connect>
The command lists each server with its tool count or its error, then the names of all MCP tools. In a session, /mcp shows the same status. Servers that fail do not stop malac; it warns on stderr (the terminal UI lists them itself) and carries on without them.
malac's own computer and browser control is an MCP server too, connected as control with prefix = false. Defining your own [mcp.control] replaces it.
A project's .malac/config.toml cannot add MCP servers unless you set trust_project_config = true in your user config, because a server is a program malac would start. See Security model.
Getting started
Tutorials
- Tutorials
- Tutorial 1: Your first task
- Tutorial 2: Delegating to subagents
- Tutorial 3: Automating a browser
- Tutorial 4: Long-term memory with Milvus
- Tutorial 5: Running malac unattended
- Tutorial 6: Customizing malac
- Tutorial 7: Running malac on a server
Using malac
- Workspaces, tabs and the daemon
- The terminal UI
- Plain mode and scripting
- Sessions
- Jobs
- Permissions and autopilot
- Subagents
- Memory
- Project context
- Plugins and marketplaces
- Computer and browser control
- Web UI
- VS Code
- Remote access
- Mobile (preview)
- MCP servers
- Configure malac by asking
- Updating
Reference
- CLI
- Slash commands
- Configuration
- Tools
- Control service tools
- JSON events
- Protocol
- Environment variables
Guides
- Using an LLM gateway
- Running models locally
- Vector memory with Milvus
- Controlling a remote machine
- Writing agent types, skills and commands
- Security model
- Things to know
Project