विषय पर बढ़ें

Prompts

मशीनी अनुवाद

यह page अंग्रेज़ी documentation से अपने-आप अनुवादित किया गया है, और अंग्रेज़ी page ही प्रामाणिक version है। अगर कुछ गलत लगे, तो अनुवाद page बताता है कि इसकी सूचना कैसे दें।

Prompt एक message template है जिसे user चुनता है।

Tools model के लिए होते हैं। Prompt इसका उल्टा है: user अपने client के menu (slash command, button) से कोई prompt चुनता है, उसके arguments भरता है, और render हुए messages बातचीत में ऐसे जुड़ जाते हैं मानो user ने खुद type किए हों।

Prompt declare करने के लिए text लौटाने वाले function पर @mcp.prompt() लगाएँ।

आपका पहला prompt

server.py
from mcp.server import MCPServer

mcp = MCPServer("Code Helper")


@mcp.prompt()
def review_code(code: str) -> str:
    """Review a piece of code."""
    return f"Please review this code:\n\n{code}"

SDK वही तीन चीज़ें पढ़ता है जो वह tool से पढ़ता है:

  • Name function का नाम है: review_code
  • Client जो description दिखाता है, वह docstring है: Review a piece of code.
  • Arguments parameters से आते हैं। code का कोई default नहीं है, इसलिए वह required है।

prompts/list से client को यही वापस मिलता है:

{
  "name": "review_code",
  "description": "Review a piece of code.",
  "arguments": [
    {"name": "code", "required": true}
  ]
}

यहाँ कोई JSON Schema नहीं है। Prompt arguments named string values की एक flat list हैं: ऐसा form जिसे इंसान भरता है, ऐसा payload नहीं जिसे model बनाता है।

इसे render करना

Client arguments pass करते हुए prompts/get से template render करता है। आपका function चलता है और जो str आप लौटाते हैं, वह एक user message बन जाता है:

{
  "description": "Review a piece of code.",
  "messages": [
    {
      "role": "user",
      "content": {
        "type": "text",
        "text": "Please review this code:\n\ndef add(a, b): return a + b"
      }
    }
  ],
  "resultType": "complete"
}

Prompt का पूरा जीवन बस इतना ही है: नाम से list होना, माँगे जाने पर render होना, chat में डाल दिया जाना।

Check

required आपके function के चलने से पहले ही enforce होता है। review_code को code के बिना render करें और request खुद JSON-RPC error (code -32603) के साथ fail हो जाती है:

mcp.shared.exceptions.MCPError: Internal server error

Model को लौटाने के लिए tool जैसा कोई error result नहीं है, क्योंकि यहाँ कोई model शामिल ही नहीं है: call raise करता है। वजह (Missing required arguments: {'code'}) आपके server के log में जाती है।

इसे आज़माएँ

Server को MCP Inspector के साथ चलाएँ:

uv run mcp dev server.py

Prompts tab खोलें और review_code चुनें। Inspector एक required code field वाला form बनाता है। इसे भरें, render करें, और आपको ठीक ऊपर वाला user message वापस मिलता है।

एक से ज़्यादा messages

Code review एक message है। Debugging session एक बातचीत है, और prompt पूरी बातचीत की शुरुआत कर सकता है।

str की जगह messages की list लौटाएँ:

server.py
from mcp.server import MCPServer
from mcp.server.mcpserver.prompts.base import AssistantMessage, Message, UserMessage

mcp = MCPServer("Code Helper")


@mcp.prompt()
def review_code(code: str) -> str:
    """Review a piece of code."""
    return f"Please review this code:\n\n{code}"


@mcp.prompt()
def debug_error(error: str) -> list[Message]:
    """Start a debugging conversation."""
    return [
        UserMessage("I'm seeing this error:"),
        UserMessage(error),
        AssistantMessage("I'll help debug that. What have you tried so far?"),
    ]
  • UserMessage और AssistantMessage, mcp.server.mcpserver.prompts.base से आते हैं। इन्हें str दें और ये उसे आपके लिए TextContent में wrap कर देते हैं। Role class का नाम है।
  • Message इनका साझा base है। इसे return annotation के रूप में इस्तेमाल करें।

debug_error को render करने पर अब तीन messages इसी क्रम में बनते हैं:

{
  "description": "Start a debugging conversation.",
  "messages": [
    {"role": "user", "content": {"type": "text", "text": "I'm seeing this error:"}},
    {"role": "user", "content": {"type": "text", "text": "TypeError: 'int' object is not iterable"}},
    {
      "role": "assistant",
      "content": {"type": "text", "text": "I'll help debug that. What have you tried so far?"}
    }
  ],
  "resultType": "complete"
}

आख़िरी message पर ध्यान दें। assistant turn पहले से भरना ही वह तरीका है जिससे आप model के अगले जवाब की दिशा तय करते हैं, बिना user से वह निर्देश खुद type करवाए।

titles और argument descriptions

review_code function का नाम है, label नहीं। client को button पर लगाने के लिए कुछ बेहतर दें, और हर argument का description लिखें ताकि form खुद ही समझ में आ जाए:

server.py
from typing import Annotated

from pydantic import Field

from mcp.server import MCPServer

mcp = MCPServer("Code Helper")


@mcp.prompt(title="Code review")
def review_code(
    code: Annotated[str, Field(description="The code to review.")],
    language: Annotated[str, Field(description="The language the code is written in.")] = "python",
) -> str:
    """Review a piece of code."""
    return f"Please review this {language} code:\n\n{code}"
  • title="Code review" इंसानों के पढ़ने लायक नाम है, ठीक tool के title की तरह।
  • Annotated[str, Field(description=...)] वही pattern है जो Tools tool के parameters describe करने के लिए इस्तेमाल करता है। यहाँ description schema में जाने के बजाय argument पर लगता है।
  • language का default है, इसलिए वह अब required नहीं रहता।

prompts/list entry में अब वह सब है जो client को अच्छा form बनाने के लिए चाहिए:

{
  "name": "review_code",
  "title": "Code review",
  "description": "Review a piece of code.",
  "arguments": [
    {"name": "code", "description": "The code to review.", "required": true},
    {"name": "language", "description": "The language the code is written in.", "required": false}
  ]
}

Info

अगर आपने Tools पढ़ लिया है, तो यहाँ तक की हर बात आप पहले से जानते हैं। वही decorator, वही docstring-as-description, वही Annotated/Field। बदलता सिर्फ़ इतना है कि इसे trigger कौन करता है (user) और result कहाँ जाता है (बातचीत में)।

सिर्फ़ text ही नहीं

UserMessage और AssistantMessage जहाँ भी str लेते हैं, वहाँ content block या Image / Audio helper भी ले लेते हैं। prompts में दो मामले सामने आते हैं: document जोड़ना और तस्वीर जोड़ना।

file embed करना

server.py
from pathlib import Path

from mcp.server import MCPServer
from mcp.server.mcpserver import Message, UserMessage
from mcp.types import EmbeddedResource, TextResourceContents

mcp = MCPServer("Code Helper")

STYLE_GUIDE_FILE = Path(__file__).parent / "style-guide.md"  # or the path to your file on disk


@mcp.resource("style://python", mime_type="text/markdown")
def style_guide() -> str:
    """The team's Python style guide."""
    return STYLE_GUIDE_FILE.read_text(encoding="utf-8")


@mcp.prompt()
def review_code(code: str) -> list[Message]:
    """Review a piece of code against the team style guide."""
    guide = TextResourceContents(uri="style://python", mime_type="text/markdown", text=style_guide())
    return [
        UserMessage(EmbeddedResource(resource=guide)),
        UserMessage(f"Review this code against the style guide above:\n\n{code}"),
    ]
  • style guide style://python पर एक resource है (Resources में इनकी बात है), जो server.py के बगल में रखी style-guide.md से पढ़ा जाता है। वहाँ कोई भी Markdown file रख दें।
  • EmbeddedResource(resource=TextResourceContents(...)), दोनों mcp.types से, file को उसके URI और MIME type के साथ पहले message के रूप में ले जाता है; उसका ज़िक्र करने वाली request उसके बाद plain text के रूप में आती है।
  • guide को f-string में चिपकाने के बजाय embed करने से client उसे attachment की तरह दिखा सकता है और बाद में style://python फिर से खोल सकता है, और model को file ज्यों की त्यों मिलती है। binary file के लिए base64 blob के साथ BlobResourceContents इस्तेमाल करें।

render होने पर पहले message का content एक resource block है:

{"type": "resource", "resource": {"uri": "style://python", "mimeType": "text/markdown", "text": "* Prefer early returns.\n..."}}

image जोड़ना

server.py
from pathlib import Path

from mcp.server import MCPServer
from mcp.server.mcpserver import Image, Message, UserMessage

mcp = MCPServer("Code Helper")

DIAGRAM_FILE = Path(__file__).parent / "architecture.png"  # or the path to your file on disk


@mcp.prompt()
def explain_component(component: str) -> list[Message]:
    """Explain one component using the architecture diagram."""
    return [
        UserMessage(Image(path=DIAGRAM_FILE)),
        UserMessage(f"Where does {component} sit in this architecture, and what does it talk to?"),
    ]
  • Image Images, audio और icons वाला helper है। prompt render होते समय UserMessage इसे ImageContent block में बदल देता है (file base64-encoded, MIME type .png से अंदाज़ा लगाया गया); Audio इसी तरह AudioContent बन जाता है।
  • server.py के बगल में architecture.png नाम की कोई भी PNG रख दें। prompt arguments strings होते हैं, इसलिए तस्वीर हमेशा server से आती है; component सिर्फ़ शब्द देता है।
{"type": "image", "data": "iVBORw0KGgoAAAANSUhEUg...", "mimeType": "image/png"}

runtime पर list बदलना

clients जुड़े रहते हुए भी prompts जोड़े जा सकते हैं, उदाहरण के लिए ताकि user किसी निर्देश को अपनी खुद की menu entry के रूप में save कर सके। prompt register करें, फिर notify करें:

server.py
from contextlib import suppress

from mcp.server import MCPServer
from mcp.server.mcpserver import Context
from mcp.server.mcpserver.prompts import Prompt

mcp = MCPServer("Code Helper")


@mcp.prompt()
def review_code(code: str) -> str:
    """Review a piece of code."""
    return f"Please review this code:\n\n{code}"


@mcp.tool()
async def save_template(name: str, instruction: str, ctx: Context) -> str:
    """Save an instruction as a prompt the user can pick from the menu."""

    def template(code: str) -> str:
        return f"{instruction}\n\n{code}"

    with suppress(ValueError):  # replace an existing entry of the same name
        mcp.remove_prompt(name)
    mcp.add_prompt(Prompt.from_function(template, name=name, description=instruction))
    await ctx.notify_prompts_changed()
    await ctx.session.send_prompt_list_changed()
    return f"Saved '{name}' to the prompt menu."
  • mcp.add_prompt(Prompt.from_function(fn, name=..., description=...)) किसी function को ठीक वैसे ही register करता है जैसे @mcp.prompt() करता, और mcp.remove_prompt(name) इसका उल्टा है। add_prompt उसी नाम की मौजूदा entry को overwrite करने के बजाय बनाए रखता है, इसलिए tool पहले कोई भी पुरानी entry हटा देता है ताकि save करना replace बन जाए। prompts/list बदलाव तुरंत दिखाती है।
  • await ctx.notify_prompts_changed() हर उस 2026-07-28 client को notifications/prompts/list_changed भेजता है जो subscriptions/listen stream पर सुन रहा हो (Subscriptions)। await ctx.session.send_prompt_list_changed() इसे call करने वाले client को भेजता है, जब वह client 2026 से पहले का हो (legacy clients को serve करना)। दोनों call करें; जब बताने के लिए कोई न हो तो दोनों में से कोई कुछ नहीं करता।
  • जिस client को notification मिलता है, वह prompts/list फिर से call करता है। Python Client में यह async with client.listen(prompts_list_changed=True) as sub: है, जो PromptsListChanged event देता है।

सारांश

  • function पर @mcp.prompt() लगाने से वह prompt बन जाता है। नाम function से, description docstring से।
  • prompts user-controlled हैं: client इन्हें list करता है, user कोई एक चुनता है और arguments भरता है।
  • arguments named strings की flat list हैं (कोई schema नहीं)। default वाला parameter optional है।
  • str लौटाएँ और वह एक user message बन जाता है। multi-turn बातचीत की शुरुआत करने के लिए UserMessage / AssistantMessage की list लौटाएँ।
  • title= और Field(description=...) वही हैं जो client अपने UI में दिखाता है।
  • कोई required argument छूट जाए तो पूरी request fail होती है। हर prompt का अलग error result नहीं होता।
  • document या तस्वीर जोड़ने के लिए EmbeddedResource या Image को UserMessage में wrap करें।
  • runtime पर mcp.add_prompt(...) / mcp.remove_prompt(...) से prompts जोड़ें या हटाएँ, फिर await ctx.notify_prompts_changed() और await ctx.session.send_prompt_list_changed() call करें।

prompt के (या resource template के) arguments के लिए server-side autocomplete Completions में है।