Subspace Communications: Managing Prompts


MCP Deep-Dive Series

📋 What Are Prompts?

In MCP, Prompts are user-controlled prompt templates — pre-programmed tactical maneuvers that the user (not the model) can select and invoke. Think of them as Captain Picard's numbered tactical patterns: "Pattern Delta-5" triggers a known sequence of instructions.

Key differences from Tools:

A Prompt is essentially a function that returns a formatted string (or a list of messages) to be injected into the conversation. It can accept arguments to customize the tactical approach.

🎯 The @mcp.prompt() Decorator

Registering a prompt is as elegant as programming a new tactical maneuver into the ship's computer:

from mcp.server.fastmcp import FastMCP

enterprise = FastMCP("USS Enterprise NCC-1701-D")

@enterprise.prompt()
def tactical_analysis(threat: str, quadrant: str = 'Alpha') -> str:
    """Request a tactical analysis of a threat in a specific quadrant.
    Args:
        threat: The nature of the threat (e.g. 'Romulan warbird', 'spatial anomaly')
        quadrant: The quadrant where the threat is located
    """
    return (
        f'You are the tactical officer aboard the USS Enterprise.\n\n'
        f'Analyze the following threat: {threat} in the {quadrant} Quadrant.\n\n'
        f'Provide: 1) Threat assessment 2) Recommended shield configuration '
        f'3) Suggested evasive maneuvers 4) Diplomatic options if applicable.'
    )

When a user selects this prompt in their client (e.g., Claude Desktop shows it in a slash-command menu), they provide the arguments, and the resulting text becomes part of the conversation context. The model then responds to that structured prompt.

🧠 Prompts with Complex Context Injection

Prompts can do more than return a simple string. They can assemble multi-message conversations, inject system context, and even embed resource data:

from mcp.server.fastmcp import FastMCP
from mcp.types import TextContent, UserMessage, AssistantMessage

enterprise = FastMCP("USS Enterprise NCC-1701-D")

@enterprise.prompt()
def away_team_briefing(planet: str, mission_type: str = 'survey') -> list:
    """Generate a complete away team briefing for a planetary mission.
    Args:
        planet: Target planet designation
        mission_type: Type of mission (survey, rescue, diplomatic, combat)
    """
    return [
        {
            "role": "system",
            "content": (
                "You are Commander Data, second officer of the USS Enterprise. "
                "You provide precise, thorough briefings with relevant data."
            )
        },
        {
            "role": "user",
            "content": (
                f"Commander Data, prepare an away team briefing for a "
                f"{mission_type} mission to {planet}.\n\n"
                f"Include:\n"
                f"- Environmental hazards\n"
                f"- Recommended team composition\n"
                f"- Equipment checklist\n"
                f"- Contingency protocols\n"
                f"- Estimated mission duration"
            )
        }
    ]

This creates a fully structured conversation that primes the model to respond as Commander Data giving a mission briefing. The user just picks "Away Team Briefing" from the menu and provides the planet name.

⚖️ When to Use Prompts vs System Messages

You might wonder: "Why not just put instructions in the system message?" Here's the tactical distinction:

CriterionSystem MessageMCP Prompt
Who controls it?Developer (hardcoded)User (selectable at runtime)
When applied?Always, at conversation startOn demand, user-triggered
Parameterized?No (static)Yes (dynamic arguments)
Discoverable?NoYes (listed via prompts/list)
Star Trek analogyStanding ordersTactical patterns (selectable maneuvers)

Use system messages for baseline personality and constraints ("You are a helpful assistant"). Use Prompts for specialized interaction patterns the user can invoke on demand ("Analyze this code for security vulnerabilities").

🚀 Combining All Three Primitives — The Complete Ship

A fully operational starship exposes Resources (sensors), Tools (weapons & systems), and Prompts (tactical patterns). Here's a complete server that demonstrates all three working together:

from mcp.server.fastmcp import FastMCP

enterprise = FastMCP("USS Enterprise NCC-1701-D")

# === RESOURCE: Ship's sensor data (read-only, application-controlled) ===
@enterprise.resource("enterprise://sensors/status")
def sensor_status() -> str:
    """Current sensor array status and readings."""
    return (
        "Long-range sensors: Online\n"
        "Short-range sensors: Online\n"
        "Nearest vessel: Romulan Warbird, bearing 247 mark 3, distance 2.4 light-years\n"
        "Anomalies detected: Subspace distortion at coordinates 427.3, 291.7"
    )

# === TOOL: Actionable capability (model-controlled) ===
@enterprise.tool()
def fire_phasers(target: str, power_level: int = 50) -> str:
    """Fire phaser array at specified target. Power level 1-100."""
    if power_level > 80:
        return f'Maximum phaser discharge at {target}. Direct hit!'
    return f'Phaser burst at {target}, power level {power_level}%. Standing by.'

@enterprise.tool()
def raise_shields(configuration: str = 'standard') -> str:
    """Raise deflector shields with specified configuration."""
    configs = {
        'standard': 'Standard shield configuration. All frequencies rotating.',
        'modulated': 'Shields modulated to Borg cutting beam frequency.',
        'metaphasic': 'Metaphasic shields engaged. Safe for stellar corona entry.'
    }
    return configs.get(configuration, f'Unknown configuration: {configuration}')

# === PROMPT: Tactical pattern (user-controlled) ===
@enterprise.prompt()
def tactical_analysis(threat: str, quadrant: str = 'Alpha') -> str:
    """Request a tactical analysis of a threat in a specific quadrant."""
    return (
        f'You are the tactical officer aboard the USS Enterprise.\n\n'
        f'Analyze the following threat: {threat} in the {quadrant} Quadrant.\n\n'
        f'Provide: 1) Threat assessment 2) Recommended shield configuration '
        f'3) Suggested evasive maneuvers 4) Diplomatic options if applicable.'
    )

@enterprise.prompt()
def captains_log(stardate: str, summary: str) -> str:
    """Format a Captain's Log entry."""
    return (
        f"Captain's Log, Stardate {stardate}.\n\n"
        f"Context: {summary}\n\n"
        f"Write a formal Captain's Log entry in the style of Jean-Luc Picard. "
        f"Include reflections on the moral and philosophical implications."
    )

if __name__ == "__main__":
    enterprise.run()

This single server file gives you a fully operational starship:

Engage. 🖖