PluginsCreate a plugin

Create a plugin

A plugin bundles the things you have built for Syntic Code, such as skills, commands, agents, hooks and servers, so other people can install them with one command and get updates later. This page takes you from an empty folder to a working plugin you can test and share.

Do you need a plugin?

You want toUse
Give yourself a reusable prompt in one projectA skill in .syntic/skills/
Run a check every time a file is edited, just for youA hook in your settings
Share several of these with a team, versioned, installable and removable as one unitA plugin
Connect one external serviceAn MCP server in your settings, or a plugin if you want to ship it with other pieces

A plugin is worth it once you have something other people should install, or once you want one switch to turn a set of pieces on and off together.

Your first plugin

Scaffold it

syntic plugin init release-helper --description "Release chores for this repo"

This creates .syntic/skills/release-helper/ in the current project with two files:

.syntic/skills/release-helper/
  .syntic-plugin/plugin.json    name, version 0.1.0 and your description
  SKILL.md                      a first skill to edit

Because the folder holds a SKILL.md, Syntic Code already picks it up as a project skill. Names may use letters, digits, ., _ and -; lowercase with hyphens is recommended.

Write the skill

Open SKILL.md. The frontmatter tells the agent when to use the skill; the body tells it what to do:

---
name: release-helper
description: Prepare a release. Use when the user asks to cut, tag or ship a release.
---
 
# Release helper
 
1. Read CHANGELOG.md and list the entries since the last tag.
2. Propose the next version number using semantic versioning.
3. Update the version in the manifest files and the changelog.

Add more pieces

Create the folders you need next to the manifest. Each is picked up from its usual place without any change to plugin.json:

release-helper/
  .syntic-plugin/plugin.json
  SKILL.md                     (or skills/<name>/SKILL.md for several skills)
  commands/ship.md             runs as /release-helper:ship
  agents/changelog-writer.md   offered as release-helper:changelog-writer
  hooks/hooks.json
  .mcp.json
  .lsp.json
  output-styles/terse.md
  bin/                         executables put first on PATH for the plugin's processes
  settings.json                default settings (only "agent" is honoured)

Plugin components explains each one.

Check the manifest

syntic plugin validate .syntic/skills/release-helper
warning [author]: missing recommended field `author`
✓ .syntic/skills/release-helper/.syntic-plugin/plugin.json — valid (with warnings).

Errors (bad JSON, a missing name, a component path with ..) make the command exit with code 1.

Load it as a plugin

syntic --plugin-dir .syntic/skills/release-helper

--plugin-dir loads the folder as a full plugin for this run only: its skills, commands, agents, hooks and servers load, and the plugin’s variables are set. Nothing is installed.

Command names get the plugin prefix (/release-helper:ship) when the plugin sits in a folder named plugins, which is always true once it is installed. A folder plugin elsewhere, like .syntic/skills/release-helper, offers its commands under their bare names (/ship). To see the final names while developing, keep the plugin in a plugins/<name>/ folder and load it from there.

Plugin layout

The manifest lives at .syntic-plugin/plugin.json. A plugin.json at the plugin’s root is also read when the nested one is missing. A folder with only a SKILL.md and no manifest at all still counts as a plugin: it is named after the folder, gets version 0.0.0, and its single skill is the folder itself.

The smallest valid manifest:

{ "name": "release-helper", "version": "0.1.0" }

Every field is described in the manifest reference. To place components somewhere other than the default folders, list their paths in the manifest. Paths are relative to the plugin folder and must stay inside it.

Develop without a marketplace

You do not need a marketplace while you work. Pick whichever loop suits you:

MethodGood for
syntic --plugin-dir ./my-pluginDay-to-day work. Repeat the flag for several plugins, or point it at a parent folder to load every plugin inside it.
syntic --plugin-dir ./my-plugin.zipChecking the packaged archive before you publish it.
A local marketplace: syntic plugin marketplace add ./my-marketplaceTesting the full install, update and dependency flow.

Inside a running session, edits to the manifest or hooks/hooks.json of a loaded plugin reload plugins automatically. Edits to a SKILL.md reload skills. Run /reload-plugins any time to force it and see what changed. MCP and language servers need a restart to pick up new definitions.

If a folder plugin has the same name as an installed plugin, the installed copy wins and the folder is skipped with a warning. Disable the installed one while you work on the new version.

Test and debug

A component does not show up

  • Run syntic plugin validate <folder> and fix any errors.
  • Check the folder names: commands/, agents/, skills/, output-styles/, hooks/hooks.json, .mcp.json, .lsp.json. They are exact.
  • Paths you list in the manifest replace the default for that component. If you list "commands": "./cmds", the commands/ folder is no longer read.
  • A path that climbs out of the plugin with .. or is absolute is dropped without a message at load time. The validator reports it.

Skills are missing

Only sub-folders that contain a SKILL.md count as skills. A folder like skills/assets/ without one is skipped on purpose. If the same skill name exists in your user or project skills, that one wins over the plugin’s.

Pointing --plugin-dir at the wrong level

--plugin-dir accepts a plugin folder, or a folder whose direct children are plugin folders. A marketplace repository with plugins under plugins/ needs --plugin-dir ./repo/plugins, not ./repo.

Options are never asked for

Options are asked for by syntic plugin configure, or set with --config at install. Folder plugins loaded with --plugin-dir do not prompt. Give options a default so the plugin works before anyone configures it.

Check it actually helps

Write a few eval cases and run syntic plugin eval ./release-helper. Each case runs a real prompt with the plugin loaded and checks the answer. See Test a plugin.

Next steps