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/engine

v0.0.10

Published

The execution core of MarkdownAI. Takes a parsed AST and evaluates all directives - shell queries, HTTP requests, database connections, environment resolution, caching, security enforcement, and output assembly.

Readme

@markdownai/engine

The execution core of MarkdownAI. Takes a parsed AST and evaluates all directives - shell queries, HTTP requests, database connections, environment resolution, caching, security enforcement, and output assembly.

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

Links: GitHub  ·  npm org


What it does

@markdownai/engine is the brain of MarkdownAI. It takes a parsed AST from @markdownai/parser, walks every node in document order, resolves all dynamic directives, and assembles the final rendered output.

If you want to embed MarkdownAI rendering inside your own Node.js application - or build tools on top of the language - this is the package to use. The CLI (@markdownai/core) and MCP server (@markdownai/mcp) both use it internally.

Installation

npm install @markdownai/engine

Requires Node.js >= 18. Database adapters (PostgreSQL, MySQL, MSSQL, MongoDB, SQLite) are included but only loaded when a @connect directive references them.

Quick Start

import { parse } from '@markdownai/parser'
import { execute } from '@markdownai/engine'

const source = `@markdownai

# Project Status

**Branch:** @query "git branch --show-current" label="branch"
{{ branch }}

**Source files:** @count ./src/ match="**/*.ts"
`

const ast = parse(source)
const result = execute(ast, {
  ctx: {
    security: {
      allowShell: true,
      allowHttp: false,
      allowDb: false,
      jailRoot: null,
    }
  }
})

if (result.errors.length === 0) {
  console.log(result.output)
} else {
  console.error(result.errors)
}

Core API

execute(ast, options?): EngineResult

Executes a parsed MarkdownAI AST and returns the rendered output.

import { parse } from '@markdownai/parser'
import { execute, makeContext } from '@markdownai/engine'

const ast = parse(source)
const result = execute(ast, {
  filePath: '/path/to/doc.md',   // used for relative path resolution
  ctx: makeContext({
    envFiles: ['.env'],
    cwd: process.cwd(),
    security: {
      allowShell: false,
      allowHttp: false,
      allowDb: false,
      jailRoot: null,
    }
  })
})

EngineOptions:

interface EngineOptions {
  filePath?: string         // absolute path to the document being executed
  ctx?: Partial<EngineContext>  // execution context (security, env, etc.)
}

EngineResult:

interface EngineResult {
  output: string            // the final rendered markdown
  errors: string[]          // fatal errors that prevented execution
  warnings: string[]        // non-fatal issues (blocked directives, missing vars, etc.)
}

makeContext(options?): EngineContext

Creates a complete execution context with defaults filled in.

import { makeContext } from '@markdownai/engine'

const ctx = makeContext({
  envFiles: ['.env.production'],
  cwd: '/path/to/project',
  consumer: 'ai',
  security: {
    allowShell: true,
    allowHttp: true,
    allowDb: true,
    jailRoot: '/path/to/project',
    shellConfig: { /* ... */ },
    httpConfig: { /* ... */ },
  }
})

strip(source, options?): StripResult

Removes all MarkdownAI directives from a document, producing clean static Markdown. Conditional blocks are evaluated against the provided environment so the correct branch is preserved. @note blocks are always stripped regardless of their visible flag - mai strip is for producing plain markdown, not for consumer-targeted rendering.

import { strip } from '@markdownai/engine'

const result = strip(source, {
  env: { APP_ENV: 'production' },
  keepPrompts: false,    // strip @prompt blocks (default: false)
})

console.log(result.output)     // clean markdown
console.log(result.stripped)   // count of directives removed

StripOptions:

interface StripOptions {
  env?: Record<string, string>   // variables for conditional evaluation
  keepPrompts?: boolean           // preserve @prompt blocks in output
}

StripResult:

interface StripResult {
  output: string
  stripped: number
}

Security

All security is opt-out by default - everything that could have side effects is blocked unless explicitly enabled.

Security Config

interface SecurityConfig {
  allowShell: boolean        // enable @query shell execution
  allowHttp: boolean         // enable @http requests
  allowDb: boolean           // enable @db database queries
  jailRoot: string | null    // confine filesystem access to this directory
  shellConfig?: ShellSecurityConfig
  httpConfig?: HttpSecurityConfig
  filesystemConfig?: FilesystemSecurityConfig
}

Loading from disk

The mai security commands write to ~/.markdownai/security.json. Use loadSecurityConfig() to read it:

import { loadSecurityConfig } from '@markdownai/engine'

const json = loadSecurityConfig()
// json.shell.enabled, json.http.enabled, json.db, etc.

Default config

import { defaultSecurityConfig } from '@markdownai/engine'

// defaultSecurityConfig = {
//   allowShell: false,
//   allowHttp: false,
//   allowDb: false,
//   jailRoot: null,
// }

Immutable rules

Certain operations are permanently blocked regardless of your configuration. These cannot be overridden:

  • Cloud metadata endpoints (169.254.169.254, metadata.google.internal, etc.)
  • Pipe-to-shell patterns (curl ... | bash, wget ... | sh)
  • Filesystem paths that escape the jail root

When an immutable rule blocks something, a SECURITY_ALERT is emitted to stderr even if --silent is set.

Shell security

When allowShell: true, shell commands run through your allowlist and deny patterns:

const shellConfig: ShellSecurityConfig = {
  enabled: true,
  allow_patterns: ['git log *', 'npm audit *'],
  deny_patterns: ['rm *', 'sudo *'],
  allow_network: false,
  require_confirmation: false,
  audit_log: true,
}

HTTP security

When allowHttp: true, HTTP requests are limited to your allowed domains:

const httpConfig: HttpSecurityConfig = {
  enabled: true,
  allowed_domains: ['api.github.com', 'api.example.com'],
  denied_domains: [],
  allowed_methods: ['GET'],
  max_response_size: 1048576,  // 1 MB
  timeout: 10000,              // 10 seconds
}

Environment Resolution

The engine resolves environment variables in a fixed priority order:

  1. Shell environment (process.env)
  2. Any env files passed via envFiles or --env
  3. Fallbacks registered via @import files
  4. The fallback= value on the directive itself
  5. Empty string (no error)
import { resolveEnv } from '@markdownai/engine'

const value = resolveEnv('DATABASE_URL', ctx)

Expression Evaluation

The expression system is used in @if conditions, {{ }} interpolations, and where filters. It runs in a sandboxed vm.runInNewContext context - eval() is never used.

import { evalCondition, evalExpression } from '@markdownai/engine'

// Boolean condition (for @if)
const matches = evalCondition('env.APP_ENV == "production"', ctx)

// Expression result (for {{ }})
const value = evalExpression('date format="YYYY-MM-DD"', ctx)

Supported operators:

  • Equality: ==, !=
  • Comparison: >, <, >=, <=
  • Logical: &&, ||, !
  • Existence: file.exists, file.isDir
  • String: .startsWith(), .endsWith(), .includes()
  • Ternary: condition ? "yes" : "no"
  • Nullish: ?? (fallback if null/undefined)
  • Optional chain: ?.

Caching

Add @cache to any data directive to cache its result:

import { cacheKey, readCache, writeCache, clearSessionCache, clearPersistCache, showCacheEntries } from '@markdownai/engine'

// Read a cached value
const cached = readCache(key)

// Write to cache
writeCache(key, value, { mode: 'session' | 'persist', ttl?: number })

// List all cache entries
const entries = showCacheEntries()

// Clear session (in-memory) cache
clearSessionCache()

// Clear persistent (disk) cache
clearPersistCache()

Cache modes:

  • session - in-memory, cleared when the process exits
  • persist - written to disk, survives restarts
  • ttl=N - session cache that expires after N seconds
  • persist ttl=N - disk cache that expires after N seconds
  • mock=./file.json - always returns the contents of a local file, never hits the real source

Sensitive content is masked before anything is written to the cache.

Built-in Pipe Commands

The engine includes pure-Node.js implementations of common Unix pipe utilities. These work on all platforms without spawning a shell:

| Command | Behavior | |---------|----------| | grep <pattern> | Filter lines matching a regex | | sort | Sort lines alphabetically | | sort -r | Sort lines in reverse | | head -n N | Keep first N lines | | tail -n N | Keep last N lines | | wc -l | Count lines | | uniq | Remove consecutive duplicate lines |

Shell-dependent commands (awk, sed, jq, etc.) spawn a child process and are Unix/WSL only. The engine detects platform at startup and warns when shell-only commands are used on Windows.

import { isBuiltin, runBuiltin } from '@markdownai/engine'

if (isBuiltin('grep \\.ts$')) {
  const filtered = runBuiltin('grep \\.ts$', lines)
}

Database Support

@markdownai/engine includes adapters for:

  • MongoDB (mongodb:// or mongodb+srv://)
  • PostgreSQL (postgres:// or postgresql://)
  • MySQL (mysql://)
  • MSSQL (mssql://)
  • SQLite (sqlite://)

Connections are established via @connect in your document and referenced by name in @db blocks. All queries run through the database security jail (read-only by default, operation allowlist, collection restrictions).

TypeScript

Full type declarations are included for all exports:

import type {
  EngineContext,
  EngineOptions,
  EngineResult,
  SecurityConfig,
  ShellSecurityConfig,
  HttpSecurityConfig,
  DbSecurityConfig,
  FilesystemSecurityConfig,
  SecurityJsonConfig,
  DbConnectionSecurityConfig,
  Connection,
  MacroDefinition,
  MCPContext,
  CacheEntry,
  StripOptions,
  StripResult,
} from '@markdownai/engine'

Part of the MarkdownAI toolchain

License

MIT - GitHub