Skip to content

Feedback tools

Tool names below are unprefixed. With prefix="support" they become support_submit_feedback and so on.

Takes a single argument, request, an object:

FieldTypeRules
typestring, requiredbug, feature, improvement or question
titlestring, requiredNot blank, at most 255 characters; trimmed
descriptionstring, requiredNot blank, at most 10000 characters; trimmed
submitterstring, requiredNot blank; trimmed. A model name or session id rather than a person’s name.
contact_infostring or nullAt most 255 characters
{"request": {"type": "bug", "title": "forecast fails for some cities",
"description": "Atlantis returns ok=False.", "submitter": "claude-session-41"}}

Response:

{"success": true, "feedback_id": "1", "message": "Feedback submitted successfully", "linked_calls": 2}

feedback_id is a string. linked_calls is present only when the tools were added with instrumentation=; it is the number of calls linked to the report, and the report is also recorded as a feedback.submitted event. Arguments that fail validation are rejected by FastMCP before the tool runs, so the client gets a tool error naming the field. A storage failure returns {"success": false, "error": "..."}.

ArgumentTypeDefault
type_filterstring or nullnull (all types)
status_filterstring or nullnull (all statuses)
pageinteger1
per_pageinteger10

Newest first. Response:

{"feedback": [{"id": "1", "type": "bug", "title": "forecast fails for some cities",
"description": "Atlantis returns ok=False.", "submitter": "claude-session-41",
"contact_info": null, "status": "open",
"created_at": "2026-10-01T18:02:11.304512", "updated_at": "2026-10-01T18:02:11.304512"}],
"total_count": 1, "page": 1, "per_page": 10}

Timestamps are ISO 8601 without a zone, in UTC. On failure the same shape comes back empty with an error field.

No arguments. Response:

{"total_count": 3, "by_type": {"BUG": 2, "QUESTION": 1}, "by_status": {"OPEN": 2, "RESOLVED": 1}, "recent_count": 3}

recent_count counts items created in the last 7 days. The keys of by_type and by_status are the stored enum names in upper case, unlike the lower-case values list_feedback returns.

ArgumentTypeRules
feedback_idstring, requiredAn id from submit_feedback
new_statusstring, requiredopen, in_progress, resolved or closed
notestring or nullRecorded only in usage analytics, as its length

Response: {"success": true, "message": "Feedback status updated successfully"}, or {"success": false, "error": "Feedback with ID 99 not found"}. Any status can move to any other; open, in_progress, resolved, closed is the intended order.

ArgumentType
feedback_idstring, required

Response: {"success": true, "message": "Feedback deleted successfully"}, or {"success": false, "error": "..."}.

from fastmcp_feedback import add_feedback_tools, create_feedback_server
add_feedback_tools(mcp, database_url=None, insights=None, prefix="", separator="_",
instrumentation=None) -> None
ParameterDescription
mcpThe FastMCP server.
database_urlSync SQLAlchemy URL. Defaults to in-memory SQLite (sqlite:///:memory:), which is lost on exit.
insightsA FeedbackInsights. Defaults to one configured from the environment (off unless FEEDBACK_INSIGHTS_ENABLED=true).
prefixPrepended to every tool name. A trailing separator is stripped.
separatorBetween prefix and the tool name.
instrumentationThe middleware from instrument(). submit_feedback then links preceding calls, records feedback.submitted, and returns linked_calls.

add_submission_tools, add_retrieval_tools and add_management_tools take (mcp, database_url=None, insights=None, prefix="") and add one group each.

ClassConstructorTools
SubmissionMixin(database, insights=None, instrumentation=None)submit_feedback
RetrievalMixin(database, insights=None)list_feedback, get_feedback_statistics
ManagementMixin(database, insights=None)update_feedback_status, delete_feedback

database is a FeedbackDatabase(database_url=None), or get_database_session(database_url="sqlite:///feedback.db"), which builds one. Register with mixin.register_tools(mcp, prefix=None, separator="_").

create_feedback_server(name="FastMCP Feedback Server", database_url=None,
insights=None, description=None) -> FastMCP

A new FastMCP server with all five tools, for mounting: main_app.mount(server, "feedback"). create_submission_server, create_management_server and create_analytics_server build servers with subsets.

FeedbackInsights(enabled=None, retention_days=90)

In-memory usage analytics for the feedback tools. enabled=None reads FEEDBACK_INSIGHTS_ENABLED (true turns it on); retention_days is then read from FEEDBACK_INSIGHTS_RETENTION_DAYS. Records metadata only (types, lengths, timings), never feedback text or contact details.