Skip to main content
Back to AI Explorations

Behind the Build: MCP Prompt Library – The 'Brain' for Your AI Editor

2026-01-10
4 min read

Most developers have a "prompts.txt" file somewhere. It's usually a mess.

I wanted something better: a single source of truth for my best engineering prompts that I could access from anywhere—my terminal, my editor, or my AI chat app.

So I built the MCP Prompt Library, a standardized brain for AI interactions.


The "Three-Headed" Architecture

The core engineering challenge was building one system that works in three completely different contexts:

  1. As a Code Library: npm install @esreekarreddy/ai-prompts
  2. As a CLI Tool: ai-lib get prd-generator
  3. As an MCP Server: Connecting directly to Claude or Cursor.

To achieve this, I separated the "Brain" from the "Body".

The Brain (src/lib/Library.ts): This class knows nothing about servers or consoles. It scans the file system, parses frontmatter using gray-matter, indexes tags, and runs fuzzy searches. It's pure logic.

The Bodies:

  • src/cli.ts: Wraps the Brain in a commander interface for the terminal.
  • src/server.ts: Wraps the Brain in an McpServer instance for the protocol.

This separation means I can add a new feature (like "Smart Suggest") to the library, and it immediately works in both the terminal and Cursor.


Understanding MCP (Model Context Protocol)

MCP is a game-changer because it standardizes how AI tools ask for help. Instead of hardcoding "read file" logic into every app, the app just asks the MCP server: "What tools do you have?"

Here is the actual registration code from src/server.ts:

// server.ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";

// 1. Create the server
const server = new McpServer({
  name: "ai-library",
  version: "1.0.0",
});

// 2. Register a tool
server.tool(
  "get_prompt",
  "Fetch a prompt by name (fuzzy matching works)",
  { name: z.string() },
  async ({ name }) => {
    // The server just delegates to the library "brain"
    const item = library.getItem(name);
    return toolSuccess(item.body);
  },
);

Because of this standard, I didn't have to write a plugin for VS Code, and another for Claude, and another for Zee. I just wrote one MCP server, and it works everywhere.


Feature Spotlight: Smart Intent Detection

The coolest feature isn't just "getting" prompts—it's having the AI predict what you need.

I built a tool called enhance_prompt (src/tools/library.ts) that analyzes your raw request. If you say "I need to fix this bug," it doesn't just read the code. It:

  1. Detects the intent: fix_bug
  2. Loads the deep-debugger prompt framework.
  3. Injects the systematic-debugging skill.
  4. Returns a structured plan: Hypothesize → Verify → Fix.

This prevents "AI Slop"—lazy, meandering answers. The system forces the AI into a structured engineering workflow before it answers a single question.

Deep Dive: The Suggestion Engine

I didn't use an LLM for intent detection. I used a deterministic scoring algorithm.

Why? Speed. An LLM call takes 500ms+. My algorithm takes 2ms.

Here is the actual scoring logic from src/lib/library.ts:

// Calculate confidence score
const confidence = Math.min(
  0.9,
  0.3 + matchedKeywords.length * 0.2 + pattern.priority * 0.03,
);

It relies on three factors:

  1. Base Score (0.3): Every match starts with valid intent.
  2. Keyword Density (0.2): "fix bug" is better than just "bug".
  3. Heuristic Priority (0.03): "Security" patterns rank higher than "General".

This means enhance_prompt("fix critical security bug") will always outrank enhance_prompt("fix bug") because the keyword density is higher. It is predictable, testable, and instant.


Workflow Chains

For complex tasks like "New Feature" or "Security Hardening," a single prompt isn't enough.

I implemented a State Machine in src/lib/chains.ts. It manages multi-step interactions:

  1. Start: start_chain("new-feature") → Creates a session.
  2. Step 1: "Draft PRD" (Waits for user input).
  3. Step 2: "Review Architecture" (Auto-loads context).
  4. Step 3: "Generate Tests".

The state persists in memory, allowing you to have a continuous, guided "pair programming" session that follows a strict quality standard.


What I Learned

Tools should meet you where you are. Sometimes I'm in the terminal (ai-lib get git-commit). Sometimes I'm in Cursor (@Start New Feature Chain). By building a hybrid architecture, I didn't have to choose.

Structured prompts > Conversational drifting. The biggest productivity boost came from constraining the AI. By forcing it to use the "Architecture Review" template, I stop it from writing code before it understands the system.


Deep Dive: The "Zero-Dep" CLI

Most CLI tools use heavy frameworks like Oclif or Commander. They add 50ms to startup time. That sounds small, but for a tool you use 100 times a day, it adds up.

I built the CLI (src/cli.ts) with zero runtime dependencies for argument parsing.

// src/cli.ts
const args = process.argv.slice(2);
const command = args[0];
const commandArgs = args.slice(1);

switch (command) {
  case "get":
    await cmdGet(library, commandArgs);
    break;
  case "search":
    await cmdSearch(library, commandArgs);
    break;
  // ...
}

It parses flags manually. It creates no extra objects. It boots instantly.

By sharing the same Library class as the MCP server, the CLI is just a thin, 500-line wrapper around the core logic. It has no "business logic" of its own—it just formats the output for the terminal.


Resources

Leave a Comment

Comments (0)

Be the first to comment on this post.

Comments are approved automatically.