How to Use MCP Prompts to Create Reusable AI Workflows

Learn how MCP Prompts let you package complex instructions into reusable, parameterized templates that Claude can call on demand.

The Problem with One-Off Prompts

Here's something that happened to me about six months into using Claude seriously. I'd written this beautiful, detailed prompt for doing a code review — the kind that checks for security issues, points out naming inconsistencies, flags anything that looks like a performance trap. It took me maybe forty minutes to get it right. I used it once, got great results, and then completely forgot where I saved it.

Next time I needed a code review, I wrote a new prompt from scratch. A worse one. And I kept doing this — reinventing the wheel every single session because I had no systematic way to store and reuse my best prompts.

That's exactly the problem MCP Prompts solves. If you've already set up an MCP server (or read through the basics), you probably know that MCP lets Claude interact with tools and resources. But there's a third capability that often gets skipped over: Prompts. And once you understand what they are, you'll wonder how you worked without them.

What Are MCP Prompts, Exactly?

MCP Prompts are pre-defined, parameterized message templates that live inside your MCP server. Think of them like functions — but instead of returning code output, they return a structured conversation that Claude can immediately act on.

Here's the difference in practice. A normal prompt lives in your head, a text file, or some notes app. An MCP Prompt lives in your server, has a name Claude can discover, and accepts arguments that get filled in at runtime. You call it, pass in your variables, and Claude receives a fully formed set of messages ready to go.

The MCP spec defines three components to a Prompt object:

  • name — a unique identifier (like code_review)
  • description — plain English explanation of what it does
  • arguments — optional list of named parameters with descriptions

When Claude connects to your server, it can call prompts/list to discover what's available, then prompts/get to retrieve a specific one — filling in the arguments you provide.

Building Your First MCP Prompt

Let's make this concrete. I'll show you how to add a Prompt handler to an MCP server using the TypeScript SDK. If you've built a basic MCP server before, this will slot right in.

First, here's the shape of a prompt definition:

server.ts
// Register prompt list handler
server.setRequestHandler(ListPromptsRequestSchema, async () => {
  return {
    prompts: [
      {
        name: "code_review",
        description: "Review code for bugs, style, and security issues",
        arguments: [
          {
            name: "code",
            description: "The code snippet to review",
            required: true
          },
          {
            name: "language",
            description: "Programming language (e.g. Python, TypeScript)",
            required: false
          }
        ]
      }
    ]
  };
});

Now the prompts/get handler — this is where the magic happens. When Claude requests this prompt, your server fills in the arguments and returns structured messages:

server.ts
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
  const { name, arguments: args } = request.params;

  if (name === "code_review") {
    const code = args?.code ?? "(no code provided)";
    const language = args?.language ?? "unknown language";

    return {
      description: "Code review prompt",
      messages: [
        {
          role: "user",
          content: {
            type: "text",
            text: `Review this ${language} code for bugs, security issues, and style problems. Be specific about line numbers. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ ${code} \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ Format your response as: 1. Critical issues 2. Minor issues 3. Suggestions`
          }
        }
      ]
    };
  }

  throw new Error(`Prompt not found: ${name}`);
});

Multi-Turn Prompts: Where It Gets Interesting

Here's something that surprised me when I first dug into this — MCP Prompts aren't limited to a single user message. You can return a full multi-turn conversation as your prompt. This means you can bake in an AI persona, a prior exchange that sets context, or even a simulated example interaction that primes Claude's behavior.

Imagine a debugging workflow where you want Claude to always start by asking clarifying questions before jumping to solutions. You can encode that pattern directly:

server.ts
// Multi-turn prompt for structured debugging
messages: [
  {
    role: "user",
    content: { type: "text", text: "I have a bug I need help with." }
  },
  {
    role: "assistant",
    content: {
      type: "text",
      text: "Happy to help. Before I look at the code, can you tell me: what did you expect to happen, and what actually happened instead?"
    }
  },
  {
    role: "user",
    content: { type: "text", text: errorDescription }
  }
]

The client receives this whole conversation and picks up from there. Claude sees the established dynamic — careful, methodical debugging — and continues in that mode. You've essentially trained a micro-workflow without any fine-tuning.

Assistant role messages are optional

The MCP spec allows assistant-role messages in prompt responses, but not all clients support them yet. Claude Desktop handles them well. If you're building for other clients, test this first.

Combining Prompts with Resources

This is where MCP Prompts really shines as an intermediate technique. You can embed resource references inside your prompt messages. Instead of pasting raw content, you reference a resource URI and the client fetches it.

Say your MCP server exposes a resource at file:///project/style-guide.md. You can build a prompt that tells Claude to review code against that guide — without hardcoding the guide content into every prompt call:

server.ts
messages: [
  {
    role: "user",
    content: [
      {
        type: "resource",
        resource: {
          uri: "file:///project/style-guide.md",
          mimeType: "text/markdown",
          text: styleGuideContent // fetched from disk
        }
      },
      {
        type: "text",
        text: `Review the code below against the style guide above. ${code}`
      }
    ]
  }
]

Your style guide can evolve independently from your prompt logic. Update the file, and every future prompt call automatically picks up the new version. No copy-pasting, no stale instructions baked into a prompt.

Practical Prompt Ideas Worth Building

Once I started thinking in MCP Prompts, I found uses everywhere. Here are a few that I've found genuinely useful and that you could build in an afternoon:

  • PR description generator — takes a diff as an argument, returns a structured PR description with summary, changes, and testing notes
  • Error explainer — takes a stack trace and file context, formats a methodical debugging session
  • Meeting note formatter — takes raw notes, returns action items, decisions, and open questions
  • Commit message writer — takes staged diff output, returns a conventional commit message with optional body
  • API documentation reviewer — takes a spec file reference and returns structured feedback against REST best practices

Version your prompts like code

Since your prompts live in a server file, they're already in source control. Add a version field to your prompt names (like code_review_v2) when you iterate so you can roll back if a new version performs worse.

How Clients Surface MCP Prompts

One thing worth knowing: different MCP clients expose prompts differently. In Claude Desktop, prompts registered on connected servers show up in the slash command menu — type / and you'll see them listed. That's a genuinely nice UX when you have five or six prompts you use daily.

In a custom client you're building yourself, you'd call prompts/list on startup to discover available prompts, render them in whatever UI makes sense, collect the required arguments from the user, then call prompts/get to retrieve the filled messages before passing them to the model.

The key mental model: the server owns the prompt logic, the client owns the UI, and Claude owns the execution. Clean separation of concerns that makes everything easier to maintain.

The Bigger Picture

When I finally stopped hoarding prompts in a scattered text file and started encoding them properly as MCP Prompts, something clicked. My AI workflows started feeling less like improvisation and more like a repeatable system. The same quality output, every time, without the setup tax.

If you've been investing time in crafting really good prompts — the kind that consistently get great results — it's worth the few extra lines of code to promote them to first-class MCP citizens. Your future self, staring at a blank chat box at 9am, will thank you.

Keep going

More tutorials in this category, or explore the full field guide.

More Plugin Tutorials Official Docs ↗