Skip to content

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, delete
  • ignore, mcp, permissions, hooks: get, put, delete
  • generate: run
  • import: run
  • convert: run
  • init, 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.

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:

FieldTypeRequiredDescription
namestringYesPath of the file relative to the skill directory (e.g. references/logo.png).
bodystringYesFile content, encoded according to encoding.
encoding"utf-8" | "base64"NoDefaults 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:

OptionTypeDescription
targetsstring[]Tools to generate for (e.g. ["claudecode", "cursor"] or ["*"]).
featuresstring[]Features to generate (e.g. ["rules", "skills"] or ["*"]).
deletebooleanDelete existing generated files before generating.
globalbooleanGenerate global (user-scope) configuration files.
simulateCommandsbooleanGenerate simulated commands.
simulateSubagentsbooleanGenerate simulated subagents.
simulateSkillsbooleanGenerate simulated skills.
dryRunbooleanPreview the run without writing or deleting anything.
checkbooleanReport 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.
retireTargetsstring[]Tools the project no longer uses; deletes the outputs rulesync manages for them. Requires features (not "*") and cannot be combined with targets.
outputRootsstring[]Output root directories.
inputRootsstring[]Ordered rulesync source trees (each directly contains rules/, skills/, ...). Cannot be combined with inputRoot.
inputRootstringDeprecated: parent directory of a .rulesync/ source tree. Prefer inputRoots. Cannot be combined with inputRoots.
configPathstringPath 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:

OptionTypeRequiredDescription
targetstringOne ofThe tool to import from (e.g. "claudecode").
targetsstring[]One ofThe CLI-style form of target: a list holding exactly one tool. Pass either target or targets, not both.
featuresstring[]NoFeatures to import (e.g. ["rules", "commands"] or ["*"]).
globalbooleanNoImport global (user-scope) configuration files.
outputRootstringNoRoot 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:

OptionTypeRequiredDescription
fromstringYesSource tool name (e.g. "claudecode"). Must be a valid ToolTarget.
tostring[]YesOne or more destination tool names. Must not be empty and must not include from.
featuresstring[]NoFeatures to convert (e.g. ["rules", "commands"]). Defaults to ["*"].
globalbooleanNoConvert global (user-scope) configurations. Defaults to false.
dryRunbooleanNoPreview 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.

FeatureOptions objectOptions
initnone—
gitignoregitignoreOptionstargets, features
addaddOptionssource (required), name, force, skills, rules, transport, ref, path, rulesPath, registry, tokenEnv, configPath
fetchfetchOptionssource (required), target, features, ref, path, output, conflict, prune, skills
installinstallOptionsmode, update, frozen, outdated, configPath
doctordoctorOptionsconfigPath, strict
docsdocsOptionsdocument or search; neither lists the documents
releaseNotesreleaseNotesOptionssource (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 add source that is a file:// 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. A file:// 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, gitignore and fetch write are checked before anything is written, as on the CLI: init does not create rulesync.jsonc or 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); gitignore refuses .gitignore and .gitattributes when either is a symbolic link (dangling or not) that leads outside the project; and fetch checks its output directory, .rulesync by default. The gitexclude destination is the exception: it is Git's own info/exclude, which Git locates, and in a linked worktree it lives in the main repository's .git directory.
  • install with mode: "gh" refuses a configuration that declares a source with scope: "user", since that would install outside the project; run it from the CLI instead.
  • There is no token option: add, fetch, install and releaseNotes read GITHUB_TOKEN / GH_TOKEN (and the npm token variables named by tokenEnv) from the server's environment.
  • fetch has no interactive option; select skills with skills. add never prompts: without force, an existing scaffold file is left unchanged and the call fails.
  • doctor returns result.diagnostics (each with severity, code, file, message, and optional hint, line, column) and result.summary. success means the diagnosis ran; result.passed says whether the configuration passed it (no errors, and no warnings with strict).
  • install with outdated: true writes nothing and returns result.sources (the lockfile status of every source) and result.upToDate, instead of failing when a source is behind.
  • docs returns result.content (the Markdown, with its id), result.matches (id and snippet per match; empty when nothing matches), or result.documents.
  • releaseNotes returns result.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).

ExcludedScopeReason
mcpcommandStarts the MCP server itself.
updatecommandReplaces the rulesync binary the server is running from; npm and Homebrew installs only print upgrade instructions.
--versionprogramPrints the CLI version; not a command an agent runs.
--jsonprogramMCP results are always structured JSON.
--verbose, --silentevery commandThe MCP server writes no console output.
--tokenevery commandSecrets stay out of tool arguments; GITHUB_TOKEN / GH_TOKEN from the server's environment is used instead.
--watchgenerateLong-running; an MCP call must return.
--interactivefetchNeeds a terminal prompt; select skills with skills instead.

Usage ​

Starting the MCP Server ​

bash
rulesync mcp

This starts an MCP server using stdio transport that AI agents can communicate with.

Configuration ​

Add the Rulesync MCP server to your .rulesync/mcp.jsonc:

json
{
  "$schema": "https://github.com/dyoshikawa/rulesync/releases/latest/download/mcp-schema.json",
  "mcpServers": {
    "rulesync-mcp": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "rulesync", "mcp"],
      "env": {}
    }
  }
}

Released under the MIT License.