Feedback tools
Tool names below are unprefixed. With prefix="support" they become
support_submit_feedback and so on.
submit_feedback
Section titled “submit_feedback”Takes a single argument, request, an object:
| Field | Type | Rules |
|---|---|---|
type | string, required | bug, feature, improvement or question |
title | string, required | Not blank, at most 255 characters; trimmed |
description | string, required | Not blank, at most 10000 characters; trimmed |
submitter | string, required | Not blank; trimmed. A model name or session id rather than a person’s name. |
contact_info | string or null | At 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": "..."}.
list_feedback
Section titled “list_feedback”| Argument | Type | Default |
|---|---|---|
type_filter | string or null | null (all types) |
status_filter | string or null | null (all statuses) |
page | integer | 1 |
per_page | integer | 10 |
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.
get_feedback_statistics
Section titled “get_feedback_statistics”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.
update_feedback_status
Section titled “update_feedback_status”| Argument | Type | Rules |
|---|---|---|
feedback_id | string, required | An id from submit_feedback |
new_status | string, required | open, in_progress, resolved or closed |
note | string or null | Recorded 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.
delete_feedback
Section titled “delete_feedback”| Argument | Type |
|---|---|
feedback_id | string, required |
Response: {"success": true, "message": "Feedback deleted successfully"}, or
{"success": false, "error": "..."}.
Python API
Section titled “Python API”from fastmcp_feedback import add_feedback_tools, create_feedback_serveradd_feedback_tools
Section titled “add_feedback_tools”add_feedback_tools(mcp, database_url=None, insights=None, prefix="", separator="_", instrumentation=None) -> None| Parameter | Description |
|---|---|
mcp | The FastMCP server. |
database_url | Sync SQLAlchemy URL. Defaults to in-memory SQLite (sqlite:///:memory:), which is lost on exit. |
insights | A FeedbackInsights. Defaults to one configured from the environment (off unless FEEDBACK_INSIGHTS_ENABLED=true). |
prefix | Prepended to every tool name. A trailing separator is stripped. |
separator | Between prefix and the tool name. |
instrumentation | The 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.
Mixins
Section titled “Mixins”| Class | Constructor | Tools |
|---|---|---|
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
Section titled “create_feedback_server”create_feedback_server(name="FastMCP Feedback Server", database_url=None, insights=None, description=None) -> FastMCPA 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
Section titled “FeedbackInsights”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.