Plugins & Skills
Extensions come in three layers with a shared idea: everything is a directory with a manifest, nothing executes just by being present.
Skills: a directory with a SKILL.md
A skill is a written procedure for one kind of task — plain instructions the model reads and follows. It is discovered from its frontmatter, and its body is only loaded when the task actually matches.
<data>/skills/<name>/SKILL.md ← installed by you
<root>/.agents/skills/<name>/SKILL.md ← shipped in a repository (cross-agent standard)
<root>/.zlogic/skills/<name>/SKILL.md ← shipped in a repository (zlogic-specific)
The file needs a ----delimited YAML frontmatter with a description — the
model uses it to decide when to read the body, so a skill without a
description does not exist (it is skipped and reported). The optional name
defaults to the directory name. Frontmatter that zlogic cannot honor yet
(allowed_tools, context: fork, model, effort) is reported rather than
silently ignored.
---
name: release-notes
description: Draft release notes from the changelog between two git tags.
---
# Body
(Procedure the model follows — written in markdown, loaded on demand.)
Discovery reads only the frontmatter and a one-line description into the system
prompt (progressive disclosure); the body is snapshotted into the object store
when the skill tool actually loads it. Skills never embed shell execution — if
the procedure needs a command, the model decides to run shell, and that call
still goes through the normal approval gate. Inside the body, ${SKILL_DIR} and
${SESSION_ID} are expanded when loaded; $ARGUMENTS / $1 are interpreted per
invocation.
Name conflicts: the repository wins. A skill in the workspace (.zlogic/ skills or .agents/skills) overrides the user's same-named install — and the
conflict is reported, never silent. Enabled plugins contribute skills too,
namespaced <plugin>:<skill>.
Installed skills take effect on the next turn; no restart needed.
Plugins: a directory with a manifest
A plugin is a directory containing a manifest, optionally bundling MCP servers
(mcpServers in the manifest or a .mcp.json / mcp.json inside the plugin),
plus skills/ and agents/ directories:
<data>/extensions/plugins/<name>/ ← installed by you
<root>/.zlogic/extensions/plugins/<name>/ ← shipped in a repository
plugin.json | plugin.yaml ← manifest
.mcp.json ← or servers in their own file
skills/<skill-name>/SKILL.md ← bundled skills
agents/<agent>.md ← bundled sub-agent definitions
Manifest names, in lookup order: plugin.json, plugin.yaml, plugin.yml,
zlogic-plugin.json, zlogic-plugin.yaml. A manifest writes ${pluginRoot} /
${ZLOGIC_PLUGIN_ROOT} for paths inside the plugin.
Contributed MCP servers are namespaced <plugin>.<server> so two plugins can
each ship a search server, and a plugin can never shadow a server you
configured yourself. Plugins may also carry optional tool runtimes that are
downloaded on demand (see the Marketplace below).
The identity of a plugin is its directory name; the manifest name is just a
label. enabled: false in the manifest (or a .zlogic-disabled marker file in
the directory, or a switch in the UI) disables it; agents/commands/hooks
directories that zlogic has nowhere to load yet are reported to the person who
installed it, never ignored silently.
Plugins ship with the repository arrive with a git clone, and a manifest can
name any command on the machine — so the loader only ever reports what it
found, carrying an origin that distinguishes repository-supplied definitions
(workspace) from your own installs. Trust decisions are made elsewhere: servers
that came with the repository are not started until confirmed.
MCP servers declared per workspace
Beyond plugins, a workspace can declare MCP servers directly in the project root
.mcp.json (or mcp.json):
{
"mcpServers": {
"my-server": {
"command": "node",
"args": ["server.js"],
"env": { "MY_VAR": "value" }
}
}
}
HTTP servers use a url field instead. Tool definitions from MCP servers are
charged against the context window on every round; when they would exceed ~10% of
the window, a notice names the servers instead of silently trimming them — trim
with the definition's tool allowlist or the enable switch.
Where things live
| What | Location (default) |
|---|---|
| Installed skills | ~/.local/share/zlogic/skills/ |
| Installed plugins | ~/.local/share/zlogic/extensions/plugins/ |
| Managed MCP servers | ~/.local/share/zlogic/extensions/mcp/ |
| Optional runtimes | ~/.local/share/zlogic/extensions/runtimes/ |
| Repository skills | <project>/.agents/skills/ or <project>/.zlogic/skills/ |
| Repository plugins | <project>/.zlogic/extensions/plugins/ |
| Workspace MCP servers | <project>/.mcp.json |
| Global MCP servers | ~/.config/zlogic/mcp.json |
(Paths use the four XDG-style roots — config / data / state / cache — see
Configuration Reference. The site convention
~/.zlogic/… shown in the desktop Marketplace UI strings maps to these same
roots.)
The Marketplace (desktop) and installing
The desktop Marketplace view manages plugins, skills, MCP servers and optional runtimes. It offers a curated registry index when one is configured, and two universal install paths:
- Install from GitHub — paste a repository:
owner/repoowner/repo@tag-or-branch(or a full URL)owner/repo#subdir/owner/repo/tree/<ref>/subdir— install one folder from a monorepo
- Install from local folder — pick a directory:
- contains
plugin.json/plugin.yaml→ a plugin - contains
SKILL.md→ a skill - contains
.mcp.json/mcp.json→ an MCP bundle
- contains
Installation is a filesystem operation, not plugin execution: GitHub inputs are
parsed into owner/repo/ref first, archives are stripped of links and path
traversal, and replacement is staged in the managed directory before an atomic
rename. A .zlogic-source.json marker records where each install came from.
Capabilities are approved before install. Every source is inspected first
and its potentially executable MCP declarations are surfaced as explicit
capabilities (process to launch / network endpoint). The install only proceeds
when you accept them (accept_capabilities); there is no hidden "install and
run". After install you can enable / disable / uninstall at any time; MCP
servers contributed by extensions carry their own token credentials
(API-key header, bearer token or OAuth, stored in the OS keyring).
Under a remote daemon, local-folder installs are unavailable — the folder would be on the daemon host. Use the GitHub source, or a path that exists on the daemon host.
Managing installed skills and plugins from the CLI
The engine treats skills as first-class in the model's own tooling: the system
prompt lists every available skill as a one-line index, the model loads a body
with the skill tool, and you invoke one directly as a slash command. Skills
discovered on disk are re-read on every turn, so what the prompt lists and what
the tool can load can never diverge — and a newly installed skill is available
without a restart:
zlogic # then: /<skill-name> <arguments>
Plugins and their bundled MCP servers are managed from the desktop Marketplace; MCP credentials are managed per server there too (or in config, see Configuration Reference).