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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@markdownai/mcp

v0.0.13

Published

MCP (Model Context Protocol) server for MarkdownAI. Bridges AI assistants and live documents - intercepts file reads, resolves directives, and serves phase-aware content through 8 tools AI tools can call directly.

Readme

@markdownai/mcp

MCP (Model Context Protocol) server for MarkdownAI. Bridges AI assistants and live documents - intercepts file reads, resolves directives, and serves phase-aware content through 8 tools AI tools can call directly.

All packages: @markdownai/core  ·  @markdownai/engine  ·  @markdownai/parser  ·  @markdownai/renderer  ·  @markdownai/mcp  ·  @markdownai

Links: GitHub  ·  npm org


What it does

@markdownai/mcp solves the core problem of AI tools reading live documents: without it, an AI opens a .md file and sees raw source - directives, macro definitions, unexpanded expressions. With the MCP server configured, the AI receives fully rendered, up-to-date content every time it reads a MarkdownAI document.

The server implements the Model Context Protocol over stdio. It exposes 8 tools AI assistants can call to interact with documents, navigate phases, invoke macros, and manage cache state.

Key capability - lazy phase loading. For multi-phase documents (workflows, runbooks, multi-step guides), the server loads only the currently active phase into AI context. A 20-phase document doesn't flood the AI with everything at once - the AI works through phases in sequence, requesting each one as needed.

Installation

npm install -g @markdownai/core

This installs the mai CLI and the mai-serve binary, which is what your AI client will use as the MCP server process.

Setup with Claude Code

You don't start the server manually. Claude Code starts it automatically when you open a session, based on the configuration you add once.

The easiest way is mai init, which writes the config for you:

mai init

Or add it manually to your project's .claude/settings.json (or your global Claude Code settings):

{
  "mcpServers": {
    "markdownai": {
      "command": "mai-serve",
      "args": []
    }
  }
}

That's it. Claude Code reads this config on startup, launches mai-serve as a subprocess, and connects to it over stdio. From that point on, every .md file with a @markdownai header that Claude reads is automatically rendered before Claude sees it - no manual steps needed per session.

To scope the server to a specific project directory, add --cwd:

{
  "mcpServers": {
    "markdownai": {
      "command": "mai-serve",
      "args": ["--cwd", "/path/to/your/project"]
    }
  }
}

The 8 MCP tools

Once the server is configured, Claude can call these tools directly during a session.

read_file

Reads and renders a MarkdownAI document, resolving all directives. Returns the same output you'd get from mai render.

{
  "name": "read_file",
  "arguments": {
    "path": "./docs/status.md"
  }
}

Optional budget parameter (in tokens) enables AI-format compression - drops low-priority sections to fit within the limit.

{
  "name": "read_file",
  "arguments": {
    "path": "./docs/status.md",
    "budget": 4000
  }
}

list_phases

Lists all phases defined in a document and their transitions.

{
  "name": "list_phases",
  "arguments": {
    "file": "./runbooks/deploy.md"
  }
}

Returns an array like:

[
  { "name": "preflight", "transitions": ["deploy"] },
  { "name": "deploy", "transitions": ["verify", "@call notify_team"] },
  { "name": "verify", "transitions": [] }
]

resolve_phase

Renders the content of a specific named phase, running all its directives.

{
  "name": "resolve_phase",
  "arguments": {
    "file": "./runbooks/deploy.md",
    "phase": "preflight"
  }
}

next_phase

Returns the name of the phase that follows the given phase, or null if it's the last one. Used to walk through a multi-phase document step by step.

{
  "name": "next_phase",
  "arguments": {
    "file": "./runbooks/deploy.md",
    "phase": "preflight"
  }
}
// returns: "deploy"

call_macro

Invokes a named macro defined in a document, with optional arguments.

{
  "name": "call_macro",
  "arguments": {
    "file": "./report-template.md",
    "macro": "summary-block",
    "args": { "period": "Q1 2026", "format": "concise" }
  }
}

get_env

Retrieves an environment variable value, with an optional fallback.

{
  "name": "get_env",
  "arguments": {
    "key": "DATABASE_URL",
    "fallback": "postgres://localhost:5432/dev"
  }
}

Keys matching credential patterns (PASSWORD, SECRET, TOKEN, API_KEY, etc.) are blocked - the tool returns an error rather than exposing sensitive values.


execute_directive

Runs a single MarkdownAI directive and returns its output. Useful for ad-hoc queries during a session.

{
  "name": "execute_directive",
  "arguments": {
    "directive": "@query \"git log --oneline -5\""
  }
}

Security rules apply exactly as they do during a full render - the directive must pass the shell allowlist, HTTP domain allowlist, or database jail before it executes.


invalidate_cache

Clears cached rendered output for a specific file, or for all files if no path is given.

{
  "name": "invalidate_cache",
  "arguments": {
    "file": "./docs/live-metrics.md"
  }
}
{
  "name": "invalidate_cache",
  "arguments": {}
}

Security at the MCP boundary

The server enforces the same security rules as the CLI:

  • File access - only files within the project's document root can be read. Path traversal attempts (../../../etc/passwd) are rejected.
  • Environment variables - keys matching credential patterns are blocked in get_env responses.
  • Directives - execute_directive calls run through the full security jail. Shell-injection sequences are blocked.
  • Server resilience - a bad request never crashes the server. The server recovers and keeps running.

API Reference (library usage)

If you're building your own MCP server or tooling on top of this package:

startServer(options?): Promise<void>

Starts the MCP stdio server. Blocks until the client disconnects.

import { startServer } from '@markdownai/mcp'

await startServer({
  cwd: process.cwd(),
})

Individual tools

Each tool is exported as a standalone function:

import {
  readFile,
  listPhases,
  resolvePhase,
  nextPhase,
  callMacro,
  getEnv,
  executeDirective,
  invalidateCache,
} from '@markdownai/mcp'

const rendered = await readFile({ path: './docs/status.md' })
const phases = await listPhases({ file: './runbook.md' })

Connection registry

The server maintains a session-level connection registry so database connections are established once and reused across all tool calls.

import { registerConnection, getConnection, listConnections, clearConnections } from '@markdownai/mcp'

registerConnection('reports', { type: 'mongodb', uri: process.env.MONGODB_URI })

const conn = getConnection('reports')
clearConnections()  // closes all connections

TypeScript

import type { ServerOptions } from '@markdownai/mcp'

Part of the MarkdownAI toolchain

License

MIT - GitHub