Rulesync MCP Server
Rulesync provides an MCP (Model Context Protocol) server that enables AI agents to manage your Rulesync files. This allows AI agents to discover, read, create, update, and delete files dynamically.
NOTE
The MCP server exposes the only one tool to minimize your agent's token usage. Approximately less than 1k tokens for the tool definition.
Supported Features and Operations
The single rulesyncTool multiplexes by feature and operation:
rule,command,subagent,skill:list,get,put,deleteignore,mcp,permissions,hooks:get,put,deletegenerate:runimport:runconvert:runinit,gitignore,add,fetch,install,doctor,docs,releaseNotes:run(see CLI commands)
The permissions feature operates on .rulesync/permissions.jsonc and the hooks feature operates on .rulesync/hooks.jsonc. Both accept a content string (valid JSONC) on put.
Warnings from run operations
The server writes nothing to a console the calling agent can read, so a diagnostic raised while reading the source tool's files, or while generating — for example, that a machine-local overrides file such as .factory/settings.local.json was read into files rulesync commits — travels back in the result instead, as a warnings array of strings. The field is omitted when the operation had nothing to report, and is present on failures too, since a run that warned and then failed is exactly when the warnings matter. At most 100 warnings are returned, each truncated to 1,000 characters and 8,000 characters in total; a run that exceeds any of those limits says so in a final entry rather than growing the result without bound. Every run operation reports warnings this way — the list / get / put / delete operations read and write .rulesync/ files that the caller can inspect for itself, and say nothing.
rule frontmatter
The rule operations expose the authored frontmatter, the value written in the file, not the resolved placement: agentsmd.subprojectPath: "auto" is returned as "auto", whether or not a directory could be derived from globs, so a get → edit → put round trip leaves the request in place, and put answers with the frontmatter it wrote.
subagent paths
Unlike rule and command, which take a file name and place it in their .rulesync/ directory, the subagent operations take a relativePathFromCwd that must point inside .rulesync/subagents/ and end in .md, for example .rulesync/subagents/planner.md or, for a nested agent, .rulesync/subagents/review/security.md. A bare file name, a path outside that directory, a non-Markdown file, a path with a dot-prefixed segment (which list and generate skip), or the directory itself is rejected. list returns the same paths, so they can be passed back to get, put, and delete unchanged. .rulesync and .rulesync/subagents may be symbolic links (for example into a dotfiles repository), and the server then reads and writes wherever the link points, as the CLI does; a symbolic link below .rulesync/subagents/ is neither listed nor read, written, or deleted through.
Symbolic links in .rulesync
The get and put operations of every file feature (rule, command, check, subagent, skill, ignore, mcp, hooks, permissions), and list for the features that have it (rule, command, check, subagent, skill), refuse a file reached through a symbolic link below its feature directory — the file itself and any directory on the way included — so a link committed to a repository you cloned (.rulesync/rules/notes.md -> ~/.ssh/id_rsa) is neither returned to the agent nor written through; subagent delete refuses one too. list leaves such an entry out instead of failing. A skill is read as a whole, so list and get skip a skill directory that is a link or holds one anywhere inside it, and put checks the skill directory, SKILL.md and every other file before writing any of them, so a refused link leaves the skill unchanged. This is stricter than the CLI, which follows linked source files (see File Formats § Symlinks). .rulesync and the feature directories themselves (.rulesync/rules, .rulesync/skills, ...) may still be symbolic links, for example into a dotfiles repository, and are followed as the CLI follows them; put on mcp, hooks and permissions additionally requires the file to resolve inside the project.
WARNING
Because a symlinked .rulesync or feature directory (such as .rulesync/subagents) is followed even when it points outside the project, running the MCP server in an untrusted checkout lets put and delete create directories and create, overwrite, or remove files wherever such a committed symbolic link points, and lets list and get read files from there. Inspect .rulesync before connecting an AI agent to the server in a repository you do not trust.
skill other files
A skill directory may contain files other than SKILL.md. They are passed as otherFiles, where each entry has:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Path of the file relative to the skill directory (e.g. references/logo.png). |
body | string | Yes | File content, encoded according to encoding. |
encoding | "utf-8" | "base64" | No | Defaults to "utf-8". Use "base64" for binary files such as images. |
On get, every returned entry carries an explicit encoding: "utf-8" when the file content survives a UTF-8 round trip unchanged, and "base64" otherwise. On put, the declared encoding is trusted and the decoded bytes are written verbatim, so binary files round-trip byte for byte.
When feeding entries returned by get back into put, keep their encoding field. Dropping it makes a "base64" body be stored as literal text and corrupts the file.
A "base64" body must be canonical base64 (the standard or the URL-safe alphabet, padding optional); otherwise put fails with Invalid base64 body for other file <name>. The 1MB skill size limit is evaluated against the decoded byte length of each other file.
generate / run options
When invoking feature: "generate" with operation: "run", pass generateOptions (optional; every field is optional and falls back to rulesync.jsonc, then the defaults). The options mirror the CLI's rulesync generate flags, except --watch (long-running), --verbose, --silent and --json, which have no meaning for a single MCP call:
| Option | Type | Description |
|---|---|---|
targets | string[] | Tools to generate for (e.g. ["claudecode", "cursor"] or ["*"]). |
features | string[] | Features to generate (e.g. ["rules", "skills"] or ["*"]). |
delete | boolean | Delete existing generated files before generating. |
global | boolean | Generate global (user-scope) configuration files. |
simulateCommands | boolean | Generate simulated commands. |
simulateSubagents | boolean | Generate simulated subagents. |
simulateSkills | boolean | Generate simulated skills. |
dryRun | boolean | Preview the run without writing or deleting anything. |
check | boolean | Report whether the outputs are up to date without writing anything. Unlike the CLI, the call does not fail when changes are needed; read upToDate instead. |
retireTargets | string[] | Tools the project no longer uses; deletes the outputs rulesync manages for them. Requires features (not "*") and cannot be combined with targets. |
outputRoots | string[] | Output root directories. |
inputRoots | string[] | Ordered rulesync source trees (each directly contains rules/, skills/, ...). Cannot be combined with inputRoot. |
inputRoot | string | Deprecated: parent directory of a .rulesync/ source tree. Prefer inputRoots. Cannot be combined with inputRoots. |
configPath | string | Path to the configuration file. |
Every path option (outputRoots, inputRoots, inputRoot, configPath) must stay inside the directory the server runs in: relative paths are resolved against it, symbolic links are followed, and a .. segment or a path whose real location is outside it is rejected. As on the CLI, configPath is resolved against inputRoot when both are given (and cannot leave it). When configPath or inputRoot selects the configuration file, the outputRoots and inputRoots that file declares must stay inside the directory too (the home directory used under global is exempt). This is stricter than the CLI on purpose — an agent may only point rulesync at the project it was connected to.
With check or dryRun, the result also carries upToDate (true when a real run would change nothing; a pending deletion counts as a change) and plan, the list of writes and deletions a real run would perform, in the same shape as the plan of rulesync generate --json. The result's config echoes the resolved dryRun, check, retireTargets, outputRoots and inputRoots.
import / run options
When invoking feature: "import" with operation: "run", pass importOptions with the following shape:
| Option | Type | Required | Description |
|---|---|---|---|
target | string | One of | The tool to import from (e.g. "claudecode"). |
targets | string[] | One of | The CLI-style form of target: a list holding exactly one tool. Pass either target or targets, not both. |
features | string[] | No | Features to import (e.g. ["rules", "commands"] or ["*"]). |
global | boolean | No | Import global (user-scope) configuration files. |
outputRoot | string | No | Root directory containing the tool configuration to import. Must stay inside the directory the server runs in, as for generate. |
convert / run options
When invoking feature: "convert" with operation: "run", pass convertOptions with the following shape. It covers every flag of rulesync convert except --verbose and --silent:
| Option | Type | Required | Description |
|---|---|---|---|
from | string | Yes | Source tool name (e.g. "claudecode"). Must be a valid ToolTarget. |
to | string[] | Yes | One or more destination tool names. Must not be empty and must not include from. |
features | string[] | No | Features to convert (e.g. ["rules", "commands"]). Defaults to ["*"]. |
global | boolean | No | Convert global (user-scope) configurations. Defaults to false. |
dryRun | boolean | No | Preview changes without writing files. Defaults to false. |
CLI commands
The CLI commands below run through operation: "run" with the same behavior as on the command line, reusing the same implementations. Each takes its options in its own object, named after the feature (gitignoreOptions, addOptions, ...), with the CLI flags in camelCase. Every result is a JSON object with success, an optional message (the command's own summary), result (the data the command reports under --json), error on failure, and warnings as described above. Nothing is written to stdout.
| Feature | Options object | Options |
|---|---|---|
init | none | — |
gitignore | gitignoreOptions | targets, features |
add | addOptions | source (required), name, force, skills, rules, transport, ref, path, rulesPath, registry, tokenEnv, configPath |
fetch | fetchOptions | source (required), target, features, ref, path, output, conflict, prune, skills |
install | installOptions | mode, update, frozen, outdated, configPath |
doctor | doctorOptions | configPath, strict |
docs | docsOptions | document or search; neither lists the documents |
releaseNotes | releaseNotesOptions | source (required, owner/repo), latest, since, until, tag, from, to, includePrereleases |
- Path options (
configPath,output) must stay inside the directory the server runs in; a path that leads outside it, textually or through a symbolic link, is rejected. - An
addsourcethat is afile://URL must name a repository inside that directory too, checked the same way after percent-decoding, so an agent cannot copy skills or rules into the project from any other local repository. Afile://source with a host (file://localhost/), a?, a#or a\is rejected, since git reads those characters differently from a URL parser. - The fixed files that
init,gitignoreandfetchwrite are checked before anything is written, as on the CLI:initdoes not createrulesync.jsoncor a sample file through a symbolic link that leads outside the project (such a sample is skipped with a warning, and an existing file or link is skipped, not written through);gitignorerefuses.gitignoreand.gitattributeswhen either is a symbolic link (dangling or not) that leads outside the project; andfetchchecks its output directory,.rulesyncby default. Thegitexcludedestination is the exception: it is Git's owninfo/exclude, which Git locates, and in a linked worktree it lives in the main repository's.gitdirectory. installwithmode: "gh"refuses a configuration that declares a source withscope: "user", since that would install outside the project; run it from the CLI instead.- There is no
tokenoption:add,fetch,installandreleaseNotesreadGITHUB_TOKEN/GH_TOKEN(and the npm token variables named bytokenEnv) from the server's environment. fetchhas nointeractiveoption; select skills withskills.addnever prompts: withoutforce, an existing scaffold file is left unchanged and the call fails.doctorreturnsresult.diagnostics(each withseverity,code,file,message, and optionalhint,line,column) andresult.summary.successmeans the diagnosis ran;result.passedsays whether the configuration passed it (no errors, and no warnings withstrict).installwithoutdated: truewrites nothing and returnsresult.sources(the lockfile status of every source) andresult.upToDate, instead of failing when a source is behind.docsreturnsresult.content(the Markdown, with itsid),result.matches(idandsnippetper match; empty when nothing matches), orresult.documents.releaseNotesreturnsresult.releases(tag, name, date, URL, and Markdown body of each release).
CLI parity
Every rulesync CLI command and option is available through the MCP server unless it is listed below. A command foo-bar is the fooBar feature with operation: "run", and its options and positional arguments are keys of fooBarOptions, in camelCase (--dry-run is dryRun, --no-prune is prune: false). The one renamed option is --config, which is configPath. A test (src/cli/mcp-parity.test.ts) compares the commands and options registered by the CLI with the MCP schemas, so a new CLI command or option has to ship with MCP support or with an entry in this list (MCP_PARITY_EXCLUSIONS in src/cli/mcp-parity.ts).
| Excluded | Scope | Reason |
|---|---|---|
mcp | command | Starts the MCP server itself. |
update | command | Replaces the rulesync binary the server is running from; npm and Homebrew installs only print upgrade instructions. |
--version | program | Prints the CLI version; not a command an agent runs. |
--json | program | MCP results are always structured JSON. |
--verbose, --silent | every command | The MCP server writes no console output. |
--token | every command | Secrets stay out of tool arguments; GITHUB_TOKEN / GH_TOKEN from the server's environment is used instead. |
--watch | generate | Long-running; an MCP call must return. |
--interactive | fetch | Needs a terminal prompt; select skills with skills instead. |
Usage
Starting the MCP Server
rulesync mcpThis starts an MCP server using stdio transport that AI agents can communicate with.
Configuration
Add the Rulesync MCP server to your .rulesync/mcp.jsonc:
{
"$schema": "https://github.com/dyoshikawa/rulesync/releases/latest/download/mcp-schema.json",
"mcpServers": {
"rulesync-mcp": {
"type": "stdio",
"command": "npx",
"args": ["-y", "rulesync", "mcp"],
"env": {}
}
}
}