Skip to content

Feature/mcp prompts support #183

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

brodguez-atlas
Copy link

Add MCP Prompts Support to FastAPI-MCP

Summary

This PR adds comprehensive MCP (Model Context Protocol) prompts support to FastAPI-MCP, allowing users to create custom prompts and auto-generate helpful prompts for their FastAPI endpoints.

Features Added

  • Auto-generated tool prompts: Automatically creates prompts for each FastAPI endpoint
  • Custom prompt support: Users can define custom prompts with the @mcp.prompt() decorator
  • Prompt override capability: Custom prompts can override auto-generated ones
  • Flexible prompt control: Users can enable/disable auto-generation as needed

Changes Made

  • Added fastapi_mcp/prompts.py with core prompt functionality
  • Enhanced FastApiMCP class to support prompt registration and management
  • Added comprehensive tests in tests/test_prompts.py
  • Updated documentation and examples
  • Added support for both sync and async prompt functions

Testing

  • All existing tests pass
  • Added 16+ new tests covering prompt functionality
  • Coverage maintained at 84.60%
  • Linting and type checking passes

Usage Example

from fastapi import FastAPI
from fastapi_mcp import FastApiMCP

app = FastAPI()
mcp = FastApiMCP(app, auto_generate_prompts=True)

@mcp.prompt("api_help")
def api_help_prompt():
    return PromptMessage(
        role="user",
        content=TextContent(text="How can I use this API effectively?")
    )

mcp.mount()

- Add PromptRegistry class for managing prompt functions
- Add @mcp.prompt() decorator for FastAPI-native prompt registration
- Add prompt-related types (PromptMessage, TextContent, ImageContent, etc.)
- Add comprehensive test suite for prompts functionality
- Add example demonstrating various prompt patterns
- Support both sync and async prompt functions
- Support parameterized prompts with type validation
- Integrate with FastAPI dependency injection system
- Follow MCP specification for prompts/list and prompts/get
- Introduced detailed documentation for auto-generated and custom prompts in README.md.
- Enhanced examples to demonstrate the usage of MCP prompts, including tool prompts and troubleshooting prompts.
- Implemented auto-registration of tool prompts in the FastApiMCP server for improved user guidance.
- Added tests to verify the functionality of auto-generated prompts.
- Updated prompt titles and descriptions to enhance user understanding.
- Revised the structure of auto-generated prompts to focus on actionable guidelines and best practices.
- Adjusted tests to reflect changes in prompt content and ensure accuracy in generated messages.
- Consolidated prompt parameters in examples for cleaner presentation.
- Enhanced spacing and structure in the PromptRegistry class for better clarity.
- Updated test cases to reflect formatting changes and ensure consistency.
- Updated README.md to clarify the default behavior of auto-generated prompts and added examples for controlling prompt generation.
- Improved the example script to demonstrate three approaches for managing prompts: auto-generated only, custom prompts only, and a mixed approach.
- Modified the FastApiMCP class to include an option for enabling or disabling auto-prompt generation.
- Added tests to verify the functionality of prompt auto-generation control, ensuring both custom and auto-generated prompts work as intended.
Copy link

@boris-42 boris-42 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks very promissing. Thank you for your contirubtion: @brodguez-atlas

Note I am not a maintiner. Just trying to help with reviews.

I would suggest for next PRs to avoid unnecessary style changes. If you make them as separate PR they will be merged same day (hopefully) and your main PR less scary to review.

I pointed few things please take a look

@@ -6,7 +6,8 @@
- You can combine operation filtering with tag filtering (e.g., use `include_operations` with `include_tags`)
- When combining filters, a greedy approach will be taken. Endpoints matching either criteria will be included
"""
from examples.shared.apps.items import app # The FastAPI app

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@brodguez-atlas It's better to avoid unnecessary style changes with features as it makes it harder to review. 2 separated PR would be much better.

title="Prompts Example API", description="An example API demonstrating MCP Prompts functionality", version="1.0.0"
)

# Create MCP server with auto-generated prompts enabled (default: True)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be defaulted to the False, to preserve original behavior, and not impact existing integrations.

"""Generate a welcome message for API users."""
return PromptMessage(
role="user",
content=TextContent(text="Please provide a warm and friendly welcome message for new users of our API."),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you elaborate how LLM will consume this?

auto_generate_prompts: Annotated[
bool,
Doc("Whether to automatically generate default prompts for each tool. Defaults to True."),
] = True,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make it False to preserve existing behavior.

"""
# Focus on actionable guidance rather than repeating tool information
content_parts = [
f"You are about to use the **{tool.name}** tool.",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can this be done once for all tools? it looks more like MCP server description, rather than tool description..

return self._type_to_json_schema(non_none_type)

# Default to string for unknown types
return {"type": "string"}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would raise here errors, this looks like a ticking bomb to me

arguments.append(PromptArgument(name=param_name, description=param_desc, required=is_required))

# Create JSON schema property
properties[param_name] = self._type_to_json_schema(param_type)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's just use pydantic here, if we pass data: (somepaynanticclass) it will automatically have funcitonallity to generate json schema and it will be well aligned to the fastapi and less magic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants