npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

cursor-command-publisher

v1.0.4

Published

Dynamic MCP server that loads command templates from markdown files with variable substitution. Designed for Cursor and Claude.

Downloads

13

Readme

Command Publisher

npm version

Add to Cursor

A lightweight MCP (Model Context Protocol) server that dynamically loads and executes command templates from markdown files. Templates use YAML frontmatter for variable definitions and #{variable} placeholders for parameterized commands.

Searches ~/.cursor/published for .md files and parses front matter for interactive variable fillout.

https://github.com/user-attachments/assets/50efd387-6a83-4972-8028-7a777a3d1808

Closer view of interactive modal:

Getting Started

Quick Install

Click the Add to Cursor button above. Then, create ~/.cursor/published, or specify a different directory

Manual Installation

MCP Configuration

{
  "mcpServers": {
    "cmdpublisher": {
      "command": "npx",
      "args": ["-y", "cursor-command-publisher"],
    }
  }
}

Or specify a custom directory:

{
  "mcpServers": {
    "cmdpublisher": {
      "command": "node",
      "args": ["/path/to/cursor-command-publisher/build/index.js"],
      "env": {
        "COMMANDS_DIR": ["/custom/path"]
      }
    }
  }
}

Note that COMMANDS_DIR must be an Array.

Manual Installation

Go to Cursor Settings -> MCP -> Add new MCP Server. Name to your liking, use command type with the command from the standard config above. You can also verify config or add command like arguments via clicking Edit.

Configuration Details

  • Server Name: cmdpublisher
  • Type: NPX Package
  • Package: emmahyde/cursor-command-publisher

Features

  • Dynamic Command Loading: Watch a directory for .md files and automatically register them as MCP tools and prompts
  • Live Reloading: Changes to template files are detected instantly
  • YAML Frontmatter: Clean variable definitions with descriptions in one place
  • Simple Template Syntax: Use #{varName} for placeholders
  • Optional Parameters: Use variable?: "description" in frontmatter and #{variable?} in templates for conditional content
  • Conditional Blocks: Use #{?variable}...#{/variable} to conditionally include entire sections based on variable values
  • Dual Registration: Each template is exposed as both a tool and a prompt
  • Minimal Dependencies: Only uses @modelcontextprotocol/sdk, chokidar, and yaml
  • Local Only: No network ports or API keys required

Usage

Create Command Templates

Create a .cursor/published/ directory and add markdown files with templates:

mkdir -p .cursor/published

Example: .cursor/published/summarize.md

---
format: "output format (bullet points, paragraph, etc)"
text: "the text to summarize"
---

Summarize the following text in #{format} format:

#{text}

Example: .cursor/published/translate.md

---
language: "target language"
text: "the text to translate"
---

Translate the following text to #{language} language:

#{text}

Template Syntax

Templates use YAML frontmatter for variable definitions and #{variableName} for placeholders:

---
variableName: "human-readable description"
anotherVar: "another description"
---

Template content with #{variableName} and #{anotherVar} placeholders.

Examples

Simple variables

---
command: "shell command to run"
---

Run: #{command}

Multiple variables

---
host: "hostname or IP"
port: "port number"
user: "login username"
---

Connect to #{host} on port #{port} using username #{user}

Optional variables:

Use the ? suffix in both YAML frontmatter and template placeholders to make parameters optional. Optional parameters can be left empty or omitted, and will be replaced with an empty string when not provided.

---
host: "hostname or IP"
port: "port number"
user?: "login username"
---

Connect to #{host} on port #{port}#{user? using username }#{user?}

When user is provided: Connect to 192.168.1.1 on port 22 using username admin When user is empty: Connect to 192.168.1.1 on port 22

Advanced optional usage with conditional text:

---
topic: "main topic"
author?: "author name"
date?: "publication date"
---

# #{topic}

Written by #{author?}#{date? on }#{date?}

When all fields provided: # Testing\n\nWritten by Emma Hyde on 2025-10-17 When optional fields empty: # Testing\n\nWritten by

Conditional blocks:

Use #{?variable} to start a conditional block and #{/variable} or #{/} to end it. The entire block is only rendered if the variable has a non-empty value.

---
title: "document title"
author?: "author name"
version?: "version number"
---
# #{title}

#{?author}
## Author Information
Written by: #{author}
#{/author}

#{?version}
## Version
Version: #{version}
#{/}

## Content
Main documentation here.

When all fields provided:

# API Documentation

## Author Information
Written by: Emma Hyde

## Version
Version: 1.0.0

## Content
Main documentation here.

When optional fields empty:

# API Documentation

## Content
Main documentation here.

This is much cleaner than using multiple optional placeholders with conditional text!

Drop code into your Prompt

---
code: "the path/to/code.file:X-Y range"
audience: "who needs the explanation"
---

# Code Explanation

Explain the following code for #{audience}:

\```
#{code}
\```
Focus on what it does and why.

How It Works

  1. Startup: Server scans .cursor/published/ for .md files and parses them
  2. Registration: Each template is registered as both an MCP tool and prompt with variables as parameters
  3. Watching: File changes are detected via chokidar and tools/prompts are updated in real-time
  4. Execution: When a tool/prompt is called, variables are substituted and the result is returned

Architecture

src/
├── index.ts       # Entry point with STDIO transport
├── server.ts      # MCP server with tool registration
├── parser.ts      # Template tokenizer and AST builder
└── watcher.ts     # File watcher using chokidar

Key Components

  • Parser: YAML frontmatter parser with #{} placeholder extraction, automatically skips fenced code blocks
  • Watcher: Monitors directory and notifies of changes
  • Server: Registers tools and prompts dynamically, executes template rendering

Environment Variables

  • COMMANDS_DIR: Directory to watch for template files (default: ~/.cursor/command-publisher and ./.cursor/command-publisher)

File Watching Behavior

  • Initial scan loads all existing .md files
  • File changes are detected with a 300ms stability threshold (waits for write to complete)
  • Supports: add, modify, and delete operations
  • Only .md files are processed

Error Handling

  • Invalid template syntax is logged to stderr but doesn't crash the server
  • Missing required arguments are reported as MCP errors
  • File read errors are caught and logged
  • Graceful shutdown on SIGINT (Ctrl+C)

Performance Characteristics

  • Startup: O(n) where n = number of template files
  • File Change: O(1) to re-register affected tool
  • Tool Execution: O(1) template substitution
  • Memory: Minimal, stores only parsed templates

Limitations

  • Templates are text-based and returned as plain strings
  • No built-in validation of substituted values
  • Variable names are case-sensitive
  • No template inheritance or includes (by design, keep it lean)

Future Enhancements

  • Template validation schemas
  • Nested templates or includes
  • Multiple output formats (JSON, XML, etc.)
  • Pre/post-processing hooks
  • Template caching and optimization
  • Conditional blocks based on the value of the param

License

MIT