Skip to main content
Glama

prompt-library

A local workbench for reusable prompts: Markdown files, typed variables, immutable revisions, local regression checks, an offline browser UI, and MCP tools and native prompts. No model API, subscription, account or cloud service is required.

Your files are authoritative. SQLite is a searchable cache plus a local usage log. Prompts remain readable and reviewable in Git without a running application.

Quick start

From a clone, with a Python environment active:

pip install -e .
plib --config examples/config.toml sync --json
plib --config examples/config.toml check --json

The bundled library contains 20 useful prompts and 20 passing regression cases: weekly reports, email editing, meeting minutes, technical translation, study plans, short social posts, code review, decision briefs, project updates, bug reports, document outlines, research summaries, interview practice, release notes, risk registers, customer replies, daily priorities, dataset review, requirement clarification and structured task cards. All example facts and names are fictional. Templates and documentation are English; intentional multilingual input fixtures exercise Chinese text handling and translation use cases.

First sync:

{"ok":true,"data":{"prompts":20,"changed":20,"removed":0},"warnings":[]}

Render a report or open the interface:

plib --config examples/config.toml render weekly-report --var-file examples/variables.json
plib --config examples/config.toml serve

Visit http://127.0.0.1:8879. Search, inspect a template, fill its variables, render, and copy the result. Every asset is local; there is no CDN or browser-side model call.

Offline search, typed variables, preview and rendered prompt

Related MCP server: MCP Prompt Manager

Installation

Python 3.11 or 3.12, Linux or macOS, SQLite with FTS5:

git clone https://github.com/GuoHaoyu1688/prompt-library.git
cd prompt-library
python3 -m venv .venv
. .venv/bin/activate
pip install -e .

For development: pip install -e '.[dev]'. requirements.txt installs the same base application. Secure descriptor-relative file access requires POSIX; Windows is outside this version's supported platforms.

File format

Each prompt is prompts/<category>/<name>.md under the configured library directory:

---
name: technical-summary
title: Technical summary
description: Summarize supplied evidence without adding claims.
tags: [writing, research]
version: "0.1.0"
variables:
  source:
    type: string
    required: true
    description: Source text to summarize
  bullet_count:
    type: integer
    default: 5
    required: false
    description: Target number of bullets
model_hints: Use any suitable model manually; no provider is required.
---
Summarize this text in {{ bullet_count }} bullets:
{{ source }}
{% include 'common/style_en.md' %}

Supported variable types: string, integer, number, boolean, array, object. Values are strict JSON types: "2" is not an integer, and true is not a number. Defaults are validated. Required values without defaults must be supplied. Optional values without defaults remain undefined and need a Jinja default filter or is defined guard. Unknown input variables and undeclared template variables fail with distinct error codes. Duplicate YAML keys are rejected.

--var topic=123 remains the literal string 123 for a string declaration. For other types, values use JSON: --var count=3, --var urgent=true, --var 'items=["first","second"]'. A JSON --var-file can supply all fields; explicit --var values override it. Duplicate CLI assignments are rejected.

Plain Markdown fragments live under prompts/common/. Includes use constant paths relative to prompts/, such as {% include 'common/style_zh.md' %}. Absolute paths, .., symlinks, dynamic filenames and include cycles are rejected. Included content is part of the version SHA, so changing a fragment creates a new observed revision for each affected prompt.

Template safety

Rendering uses Jinja's ImmutableSandboxedEnvironment with StrictUndefined. Python attribute access, function calls, macros, imports and inheritance are disabled. Use record['field'] for JSON object keys and for item in items for lists. Sequence multiplication and exponentiation are disabled. Filters are limited to upper, lower, trim, replace, join, length, default, tojson, indent, escape, sort, unique, first, last, round.

Each render runs in a separate worker with a wall-clock timeout and output limit. Only supplied JSON values and validated template fragments are passed in. This is an application boundary, not a general-purpose sandbox for arbitrary executable code. The optional external runner is a separate, explicit trust decision.

Configuration and paths

--data-dir or PLIB_DATA_DIR selects runtime state; default ./data. --config settings.toml or PLIB_CONFIG selects TOML. Relative library_dir is resolved against the configuration file; PLIB_LIBRARY_DIR can override it. Without explicit configuration, saved settings in <data-dir>/config.json are used, or the working directory is used for a new library.

library_dir = "/workspace/prompts"
timezone = "Asia/Shanghai"
render_timeout = 4.0
max_output_chars = 1000000
runner_enabled = false
runner_command = []
runner_timeout = 10.0

Runtime files: index.db (FTS and usage), config.json, snapshots/<name>/<sha>.json, and dated ZIPs in backups/. Keep user libraries and runtime state outside the public repository. The shipped examples/library/ is deliberately fictional and safe to publish.

CLI reference

Global flags work before or after the command: --data-dir, --config, --json, --quiet, --progress, --yes, --version. All commands are noninteractive. Query results are JSON envelopes. render emits plain text unless --json is set; JSON includes text, semantic version, content SHA and actor. Errors are always JSON. Logs/progress go to stderr. --quiet leaves the machine-readable result intact.

Command

Example

new

plib new summary --category writing --title "Short summary"

new --body-file

plib new summary --body-file draft.txt --yes

list

plib list --tag research --json

search

plib search '"code review"' --json

show

plib show code-review --json

render

plib render polish-email --var 'draft=Hello Alice, please review the sample.' --actor assistant-a --json

history

plib history polish-email --json

diff

plib diff polish-email SHA1 SHA2 --json

check

plib check --progress --json; optionally one prompt name

sync

plib sync --progress --json

stats

plib stats --json

export

plib export --format json --out library.json --json

export

plib export --format csv --out library.csv --no-bom --json

import

plib import library.json --json; CSV and large Markdown also supported

backup

plib backup --json; optionally --out unique-backup.zip

serve

plib serve --host 127.0.0.1 --port 8879

mcp

plib mcp

new creates a simple starter with no variables; edit its YAML declarations and body in your editor, then run sync. Use import for complete existing templates. --yes authorizes overwriting changed source paths during new or import. Existing exports/backups are always refused. Back up before source replacement.

FTS search supports AND-separated terms, quoted phrases and trailing * prefixes. Chinese-only phrases use overlapping bigrams with single-character support. Mixed Chinese/Latin phrases use ordinary SQLite Unicode tokenization. Tag listing uses exact tag matching. All reading operations validate and sync current source files, so invalid source edits cannot silently serve stale cached templates.

Revisions and usage

The built-in snapshot system works with or without Git. A SHA-256 covers the raw prompt and resolved include contents. history lists immutable observed snapshots; diff accepts full SHAs, unique SHA prefixes of at least eight characters, or an unambiguous version label. Reusing a semantic version is permitted, but choose SHAs when several snapshots share it. Snapshots capture revisions observed by sync/reads/rendering; intermediate edits never observed by the tool are not recovered. Git history is independent and is not parsed.

Snapshot files preserve history even when the searchable cache is rebuilt. Usage records track successful user-facing renders by time, actor and version SHA. stats shows frequent and never-used prompts. Regression checks do not inflate usage counts. CLI defaults to cli; the Web UI records web; MCP tools record mcp, and native MCP prompts record mcp-prompt.

Local regression checks

Each prompt has tests/<name>.yaml within its library:

cases:
  - name: fictional-example
    variables:
      source: A fictional sample was inspected.
      bullet_count: 3
    expect:
      contains: ["3 bullets", "fictional sample"]
      not_contains: ["{{"]
      min_length: 30
      max_length: 2000

Assertions apply to the rendered prompt itself, not to an invented model answer. json_schema can validate a rendered JSON prompt; only local # references are allowed, so validation never retrieves a schema from the network. Missing/invalid case files count as failures. check returns exit code 1 and CHECK_FAILED when any case fails, with detailed per-case results.

Optional local command runner

Disabled by default. To check output from your own local program, explicitly set:

runner_enabled = true
runner_command = ["/absolute/path/to/your-local-program", "--stdin"]
runner_timeout = 10.0

Then run plib check --external --json. The rendered prompt goes to stdin; stdout is checked with the same expectations. Commands are argv lists with shell=False; template content never becomes command-line code. Timeouts, nonzero exit statuses and excessive output are failures. The command is user-supplied code and can have its own side effects or network access. No runner is exposed through Web or MCP.

Import, export and backups

JSON exports contain schema_version: 1 and a files array of relative path and UTF-8 content. CSV uses path,content, UTF-8 with BOM by default. Both include prompt files, shared fragments and regression cases. Imports validate the entire combined library in a temporary staging area before changing live files, reject unsafe paths and duplicate names, and are idempotent for identical content. Changed existing files require --yes; unexpected write failures roll back completed writes.

Large Markdown imports split at level-two (##) headings. Each section becomes a prompt in prompts/imported/; template variables become required strings. The preamble is ignored. Names are deterministic slugs with collision suffixes. Review inferred types after importing. See examples/bulk-import.md.

backup creates a dated ZIP with the authoritative library, regression cases, SQLite snapshot (including usage), configuration and immutable prompt revisions. To restore, stop writers, preserve the current data, extract a trusted backup into new directories, update library_dir, then run sync. Do not delete the database as a routine rebuild: sync preserves usage; deleting index.db loses usage history.

MCP tools and native prompts

{
  "mcpServers": {
    "prompt-library": {
      "command": "/workspace/apps/prompt-library/.venv/bin/plib",
      "args": ["--config", "/workspace/config/prompt-library.toml", "--data-dir", "/workspace/data/prompt-library", "mcp"]
    }
  }
}

Tools: list_prompts(tag?), search_prompts(query), get_prompt(name), render_prompt(name, variables). The render tool accepts native JSON variable types and appends a usage record. It does not invoke a model or command.

Native prompts/list exposes each prompt and its variable arguments. prompts/get returns the rendered user message. Native MCP arguments are strings: use plain strings for string variables and JSON text for other types, for example {"topic":"Sample task","priority":"3","urgent":"true"}. Required/default status is preserved. Restart the server to register newly added prompt names or changed native argument declarations; tool calls always read current source files.

Uses the official mcp SDK, constrained to >=1.20,<2 for FastMCP. Schemas and an example native prompt descriptor are in docs/mcp-capabilities.json.

Validation

pip install -e '.[dev]'
ruff check .
ruff format --check .
pytest -q --cov=prompt_library --cov-report=term-missing

The suite covers all 20 fixture checks; missing, unknown and incorrectly typed variables; template syntax and sandbox escape attempts; include traversal/symlinks; include-aware history and diff integrity; JSON/CSV/Markdown roundtrips; disabled and timed-out runners; offline schema validation; HTTP origin guards; and an actual SDK stdio client listing and fetching native prompts. The Web search, render and copy workflow is also checked in a real browser. CI runs Python 3.11/3.12 on Ubuntu.

FAQ and roadmap

  • Does rendering call a model? No. It produces text for you or your assistant.

  • Can I edit files directly? Yes. They are the source of truth; queries sync them.

  • Why is loop.index rejected? All Python attribute access is disabled. Use simple bullet loops or provide numbering in the input data.

  • Why did a fragment change alter a prompt SHA? Its rendered instructions changed, so reproducibility requires a new dependency-aware version.

  • Can I publish my library? The examples are fictional. Your own templates, variables, backups and usage records remain local unless you share them.

  • macOS editable import failure? If python -v reports hidden .pth files, clear that flag only inside the virtual environment using chflags nohidden .venv/lib/python3.12/site-packages/*.pth.

Planned improvements: richer structured variable forms, more search normalization, and optional Git revision views. Paid-model integrations and online sharing are outside this project.

MIT licensed. See LICENSE, AGENTS.md and CHANGELOG.md. Implementation references: Jinja sandbox, SQLite FTS5, and the official MCP Python SDK.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    MCP server for managing and serving dynamic prompt templates using elegant and powerful text template engine. Create reusable, logic-driven prompts with variables, partials, and conditionals that can be served to any compatible MCP client like Claude Code, Claude Desktop, Gemini CLI, etc.
    18
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    A lightweight, file-based server for managing and serving personal prompt templates with variable substitution support via the Model Context Protocol. It allows users to store, update, and organize prompts in a local directory through integrated MCP tools and CLI assistants.
    8 npm
    7
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    Allows users to save, organize, and manage AI prompts, folders, and tags directly within MCP-compatible tools like Claude and Cursor. It supports version history tracking, prompt searching, and the ability to save public templates to a personal collection.
    20
    8 npm
    MIT