FastMCP
BLOCKgrade F · trust 27/100🚀 The fast, Pythonic way to build MCP servers and clients.
agentsfastmcpllmsmcpmcp clientsmcp serversmcp toolsmodel context protocolOverview
From the repository's own README, as read at the audited commit.
<div align="center"><!-- omit in toc --><picture> <source width="550" media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/PrefectHQ/fastmcp/main/docs/assets/brand/f-watercolor-waves-4-dark.png"> <source width="550" media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/PrefectHQ/fastmcp/main/docs/assets/brand/f-watercolor-waves-4.png"> <img width="550" alt="FastMCP Logo" src="https://raw.githubusercontent.com/PrefectHQ/fastmcp/main/docs/assets/brand/f-watercolor-waves-2.png"></picture># FastMCP 🚀<strong>Move fast and make things.</strong>*Made with 💙 by [Prefect](https://www.prefect.io/)*[](https://gofastmcp.com)[](https://discord.gg/uu8dJCgttd)[](https://pypi.org/project/fastmcp)[](https://github.com/PrefectHQ/fastmcp-ts)[](https://github.com/PrefectHQ/fastmcp/actions/workflows/run-tests.yml)[](https://github.com/PrefectHQ/fastmcp/blob/main/LICENSE)<a href="https://trendshift.io/repositories/21461" target="_blank"><img src="https://trendshift.io/api/badge/repositories/21461" alt="prefecthq%2Ffastmcp | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a></div>---The [Model Context Protocol](https://modelcontextprotocol.io/) (MCP) connects LLMs to tools and data. FastMCP is a full MCP application framework for servers, clients, and interactive apps. A server starts with ordinary Python:```pythonfrom fastmcp import FastMCPmcp = FastMCP("Demo 🚀")@mcp.tooldef add(a: int, b: int) -> int: """Add two numbers""" return a + biConnect
Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.
claude mcp add fastmcp --env AUTH0_CONFIG_URL=${AUTH0_CONFIG_URL} --env AUTHKIT_DOMAIN=${AUTHKIT_DOMAIN} --env FASTMCP_GITHUB_TOKEN=${FASTMCP_GITHUB_TOKEN} --env FASTMCP_SERVER_AUTH_AWS_COGNITO_AWS_REGION=${FASTMCP_SERVER_AUTH_AWS_COGNITO_AWS_REGION} -- uvx fastmcp{
"mcpServers": {
"fastmcp": {
"command": "uvx",
"args": [
"fastmcp"
],
"env": {
"AUTH0_CONFIG_URL": "${AUTH0_CONFIG_URL}",
"AUTHKIT_DOMAIN": "${AUTHKIT_DOMAIN}",
"FASTMCP_GITHUB_TOKEN": "${FASTMCP_GITHUB_TOKEN}",
"FASTMCP_SERVER_AUTH_AWS_COGNITO_AWS_REGION": "${FASTMCP_SERVER_AUTH_AWS_COGNITO_AWS_REGION}"
}
}
}
}Exposed tools (200) 265 read · 37 write · 3 destructive
Blast radius: 3 tools can delete or overwrite. An agent that can be talked into calling a tool can be talked into calling this one.
| Tool | Risk | Description |
|---|---|---|
_trigger_docket | write | return |
add | write | return a + b |
add_comment | write | Add a comment to a request. Returns the updated request. |
add_item | write | Add a new item to inventory and return the full list. |
add_numbers | write | Add two numbers |
admin_tool | read | return |
analyze_data | read | Filter and analyze sales data. Returns rows, summary, and chart data. |
analyze_portfolio | read | Analyze a portfolio of stock symbols. |
annotate | read | current = trace.get_current_span() |
api_health | read | Show health details for each API endpoint. |
approve_request | read | Approve a pending request and return updated lists. |
ask_name | read | result = await ctx.elicit( |
async_echo | read | Async tool for testing |
async_tool | read | An async tool. |
background_tool | read | return x |
bare_sync_access | write | headers = get_http_headers() |
bare_tool | read | info = get_task_context() |
batch_process | read | Process batches. |
bg_progress_tool | read | await progress.set_total(3) |
bg_tool | read | await asyncio.sleep(0.01) |
blocked | read | return |
blocking | write | import time |
book_flight | read | return _ask( |
boom | read | raise ValueError( |
calc | read | return |
calculate | write | Add two numbers (v1.0). |
call_api | read | return f |
capture_docket_id | read | docket_ids.append((call_num, id(docket))) |
charge | read | Charge a payment (v1.0 - basic). |
check_both | read | assert isinstance(docket, Docket) |
check_docket | read | assert isinstance(docket, Docket) |
check_headers | read | headers = _worker_snapshot_headers() |
check_permission | read | return f |
check_request_header | read | return _worker_snapshot_headers().get( |
check_token | read | token = get_access_token() |
check_worker_status | read | return f |
checkpoint | read | if ctx.request_state is None: |
claimed_tool | read | return None |
combine | read | return f |
compute | read | Compute something. |
confirm_delete | destructive | Parks the task on one elicitation before doing the (pretend) deletion. |
contact_form | write | Show a form to create a new contact, with a live contact list below. |
context_sync_access | write | headers = get_http_headers() |
coordinated | write | started.set() |
count | read | return 1 |
create | write | Create item |
create_project | write | return |
create_user | write | Create a user. |
crunch | read | ... |
custom | read | A custom tool |
custom-add | write | return x + y |
custom_name | read | return str(x) |
custom_save | write | return name |
custom_tool | read | A custom tool |
declared_status | read | return { |
delete_item | destructive | Remove an item by ID and return the remaining inventory. |
demo | read | A demo app that exercises various MCP message types. |
double | read | return n * 2 |
dynamic_add | write | Add two numbers with offset |
dynamic_multiply | read | Multiply two numbers |
echo | read | Echo a message back. |
echo_with_logs | read | Echo a message and emit log notifications. |
employee_directory | read | Show a searchable, sortable employee directory. |
enabled | read | Task enabled |
enter_env | read | await ctx.disable_components(tags={ |
error_tool | read | raise ToolError( |
excluded_versioned_tool | read | return |
execute_trade | write | Execute a trade (simulated). |
exit_env | read | await ctx.reset_visibility() |
explicit_tool | read | return { |
explodes | read | raise MCPError(code=INTERNAL_ERROR, message= |
f | read | return 42 |
fail | read | Always raises an error. |
failing_tool | read | raise ValueError( |
farewell | read | Say farewell in their language. |
fast_async_tool | read | await anyio.sleep(0.01) |
fast_sync_tool | write | time.sleep(0.01) |
fast_tool | read | return x * 2 |
feature_flags | read | Toggle feature flags with live preview. |
fetch | read | Fetch data from |
fetch_data | read | return ( |
filter_by_category | read | Filter inventory by category. Pass |
filter_data | read | Filter sales data by region and/or product. |
finance_tool | read | return |
forbidden | read | Forbidden tool |
forever | read | await asyncio.Event().wait() |
full_name | read | responses = ctx.input_responses |
get_auth_type | read | auth = headers.get( |
get_client_ip | read | return request.client.host if request.client else |
get_market_data | read | Get current market data for a symbol. |
get_my_emails | read | async with httpx2.AsyncClient() as client: |
get_node | read | Get a node |
get_pr | read | Get a pull request |
get_request_details | read | Get full details for a single request. Available to both model and UI. |
get_request_id | read | return ctx.request_id |
get_summary | read | Return summary statistics for the full dataset. |
get_test_file_from_server | read | |
get_test_pdf_from_url | read | |
get_user_id | read | return token.claims.get( |
get_weather | read | Get the current weather |
greet | read | Greet someone in their language. |
greet_user | read | return f |
guard | read | calls.append(1) |
hidden_tool | read | return |
included_versioned_tool | read | return |
info | read | return |
inspect_items | read | return { |
instant_timeout | read | await anyio.sleep(0) # Give the event loop a chance to check timeout |
internal_tool | read | return |
introspect | read | return f |
leak | read | raise ValueError( |
list_contacts | read | Return all contacts. Visible to both the model and the UI. |
list_requests | read | List requests, optionally filtered by status. |
list_users | read | List all system users. |
log_progress | read | ctx.report_progress(50, 100, |
long_timeout | read | await anyio.sleep(0.01) |
make_tool | read | return |
mixed_audio_list_fn | read | return [ |
mixed_deps | read | assert isinstance(ctx, Context) |
mixed_file_list_fn | read | return [ |
mixed_list_fn | read | return [ |
modify | write | Modify the data provided. |
multi_input | read | Parks the task on two elicitations at once, so they can be answered separately. |
multiply | read | return x * y |
my_function | read | return f |
my_task | read | # Works transparently in both foreground and background task modes |
my_tool | read | A tool |
mytool | read | return |
new_tool | read | return |
no_task_tool | read | return |
normal_tool | read | return config[ |
ok | read | return |
old_tool | read | return |
one | read | return 1 |
one_question | read | responses = ctx.input_responses |
only_v5 | read | return |
pick | read | return |
ping | read | Ping the server |
plan_dinner | read | Plan a dinner menu, asking the user what they |
positional_name | read | |
premium_tool | read | return |
private_tool | read | return f |
process_data | read | return f |
progress_tool | read | await ctx.report_progress(0, 100, |
project_overview | read | Show project details organized in tabs. |
protected | read | return |
protocol_error_job | read | Raises a protocol-level error: `failed` with an inlined `error`. |
quarterly_revenue | read | Show quarterly revenue as a bar chart. |
query | read | return [] |
query_data | read | assert connection.is_open |
query_db | read | return f |
query_sync | write | assert connection.is_open |
quick_task | read | return value * 2 |
quick_tool | read | return value * 2 |
read_it | read | val = await ctx.get_state( |
refresh | read | Collect fresh system stats. |
regular_tool | read | return |
reject_request | read | Reject a pending request and return updated lists. |
remember | read | facts = await session.get( |
remote_task_tool | read | A remote tool that supports tasks |
report | read | return note |
reset_user_password | destructive | Reset a user |
return_audio | read | return Audio(path=str(test_audio)) |
return_bool | read | return True |
return_bytes | read | return b |
return_dataclass | read | return PersonDataclass(name= |
return_datetime | read | return datetime(2025, 11, 5, 12, 30, 45) |
return_dict | read | return { |
return_embedded_resource | read | return EmbeddedResource( |
return_empty_dict | read | return {} |
return_empty_list | read | return [] |
return_file | read | return File(path=str(test_file)) |
return_float | read | return 3.14159 |
return_image_content | read | return ImageContent( |
return_image_data | read | return Image(data=test_image.read_bytes(), format= |
return_image_path | read | return Image(path=str(test_image)) |
return_int | read | return 42 |
return_list | read | return [ |
return_mixed_content | read | return [ |
return_model | read | return UserData(name= |
return_none | read | return None |
return_optional | read | return |
return_optional_none | read | return None |
return_path | read | return Path( |
return_resource_link | read | return ResourceLink( |
return_set | write | return {1, 2, 3} |
return_string | read | return |
return_text_content | read | return TextContent(type= |
return_tuple | read | return (42, |
return_typeddict | read | return { |
return_union | read | return |
return_union_int | read | return 123 |
return_uuid | read | return UUID( |
run | write | Run something |
run_query | write | ... |
sales_chart | read | Show monthly online vs. retail sales as a bar chart. |
sales_dashboard | read | Company sales dashboard with KPIs, revenue trends, segment breakdown, and recent deals. |
sample_tool | read | return x * 2 |
save | write | return f |
save_contact | write | Save a new contact and return the updated list. |
Details
- Source
- jlowin/fastmcp
- PyPI
fastmcp- Transports
- sse · stdio · streamable-http
- Credentials it reads
AUTH0_CONFIG_URLAUTHKIT_DOMAINFASTMCP_GITHUB_TOKENFASTMCP_SERVER_AUTH_AWS_COGNITO_AWS_REGIONFASTMCP_SERVER_AUTH_AWS_COGNITO_CLIENT_IDFASTMCP_SERVER_AUTH_AWS_COGNITO_CLIENT_SECRETFASTMCP_SERVER_AUTH_AWS_COGNITO_USER_POOL_IDFASTMCP_SERVER_AUTH_AZURE_CLIENT_IDFASTMCP_SERVER_AUTH_AZURE_CLIENT_SECRETFASTMCP_SERVER_AUTH_AZURE_TENANT_IDFASTMCP_SERVER_AUTH_CLERK_CLIENT_IDFASTMCP_SERVER_AUTH_CLERK_CLIENT_SECRET- License
- Apache-2.0
- Stars
- 27,717 · pushed 0d ago
Trust audit
Do not install this without reading the findings. The audit found something that could harm you or your machine.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | WARN |
| L1 | Static analysis of the code | FAIL |
| L2 | Instruction surface (what it tells the agent) | FAIL |
| L3 | Class-specific surface | WARN |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- declared (4 observation(s))
- Network
- declared (2 observation(s))
- Shell
- declared (5 observation(s))
- Dependencies
- not all pinned
- Secrets in source
- found
Findings (25)
parsed = yaml.load(frontmatter_text, Loader=yaml.BaseLoader)
FastMCP has no resolver injection, but the underlying requests survive in a different shape: on a modern connection `Elicit`, `Sample`, and `ListRoots` all ride the guard pattern, where the tool retur
.claude/skills/code-review
.claude/skills/fix-issue
.claude/skills/python-tests
.claude/skills/release
.claude/skills/review-issue
return importlib.import_module(f"fastmcp.server.{name}")return importlib.import_module(private_name)
return importlib.import_module(module_name)
server_module = importlib.import_module(module_name)
DB_DSN = "postgresql://postgres:postgres@localhost:54320/memory_db"
"postgresql://postgres:postgres@localhost:54320/postgres"
token="stale-token-from-initial-auth",
token="fresh-token-after-refresh",
token="sdk-token-no-subject",
assert "-----BEGIN PRIVATE KEY-----" in private_pem
confirm_delete, delete_item, reset_user_password
.ccignore
.coderabbit.yaml
.pre-commit-config.yaml
.ccignore
.envrc
print(json.dumps({name: yaml.load(Path(f'.github/workflows/{name}.yml').read_text(), Loader=yaml.BaseLoader)spec = yaml.load(spec_file.read_text(), Loader=CSafeLoader)
Gates applied: instruction_override, no_behavioural_pass.
Audited 2026-09-18 · audit v0.4.0 · source sha cfbc52f849e6 · full audit: observations/trust-audit/mcp-server/jlowin__fastmcp.json · Report an issue or request a re-scan
Audit history
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-09-18 | cfbc52f849e6 | BLOCK | F | 27 | first audit |
Alternatives
Other servers in the same categories, safer ones first.
Questions
What is the FastMCP MCP server?
🚀 The fast, Pythonic way to build MCP servers and clients.
What tools does FastMCP expose?
200 in total: 265 read-only, 37 that write, and 3 that can delete or overwrite (confirm_delete, delete_item, reset_user_password). Every one is listed on this page with its risk.
Is FastMCP safe to connect to an agent?
No — not without reading the findings first. The audit graded it F (27/100) and found 2 critical or high issues in the source. Each one is listed on this page with the file and line it is on. Separately from the audit: 3 of its tools can destroy data, so scope the token you give it to what you actually need.
What credentials does FastMCP need?
It reads AUTH0_CONFIG_URL, AUTHKIT_DOMAIN, FASTMCP_GITHUB_TOKEN, FASTMCP_SERVER_AUTH_AWS_COGNITO_AWS_REGION, FASTMCP_SERVER_AUTH_AWS_COGNITO_CLIENT_ID, FASTMCP_SERVER_AUTH_AWS_COGNITO_CLIENT_SECRET, FASTMCP_SERVER_AUTH_AWS_COGNITO_USER_POOL_ID, FASTMCP_SERVER_AUTH_AZURE_CLIENT_ID, FASTMCP_SERVER_AUTH_AZURE_CLIENT_SECRET, FASTMCP_SERVER_AUTH_AZURE_TENANT_ID, FASTMCP_SERVER_AUTH_CLERK_CLIENT_ID and FASTMCP_SERVER_AUTH_CLERK_CLIENT_SECRET from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.
How does FastMCP run?
It speaks sse, stdio and streamable-http, so it runs as a local process your client starts. It is published on PyPI as fastmcp.
How current is this page?
The grade is for one exact copy of the source (cfbc52f849e6), read on 2026-09-18. The repository is watched and re-audited when it changes.
Provenance: OBSERVED · read 2026-09-18 · job trust-audit-2026-09-18