Jeremiah Lowin commited on
Commit
2930e7a
·
1 Parent(s): 3acddf3

Update readme

Browse files
Files changed (2) hide show
  1. README.md +366 -313
  2. src/fastmcp/__init__.py +8 -1
README.md CHANGED
@@ -1,101 +1,105 @@
1
  <div align="center">
2
 
3
- ### 🎉 FastMCP has been added to the official MCP SDK! 🎉
4
-
5
- You can now find FastMCP as part of the official Model Context Protocol Python SDK:
6
-
7
- 👉 [github.com/modelcontextprotocol/python-sdk](https://github.com/modelcontextprotocol/python-sdk)
8
-
9
- *Please note: this repository is no longer maintained.*
10
-
11
- ---
12
-
13
-
14
- </br></br></br>
15
-
16
- </div>
17
-
18
- <div align="center">
19
-
20
  <!-- omit in toc -->
21
- # FastMCP 🚀
22
- <strong>The fast, Pythonic way to build MCP servers.</strong>
23
 
24
  [![PyPI - Version](https://img.shields.io/pypi/v/fastmcp.svg)](https://pypi.org/project/fastmcp)
25
  [![Tests](https://github.com/jlowin/fastmcp/actions/workflows/run-tests.yml/badge.svg)](https://github.com/jlowin/fastmcp/actions/workflows/run-tests.yml)
26
  [![License](https://img.shields.io/github/license/jlowin/fastmcp.svg)](https://github.com/jlowin/fastmcp/blob/main/LICENSE)
27
 
28
-
29
  </div>
30
 
31
- [Model Context Protocol (MCP)](https://modelcontextprotocol.io) servers are a new, standardized way to provide context and tools to your LLMs, and FastMCP makes building MCP servers simple and intuitive. Create tools, expose resources, and define prompts with clean, Pythonic code:
32
 
33
  ```python
34
- # demo.py
35
-
36
  from fastmcp import FastMCP
37
 
38
-
39
  mcp = FastMCP("Demo 🚀")
40
 
41
-
42
  @mcp.tool()
43
  def add(a: int, b: int) -> int:
44
  """Add two numbers"""
45
  return a + b
 
 
 
46
  ```
47
 
48
- That's it! Give Claude access to the server by running:
 
 
 
49
 
 
50
  ```bash
51
- fastmcp install demo.py
52
  ```
53
 
54
- FastMCP handles all the complex protocol details and server management, so you can focus on building great tools. It's designed to be high-level and Pythonic - in most cases, decorating a function is all you need.
 
 
55
 
 
 
 
 
 
 
 
56
 
57
- ### Key features:
58
- * **Fast**: High-level interface means less code and faster development
59
- * **Simple**: Build MCP servers with minimal boilerplate
60
- * **Pythonic**: Feels natural to Python developers
61
- * **Complete***: FastMCP aims to provide a full implementation of the core MCP specification
62
 
63
- (\*emphasis on *aims*)
64
 
65
- 🚨 🚧 🏗️ *FastMCP is under active development, as is the MCP specification itself. Core features are working but some advanced capabilities are still in progress.*
66
 
 
 
 
 
67
 
68
  <!-- omit in toc -->
69
  ## Table of Contents
70
 
 
 
71
  - [Installation](#installation)
72
  - [Quickstart](#quickstart)
73
  - [What is MCP?](#what-is-mcp)
74
- - [Core Concepts](#core-concepts)
75
- - [Server](#server)
76
- - [Resources](#resources)
77
  - [Tools](#tools)
 
78
  - [Prompts](#prompts)
79
- - [Images](#images)
80
  - [Context](#context)
 
 
 
 
 
 
81
  - [Running Your Server](#running-your-server)
82
  - [Development Mode (Recommended for Building \& Testing)](#development-mode-recommended-for-building--testing)
83
  - [Claude Desktop Integration (For Regular Use)](#claude-desktop-integration-for-regular-use)
84
  - [Direct Execution (For Advanced Use Cases)](#direct-execution-for-advanced-use-cases)
85
  - [Server Object Names](#server-object-names)
86
  - [Examples](#examples)
87
- - [Echo Server](#echo-server)
88
- - [SQLite Explorer](#sqlite-explorer)
89
  - [Contributing](#contributing)
90
- - [Prerequisites](#prerequisites)
91
- - [Installation](#installation-1)
92
- - [Testing](#testing)
93
- - [Formatting](#formatting)
94
- - [Opening a Pull Request](#opening-a-pull-request)
95
 
96
  ## Installation
97
 
98
- We strongly recommend installing FastMCP with [uv](https://docs.astral.sh/uv/), as it is required for deploying servers:
99
 
100
  ```bash
101
  uv pip install fastmcp
@@ -103,10 +107,13 @@ uv pip install fastmcp
103
 
104
  Note: on macOS, uv may need to be installed with Homebrew (`brew install uv`) in order to make it available to the Claude Desktop app.
105
 
106
- Alternatively, to use the SDK without deploying, you may use pip:
107
-
108
  ```bash
109
- pip install fastmcp
 
 
 
 
110
  ```
111
 
112
  ## Quickstart
@@ -115,21 +122,17 @@ Let's create a simple MCP server that exposes a calculator tool and some data:
115
 
116
  ```python
117
  # server.py
118
-
119
  from fastmcp import FastMCP
120
 
121
-
122
  # Create an MCP server
123
  mcp = FastMCP("Demo")
124
 
125
-
126
  # Add an addition tool
127
  @mcp.tool()
128
  def add(a: int, b: int) -> int:
129
  """Add two numbers"""
130
  return a + b
131
 
132
-
133
  # Add a dynamic greeting resource
134
  @mcp.resource("greeting://{name}")
135
  def get_greeting(name: str) -> str:
@@ -153,19 +156,20 @@ fastmcp dev server.py
153
 
154
  The [Model Context Protocol (MCP)](https://modelcontextprotocol.io) lets you build servers that expose data and functionality to LLM applications in a secure, standardized way. Think of it like a web API, but specifically designed for LLM interactions. MCP servers can:
155
 
156
- - Expose data through **Resources** (think of these sort of like GET endpoints; they are used to load information into the LLM's context)
157
- - Provide functionality through **Tools** (sort of like POST endpoints; they are used to execute code or otherwise produce a side effect)
158
- - Define interaction patterns through **Prompts** (reusable templates for LLM interactions)
159
  - And more!
160
 
161
- There is a low-level [Python SDK](https://github.com/modelcontextprotocol/python-sdk) available for implementing the protocol directly, but FastMCP aims to make that easier by providing a high-level, Pythonic interface.
162
 
163
- ## Core Concepts
164
 
 
165
 
166
- ### Server
167
 
168
- The FastMCP server is your core interface to the MCP protocol. It handles connection management, protocol compliance, and message routing:
169
 
170
  ```python
171
  from fastmcp import FastMCP
@@ -173,391 +177,440 @@ from fastmcp import FastMCP
173
  # Create a named server
174
  mcp = FastMCP("My App")
175
 
176
- # Specify dependencies for deployment and development
177
  mcp = FastMCP("My App", dependencies=["pandas", "numpy"])
178
  ```
179
 
180
- ### Resources
181
-
182
- Resources are how you expose data to LLMs. They're similar to GET endpoints in a REST API - they provide data but shouldn't perform significant computation or have side effects. Some examples:
183
 
184
- - File contents
185
- - Database schemas
186
- - API responses
187
- - System information
188
 
189
- Resources can be static:
190
- ```python
191
- @mcp.resource("config://app")
192
- def get_config() -> str:
193
- """Static configuration data"""
194
- return "App configuration here"
195
- ```
196
 
197
- Or dynamic with parameters (FastMCP automatically handles these as MCP templates):
198
  ```python
199
- @mcp.resource("users://{user_id}/profile")
200
- def get_user_profile(user_id: str) -> str:
201
- """Dynamic user data"""
202
- return f"Profile data for user {user_id}"
203
- ```
204
-
205
- ### Tools
206
 
207
- Tools let LLMs take actions through your server. Unlike resources, tools are expected to perform computation and have side effects. They're similar to POST endpoints in a REST API.
 
 
208
 
209
- Simple calculation example:
210
- ```python
211
  @mcp.tool()
212
- def calculate_bmi(weight_kg: float, height_m: float) -> float:
213
- """Calculate BMI given weight in kg and height in meters"""
214
- return weight_kg / (height_m ** 2)
215
- ```
216
-
217
- HTTP request example:
218
- ```python
219
- import httpx
220
 
221
  @mcp.tool()
222
- async def fetch_weather(city: str) -> str:
223
- """Fetch current weather for a city"""
224
- async with httpx.AsyncClient() as client:
225
- response = await client.get(
226
- f"https://api.weather.com/{city}"
227
- )
228
- return response.text
229
  ```
230
 
231
- Complex input handling example:
232
- ```python
233
- from pydantic import BaseModel, Field
234
- from typing import Annotated
235
 
236
- class ShrimpTank(BaseModel):
237
- class Shrimp(BaseModel):
238
- name: Annotated[str, Field(max_length=10)]
239
 
240
- shrimp: list[Shrimp]
241
 
242
- @mcp.tool()
243
- def name_shrimp(
244
- tank: ShrimpTank,
245
- # You can use pydantic Field in function signatures for validation.
246
- extra_names: Annotated[list[str], Field(max_length=10)],
247
- ) -> list[str]:
248
- """List all shrimp names in the tank"""
249
- return [shrimp.name for shrimp in tank.shrimp] + extra_names
 
 
 
 
 
 
 
 
 
 
 
 
250
  ```
251
 
252
  ### Prompts
253
 
254
- Prompts are reusable templates that help LLMs interact with your server effectively. They're like "best practices" encoded into your server. A prompt can be as simple as a string:
255
 
256
- ```python
257
- @mcp.prompt()
258
- def review_code(code: str) -> str:
259
- return f"Please review this code:\n\n{code}"
260
- ```
261
 
262
- Or a more structured sequence of messages:
263
  ```python
264
  from fastmcp.prompts.base import UserMessage, AssistantMessage
265
 
266
  @mcp.prompt()
267
- def debug_error(error: str) -> list[Message]:
 
 
 
 
 
 
268
  return [
269
- UserMessage("I'm seeing this error:"),
270
- UserMessage(error),
271
- AssistantMessage("I'll help debug that. What have you tried so far?")
272
  ]
273
  ```
274
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
275
 
276
  ### Images
277
 
278
- FastMCP provides an `Image` class that automatically handles image data in your server:
279
 
280
  ```python
281
  from fastmcp import FastMCP, Image
282
  from PIL import Image as PILImage
 
 
 
283
 
284
  @mcp.tool()
285
- def create_thumbnail(image_path: str) -> Image:
286
- """Create a thumbnail from an image"""
287
- img = PILImage.open(image_path)
288
  img.thumbnail((100, 100))
289
-
290
- # FastMCP automatically handles conversion and MIME types
291
- return Image(data=img.tobytes(), format="png")
 
292
 
293
  @mcp.tool()
294
- def load_image(path: str) -> Image:
295
- """Load an image from disk"""
296
- # FastMCP handles reading and format detection
297
  return Image(path=path)
298
  ```
 
299
 
300
- Images can be used as the result of both tools and resources.
301
 
302
- ### Context
 
 
303
 
304
- The Context object gives your tools and resources access to MCP capabilities. To use it, add a parameter annotated with `fastmcp.Context`:
305
 
306
  ```python
307
- from fastmcp import FastMCP, Context
 
 
308
 
309
- @mcp.tool()
310
- async def long_task(files: list[str], ctx: Context) -> str:
311
- """Process multiple files with progress tracking"""
312
- for i, file in enumerate(files):
313
- ctx.info(f"Processing {file}")
314
- await ctx.report_progress(i, len(files))
315
-
316
- # Read another resource if needed
317
- data = await ctx.read_resource(f"file://{file}")
318
-
319
- return "Processing complete"
320
- ```
321
 
322
- The Context object provides:
323
- - Progress reporting through `report_progress()`
324
- - Logging via `debug()`, `info()`, `warning()`, and `error()`
325
- - Resource access through `read_resource()`
326
- - Request metadata via `request_id` and `client_id`
327
 
328
- ## Running Your Server
 
 
329
 
330
- There are three main ways to use your FastMCP server, each suited for different stages of development:
 
 
331
 
332
- ### Development Mode (Recommended for Building & Testing)
 
 
333
 
334
- The fastest way to test and debug your server is with the MCP Inspector:
335
 
336
- ```bash
337
- fastmcp dev server.py
338
- ```
339
 
340
- This launches a web interface where you can:
341
- - Test your tools and resources interactively
342
- - See detailed logs and error messages
343
- - Monitor server performance
344
- - Set environment variables for testing
345
-
346
- During development, you can:
347
- - Add dependencies with `--with`:
348
- ```bash
349
- fastmcp dev server.py --with pandas --with numpy
350
- ```
351
- - Mount your local code for live updates:
352
- ```bash
353
- fastmcp dev server.py --with-editable .
354
- ```
355
 
356
- ### Claude Desktop Integration (For Regular Use)
357
 
358
- Once your server is ready, install it in Claude Desktop to use it with Claude:
 
 
359
 
360
- ```bash
361
- fastmcp install server.py
 
 
 
 
 
 
 
 
 
 
 
 
 
362
  ```
363
 
364
- Your server will run in an isolated environment with:
365
- - Automatic installation of dependencies specified in your FastMCP instance:
366
- ```python
367
- mcp = FastMCP("My App", dependencies=["pandas", "numpy"])
368
- ```
369
- - Custom naming via `--name`:
370
- ```bash
371
- fastmcp install server.py --name "My Analytics Server"
372
- ```
373
- - Environment variable management:
374
- ```bash
375
- # Set variables individually
376
- fastmcp install server.py -e API_KEY=abc123 -e DB_URL=postgres://...
377
-
378
- # Or load from a .env file
379
- fastmcp install server.py -f .env
380
- ```
381
 
382
- ### Direct Execution (For Advanced Use Cases)
383
 
384
- For advanced scenarios like custom deployments or running without Claude, you can execute your server directly:
 
 
385
 
386
  ```python
387
  from fastmcp import FastMCP
388
 
389
- mcp = FastMCP("My App")
 
390
 
391
- if __name__ == "__main__":
392
- mcp.run()
393
- ```
394
 
395
- Run it with:
396
- ```bash
397
- # Using the FastMCP CLI
398
- fastmcp run server.py
399
 
400
- # Or with Python/uv directly
401
- python server.py
402
- uv run python server.py
403
- ```
404
 
 
 
 
405
 
406
- Note: When running directly, you are responsible for ensuring all dependencies are available in your environment. Any dependencies specified on the FastMCP instance are ignored.
 
 
407
 
408
- Choose this method when you need:
409
- - Custom deployment configurations
410
- - Integration with other services
411
- - Direct control over the server lifecycle
412
 
413
- ### Server Object Names
414
 
415
- All FastMCP commands will look for a server object called `mcp`, `app`, or `server` in your file. If you have a different object name or multiple servers in one file, use the syntax `server.py:my_server`:
 
 
416
 
417
- ```bash
418
- # Using a standard name
419
- fastmcp run server.py
420
 
421
- # Using a custom name
422
- fastmcp run server.py:my_custom_server
 
423
  ```
424
 
425
- ## Examples
426
 
427
- Here are a few examples of FastMCP servers. For more, see the `examples/` directory.
428
 
429
- ### Echo Server
430
- A simple server demonstrating resources, tools, and prompts:
 
 
 
 
 
 
 
 
431
 
432
  ```python
 
433
  from fastmcp import FastMCP
434
 
435
- mcp = FastMCP("Echo")
 
436
 
437
- @mcp.resource("echo://{message}")
438
- def echo_resource(message: str) -> str:
439
- """Echo a message as a resource"""
440
- return f"Resource echo: {message}"
441
 
442
- @mcp.tool()
443
- def echo_tool(message: str) -> str:
444
- """Echo a message as a tool"""
445
- return f"Tool echo: {message}"
446
 
447
- @mcp.prompt()
448
- def echo_prompt(message: str) -> str:
449
- """Create an echo prompt"""
450
- return f"Please process this message: {message}"
 
451
  ```
452
 
453
- ### SQLite Explorer
454
- A more complex example showing database integration:
455
 
456
  ```python
 
 
457
  from fastmcp import FastMCP
458
- import sqlite3
459
 
460
- mcp = FastMCP("SQLite Explorer")
 
 
 
461
 
462
- @mcp.resource("schema://main")
463
- def get_schema() -> str:
464
- """Provide the database schema as a resource"""
465
- conn = sqlite3.connect("database.db")
466
- schema = conn.execute(
467
- "SELECT sql FROM sqlite_master WHERE type='table'"
468
- ).fetchall()
469
- return "\n".join(sql[0] for sql in schema if sql[0])
470
 
471
- @mcp.tool()
472
- def query_data(sql: str) -> str:
473
- """Execute SQL queries safely"""
474
- conn = sqlite3.connect("database.db")
475
- try:
476
- result = conn.execute(sql).fetchall()
477
- return "\n".join(str(row) for row in result)
478
- except Exception as e:
479
- return f"Error: {str(e)}"
480
 
481
- @mcp.prompt()
482
- def analyze_table(table: str) -> str:
483
- """Create a prompt template for analyzing tables"""
484
- return f"""Please analyze this database table:
485
- Table: {table}
486
- Schema:
487
- {get_schema()}
488
-
489
- What insights can you provide about the structure and relationships?"""
490
  ```
491
 
492
- ## Contributing
493
 
494
- <details>
495
 
496
- <summary><h3>Open Developer Guide</h3></summary>
497
 
498
- ### Prerequisites
499
 
500
- FastMCP requires Python 3.10+ and [uv](https://docs.astral.sh/uv/).
 
 
 
 
 
 
501
 
502
- ### Installation
503
 
504
- For development, we recommend installing FastMCP with development dependencies, which includes various utilities the maintainers find useful.
505
 
506
  ```bash
507
- git clone https://github.com/jlowin/fastmcp.git
508
- cd fastmcp
509
- uv sync
 
 
510
  ```
511
 
512
- ### Testing
 
 
513
 
514
- Please make sure to test any new functionality. Your tests should be simple and atomic and anticipate change rather than cement complex patterns.
 
 
 
 
 
 
 
 
 
 
515
 
516
- Run tests from the root directory:
517
 
 
518
 
519
  ```bash
520
- pytest -vv
 
521
  ```
522
 
523
- ### Formatting
524
 
525
- FastMCP enforces a variety of required formats, which you can automatically enforce with pre-commit.
526
 
527
- Install the pre-commit hooks:
 
 
 
 
 
528
 
529
- ```bash
530
- pre-commit install
531
- ```
532
 
533
- The hooks will now run on every commit (as well as on every PR). To run them manually:
534
 
535
- ```bash
536
- pre-commit run --all-files
537
- ```
538
 
539
- ### Opening a Pull Request
540
 
541
- Fork the repository and create a new branch:
542
 
543
- ```bash
544
- git checkout -b my-branch
545
- ```
546
 
547
- Make your changes and commit them:
548
 
 
 
549
 
 
 
 
550
  ```bash
551
- git add . && git commit -m "My changes"
552
  ```
553
 
554
- Push your changes to your fork:
555
 
 
 
 
556
 
557
- ```bash
558
- git push origin my-branch
559
- ```
 
 
 
560
 
561
- Feel free to reach out in a GitHub issue or discussion if you have any questions!
562
 
563
- </details>
 
1
  <div align="center">
2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  <!-- omit in toc -->
4
+ # FastMCP v2 🚀
5
+ <strong>Build and interact with MCP applications the fast, Pythonic way.</strong>
6
 
7
  [![PyPI - Version](https://img.shields.io/pypi/v/fastmcp.svg)](https://pypi.org/project/fastmcp)
8
  [![Tests](https://github.com/jlowin/fastmcp/actions/workflows/run-tests.yml/badge.svg)](https://github.com/jlowin/fastmcp/actions/workflows/run-tests.yml)
9
  [![License](https://img.shields.io/github/license/jlowin/fastmcp.svg)](https://github.com/jlowin/fastmcp/blob/main/LICENSE)
10
 
 
11
  </div>
12
 
13
+ [Model Context Protocol (MCP)](https://modelcontextprotocol.io) servers are a standardized way to provide context and tools to your LLMs, and FastMCP makes building *and interacting with* them simple and intuitive. Create tools, expose resources, define prompts, and connect components with clean, Pythonic code.
14
 
15
  ```python
16
+ # server.py
 
17
  from fastmcp import FastMCP
18
 
 
19
  mcp = FastMCP("Demo 🚀")
20
 
 
21
  @mcp.tool()
22
  def add(a: int, b: int) -> int:
23
  """Add two numbers"""
24
  return a + b
25
+
26
+ if __name__ == "__main__":
27
+ mcp.run()
28
  ```
29
 
30
+ Run it locally for testing:
31
+ ```bash
32
+ fastmcp dev server.py
33
+ ```
34
 
35
+ Install it for use with Claude Desktop:
36
  ```bash
37
+ fastmcp install server.py
38
  ```
39
 
40
+ FastMCP handles the complex protocol details and server management, letting you focus on building great tools and applications. It's designed to feel natural to Python developers.
41
+
42
+ ## Key Features:
43
 
44
+ * **Simple Server Creation:** Build MCP servers with minimal boilerplate using intuitive decorators (`@tool`, `@resource`, `@prompt`).
45
+ * **Powerful Clients:** Programmatically interact with *any* MCP server, regardless of how it was built.
46
+ * **Flexible Proxying:** Create proxy servers to expose existing MCP servers or clients with modifications, or **convert between transport protocols** (e.g., expose a Stdio server via SSE for web access).
47
+ * **Server Mounting:** Compose complex applications by mounting multiple FastMCP servers together.
48
+ * **API Generation:** Automatically create MCP servers from existing **OpenAPI specifications** or **FastAPI applications**.
49
+ * **Pythonic Interface:** Designed with familiar Python patterns like decorators and type hints.
50
+ * **Context Injection:** Easily access core MCP capabilities like sampling, logging, and progress reporting within your functions.
51
 
52
+ ---
53
+
54
+ ### FastMCP v1 and v2
55
+
56
+ FastMCP v1's core approach of using the `@tool`, `@resource`, `@prompt` decorators with the `FastMCP` class proved so successful that it became part of the official Model Context Protocol Python SDK! For basic server creation, you can use the upstream version by importing `mcp.server.fastmcp.FastMCP`.
57
 
58
+ 👉 The **MCP Python SDK** can be found at [github.com/modelcontextprotocol/python-sdk](https://github.com/modelcontextprotocol/python-sdk)
59
 
60
+ **FastMCP v2 builds upon v1's foundation** and adds the advanced features listed above (Client, Proxy, Mounting, API Generation, and more).
61
 
62
+ * **Need just the basics?** Use FastMCP v1 (the official SDK).
63
+ * **Need advanced features like clients, proxies, or mounting?** Use FastMCP v2 (this library).
64
+
65
+ ---
66
 
67
  <!-- omit in toc -->
68
  ## Table of Contents
69
 
70
+ - [Key Features:](#key-features)
71
+ - [FastMCP v1 and v2](#fastmcp-v1-and-v2)
72
  - [Installation](#installation)
73
  - [Quickstart](#quickstart)
74
  - [What is MCP?](#what-is-mcp)
75
+ - [Core Concepts (The Foundation)](#core-concepts-the-foundation)
76
+ - [The `FastMCP` Server](#the-fastmcp-server)
 
77
  - [Tools](#tools)
78
+ - [Resources](#resources)
79
  - [Prompts](#prompts)
 
80
  - [Context](#context)
81
+ - [Images](#images)
82
+ - [Advanced Features](#advanced-features)
83
+ - [MCP Client](#mcp-client)
84
+ - [Proxy Servers](#proxy-servers)
85
+ - [Composing MCP Servers](#composing-mcp-servers)
86
+ - [OpenAPI \& FastAPI Generation](#openapi--fastapi-generation)
87
  - [Running Your Server](#running-your-server)
88
  - [Development Mode (Recommended for Building \& Testing)](#development-mode-recommended-for-building--testing)
89
  - [Claude Desktop Integration (For Regular Use)](#claude-desktop-integration-for-regular-use)
90
  - [Direct Execution (For Advanced Use Cases)](#direct-execution-for-advanced-use-cases)
91
  - [Server Object Names](#server-object-names)
92
  - [Examples](#examples)
 
 
93
  - [Contributing](#contributing)
94
+ - [Prerequisites](#prerequisites)
95
+ - [Setup](#setup)
96
+ - [Testing](#testing)
97
+ - [Formatting \& Linting](#formatting--linting)
98
+ - [Pull Requests](#pull-requests)
99
 
100
  ## Installation
101
 
102
+ We strongly recommend installing FastMCP with [uv](https://docs.astral.sh/uv/), as it is required for deploying servers via the CLI:
103
 
104
  ```bash
105
  uv pip install fastmcp
 
107
 
108
  Note: on macOS, uv may need to be installed with Homebrew (`brew install uv`) in order to make it available to the Claude Desktop app.
109
 
110
+ For development, install with:
 
111
  ```bash
112
+ # Clone the repo first
113
+ git clone https://github.com/jlowin/fastmcp.git
114
+ cd fastmcp
115
+ # Install with dev dependencies
116
+ uv sync --dev
117
  ```
118
 
119
  ## Quickstart
 
122
 
123
  ```python
124
  # server.py
 
125
  from fastmcp import FastMCP
126
 
 
127
  # Create an MCP server
128
  mcp = FastMCP("Demo")
129
 
 
130
  # Add an addition tool
131
  @mcp.tool()
132
  def add(a: int, b: int) -> int:
133
  """Add two numbers"""
134
  return a + b
135
 
 
136
  # Add a dynamic greeting resource
137
  @mcp.resource("greeting://{name}")
138
  def get_greeting(name: str) -> str:
 
156
 
157
  The [Model Context Protocol (MCP)](https://modelcontextprotocol.io) lets you build servers that expose data and functionality to LLM applications in a secure, standardized way. Think of it like a web API, but specifically designed for LLM interactions. MCP servers can:
158
 
159
+ - Expose data through **Resources** (think GET endpoints; load info into context)
160
+ - Provide functionality through **Tools** (think POST/PUT endpoints; execute actions)
161
+ - Define interaction patterns through **Prompts** (reusable templates)
162
  - And more!
163
 
164
+ FastMCP provides a high-level, Pythonic interface for building and interacting with these servers.
165
 
166
+ ## Core Concepts (The Foundation)
167
 
168
+ These are the building blocks for creating MCP servers, using the familiar decorator-based approach.
169
 
170
+ ### The `FastMCP` Server
171
 
172
+ The central object representing your MCP application. It handles connections, protocol details, and routing.
173
 
174
  ```python
175
  from fastmcp import FastMCP
 
177
  # Create a named server
178
  mcp = FastMCP("My App")
179
 
180
+ # Specify dependencies needed when deployed via `fastmcp install`
181
  mcp = FastMCP("My App", dependencies=["pandas", "numpy"])
182
  ```
183
 
184
+ ### Tools
 
 
185
 
186
+ Tools allow LLMs to perform actions by executing your Python functions. They are ideal for tasks that involve computation, external API calls, or side effects.
 
 
 
187
 
188
+ Decorate synchronous or asynchronous functions with `@mcp.tool()`. FastMCP automatically generates the necessary MCP schema based on type hints and docstrings. Pydantic models can be used for complex inputs.
 
 
 
 
 
 
189
 
 
190
  ```python
191
+ import httpx
192
+ from pydantic import BaseModel
 
 
 
 
 
193
 
194
+ class UserInfo(BaseModel):
195
+ user_id: int
196
+ notify: bool = False
197
 
 
 
198
  @mcp.tool()
199
+ async def send_notification(user: UserInfo, message: str) -> dict:
200
+ """Sends a notification to a user if requested."""
201
+ if user.notify:
202
+ # Simulate sending notification
203
+ print(f"Notifying user {user.user_id}: {message}")
204
+ return {"status": "sent", "user_id": user.user_id}
205
+ return {"status": "skipped", "user_id": user.user_id}
 
206
 
207
  @mcp.tool()
208
+ def get_stock_price(ticker: str) -> float:
209
+ """Gets the current price for a stock ticker."""
210
+ # Replace with actual API call
211
+ prices = {"AAPL": 180.50, "GOOG": 140.20}
212
+ return prices.get(ticker.upper(), 0.0)
 
 
213
  ```
214
 
215
+ ### Resources
 
 
 
216
 
217
+ Resources expose data to LLMs. They should primarily provide information without significant computation or side effects (like GET requests).
 
 
218
 
219
+ Decorate functions with `@mcp.resource("your://uri")`. Use curly braces `{}` in the URI to define dynamic resources (templates) where parts of the URI become function parameters.
220
 
221
+ ```python
222
+ # Static resource returning simple text
223
+ @mcp.resource("config://app-version")
224
+ def get_app_version() -> str:
225
+ """Returns the application version."""
226
+ return "v2.1.0"
227
+
228
+ # Dynamic resource template expecting a 'user_id' from the URI
229
+ @mcp.resource("db://users/{user_id}/email")
230
+ async def get_user_email(user_id: str) -> str:
231
+ """Retrieves the email address for a given user ID."""
232
+ # Replace with actual database lookup
233
+ emails = {"123": "alice@example.com", "456": "bob@example.com"}
234
+ return emails.get(user_id, "not_found@example.com")
235
+
236
+ # Resource returning JSON data
237
+ @mcp.resource("data://product-categories")
238
+ def get_categories() -> list[str]:
239
+ """Returns a list of available product categories."""
240
+ return ["Electronics", "Books", "Home Goods"]
241
  ```
242
 
243
  ### Prompts
244
 
245
+ Prompts define reusable templates or interaction patterns for the LLM. They help guide the LLM on how to use your server's capabilities effectively.
246
 
247
+ Decorate functions with `@mcp.prompt()`. The function should return the desired prompt content, which can be a simple string, a `Message` object (like `UserMessage` or `AssistantMessage`), or a list of these.
 
 
 
 
248
 
 
249
  ```python
250
  from fastmcp.prompts.base import UserMessage, AssistantMessage
251
 
252
  @mcp.prompt()
253
+ def ask_review(code_snippet: str) -> str:
254
+ """Generates a standard code review request."""
255
+ return f"Please review the following code snippet for potential bugs and style issues:\n```python\n{code_snippet}\n```"
256
+
257
+ @mcp.prompt()
258
+ def debug_session_start(error_message: str) -> list[Message]:
259
+ """Initiates a debugging help session."""
260
  return [
261
+ UserMessage(f"I encountered an error:\n{error_message}"),
262
+ AssistantMessage("Okay, I can help with that. Can you provide the full traceback and tell me what you were trying to do?")
 
263
  ]
264
  ```
265
 
266
+ ### Context
267
+
268
+ Gain access to MCP server capabilities *within* your tool or resource functions by adding a parameter type-hinted with `fastmcp.Context`.
269
+
270
+ ```python
271
+ from fastmcp import Context, FastMCP
272
+
273
+ mcp = FastMCP("Context Demo")
274
+
275
+ @mcp.resource("system://status")
276
+ async def get_system_status(ctx: Context) -> dict:
277
+ """Checks system status and logs information."""
278
+ await ctx.info("Checking system status...")
279
+ # Perform checks
280
+ await ctx.report_progress(1, 1) # Report completion
281
+ return {"status": "OK", "load": 0.5, "client": ctx.client_id}
282
+
283
+ @mcp.tool()
284
+ async def process_large_file(file_uri: str, ctx: Context) -> str:
285
+ """Processes a large file, reporting progress and reading resources."""
286
+ await ctx.info(f"Starting processing for {file_uri}")
287
+ # Read the resource using the context
288
+ file_content_resource = await ctx.read_resource(file_uri)
289
+ file_content = file_content_resource[0].content # Assuming single text content
290
+ lines = file_content.splitlines()
291
+ total_lines = len(lines)
292
+
293
+ for i, line in enumerate(lines):
294
+ # Process line...
295
+ if (i + 1) % 100 == 0: # Report progress every 100 lines
296
+ await ctx.report_progress(i + 1, total_lines)
297
+
298
+ await ctx.info(f"Finished processing {file_uri}")
299
+ return f"Processed {total_lines} lines."
300
+
301
+ ```
302
+
303
+ The `Context` object provides:
304
+ * Logging: `ctx.debug()`, `ctx.info()`, `ctx.warning()`, `ctx.error()`
305
+ * Progress Reporting: `ctx.report_progress(current, total)`
306
+ * Resource Access: `await ctx.read_resource(uri)`
307
+ * Request Info: `ctx.request_id`, `ctx.client_id`
308
+ * Sampling (Advanced): `await ctx.sample(...)` to ask the connected LLM client for completions.
309
 
310
  ### Images
311
 
312
+ Easily handle image input and output using the `fastmcp.Image` helper class.
313
 
314
  ```python
315
  from fastmcp import FastMCP, Image
316
  from PIL import Image as PILImage
317
+ import io
318
+
319
+ mcp = FastMCP("Image Demo")
320
 
321
  @mcp.tool()
322
+ def create_thumbnail(image_data: Image) -> Image:
323
+ """Creates a 100x100 thumbnail from the provided image."""
324
+ img = PILImage.open(io.BytesIO(image_data.data)) # Assumes image_data received as Image with bytes
325
  img.thumbnail((100, 100))
326
+ buffer = io.BytesIO()
327
+ img.save(buffer, format="PNG")
328
+ # Return a new Image object with the thumbnail data
329
+ return Image(data=buffer.getvalue(), format="png")
330
 
331
  @mcp.tool()
332
+ def load_image_from_disk(path: str) -> Image:
333
+ """Loads an image from the specified path."""
334
+ # Handles reading file and detecting format based on extension
335
  return Image(path=path)
336
  ```
337
+ FastMCP handles the conversion to/from the base64-encoded format required by the MCP protocol.
338
 
339
+ ## Advanced Features
340
 
341
+ Building on the core concepts, FastMCP v2 introduces powerful features for more complex scenarios:
342
+
343
+ ### MCP Client
344
 
345
+ The client allows your Python code to interact with *any* MCP server, whether it's built with FastMCP, the official SDK, or another implementation. This is essential for testing, building meta-tools, or integrating MCP servers.
346
 
347
  ```python
348
+ import asyncio
349
+ from fastmcp import Client
350
+ from fastmcp.client.transports import StdioTransport # Example transport
351
 
352
+ async def main():
353
+ # Connect to a server running via standard I/O
354
+ # Replace with the actual command to start your target server
355
+ client = Client(StdioTransport(command="python", args=["path/to/target_server.py"]))
 
 
 
 
 
 
 
 
356
 
357
+ async with client:
358
+ # Discover tools
359
+ tools_result = await client.list_tools()
360
+ print(f"Available Tools: {[t.name for t in tools_result.tools]}")
 
361
 
362
+ # Call a tool
363
+ add_result = await client.call_tool("add", {"a": 10, "b": 5})
364
+ print(f"Result of add(10, 5): {add_result.content[0].text}") # Output: 15
365
 
366
+ # Read a resource
367
+ greeting = await client.read_resource("greeting://Client")
368
+ print(f"Resource Content: {greeting.contents[0].text}") # Output: Hello, Client!
369
 
370
+ if __name__ == "__main__":
371
+ asyncio.run(main())
372
+ ```
373
 
374
+ The client supports various transports (`WSTransport`, `SSETransport`, `StdioTransport`, `FastMCPTransport`) and intelligently infers the correct one based on the connection information provided (URL, `FastMCP` instance, command arguments, etc.).
375
 
376
+ ### Proxy Servers
 
 
377
 
378
+ Create a FastMCP server that acts as an intermediary, proxying requests to another MCP endpoint (which could be a server or another client connection).
 
 
 
 
 
 
 
 
 
 
 
 
 
 
379
 
380
+ **Use Cases:**
381
 
382
+ * **Transport Conversion:** Expose a server running on Stdio (like many local tools) over SSE or WebSockets, making it accessible to web clients or Claude Desktop.
383
+ * **Adding Functionality:** Wrap an existing server to add authentication, request logging, or modified tool behavior.
384
+ * **Aggregating Servers:** Combine multiple backend MCP servers behind a single proxy interface (though `mount` might be simpler for this).
385
 
386
+ ```python
387
+ import asyncio
388
+ from fastmcp import FastMCP, Client
389
+ from fastmcp.client.transports import PythonStdioTransport
390
+
391
+ # Create a client that connects to the original server
392
+ proxy_client = Client(
393
+ transport=PythonStdioTransport('path/to/original_stdio_server.py'),
394
+ )
395
+
396
+ # Create a proxy server that connects to the client and exposes its capabilities
397
+ proxy = FastMCP.as_proxy(proxy_client, name="Stdio-to-SSE Proxy")
398
+
399
+ if __name__ == "__main__":
400
+ proxy.run(transport='sse')
401
  ```
402
 
403
+ `FastMCP.as_proxy` is an `async` classmethod. It connects to the target, discovers its capabilities, and dynamically builds the proxy server instance.
404
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
405
 
 
406
 
407
+ ### Composing MCP Servers
408
+
409
+ Structure larger MCP applications by creating modular FastMCP servers and "mounting" them onto a parent server. This automatically handles prefixing for tool names and resource URIs, preventing conflicts.
410
 
411
  ```python
412
  from fastmcp import FastMCP
413
 
414
+ # --- Weather MCP ---
415
+ weather_mcp = FastMCP("Weather Service")
416
 
417
+ @weather_mcp.tool()
418
+ def get_forecast(city: str):
419
+ return f"Sunny in {city}"
420
 
421
+ @weather_mcp.resource("data://temp/{city}")
422
+ def get_temp(city: str):
423
+ return 25.0
 
424
 
425
+ # --- News MCP ---
426
+ news_mcp = FastMCP("News Service")
 
 
427
 
428
+ @news_mcp.tool()
429
+ def fetch_headlines():
430
+ return ["Big news!", "Other news"]
431
 
432
+ @news_mcp.resource("data://latest_story")
433
+ def get_story():
434
+ return "A story happened."
435
 
436
+ # --- Composite MCP ---
 
 
 
437
 
438
+ mcp = FastMCP("Composite")
439
 
440
+ # Mount sub-apps with prefixes
441
+ mcp.mount("weather", weather_mcp) # Tools prefixed "weather/", resources prefixed "weather+"
442
+ mcp.mount("news", news_mcp) # Tools prefixed "news/", resources prefixed "news+"
443
 
444
+ @mcp.tool()
445
+ def ping():
446
+ return "Composite OK"
447
 
448
+
449
+ if __name__ == "__main__":
450
+ mcp.run()
451
  ```
452
 
453
+ This promotes code organization and reusability for complex MCP systems.
454
 
455
+ ### OpenAPI & FastAPI Generation
456
 
457
+ Leverage your existing web APIs by automatically generating FastMCP servers from them.
458
+
459
+ By default, the following rules are applied:
460
+ - `GET` requests -> MCP resources
461
+ - `GET` requests with path parameters -> MCP resource templates
462
+ - All other HTTP methods -> MCP tools
463
+
464
+ You can override these rules to customize or even ignore certain endpoints.
465
+
466
+ **From FastAPI:**
467
 
468
  ```python
469
+ from fastapi import FastAPI
470
  from fastmcp import FastMCP
471
 
472
+ # Your existing FastAPI application
473
+ fastapi_app = FastAPI(title="My Existing API")
474
 
475
+ @fastapi_app.get("/status")
476
+ def get_status():
477
+ return {"status": "running"}
 
478
 
479
+ @fastapi_app.post("/items")
480
+ def create_item(name: str, price: float):
481
+ return {"id": 1, "name": name, "price": price}
 
482
 
483
+ # Generate an MCP server directly from the FastAPI app
484
+ mcp_server = FastMCP.from_fastapi(fastapi_app)
485
+
486
+ if __name__ == "__main__":
487
+ mcp_server.run()
488
  ```
489
 
490
+ **From an OpenAPI Specification:**
 
491
 
492
  ```python
493
+ import httpx
494
+ import json
495
  from fastmcp import FastMCP
 
496
 
497
+ # Load the OpenAPI spec (dict)
498
+ # with open("my_api_spec.json", "r") as f:
499
+ # openapi_spec = json.load(f)
500
+ openapi_spec = { ... } # Your spec dict
501
 
502
+ # Create an HTTP client to make requests to the actual API endpoint
503
+ http_client = httpx.AsyncClient(base_url="https://api.yourservice.com")
 
 
 
 
 
 
504
 
505
+ # Generate the MCP server
506
+ mcp_server = FastMCP.from_openapi(openapi_spec, client=http_client)
 
 
 
 
 
 
 
507
 
508
+ if __name__ == "__main__":
509
+ mcp_server.run()
 
 
 
 
 
 
 
510
  ```
511
 
512
+ ## Running Your Server
513
 
514
+ Choose the method that best suits your needs:
515
 
516
+ ### Development Mode (Recommended for Building & Testing)
517
 
518
+ Use `fastmcp dev` for an interactive testing environment with the MCP Inspector.
519
 
520
+ ```bash
521
+ fastmcp dev your_server_file.py
522
+ # With temporary dependencies
523
+ fastmcp dev your_server_file.py --with pandas --with numpy
524
+ # With local package in editable mode
525
+ fastmcp dev your_server_file.py --with-editable .
526
+ ```
527
 
528
+ ### Claude Desktop Integration (For Regular Use)
529
 
530
+ Use `fastmcp install` to set up your server for persistent use within the Claude Desktop app. It handles creating an isolated environment using `uv`.
531
 
532
  ```bash
533
+ fastmcp install your_server_file.py
534
+ # With a custom name in Claude
535
+ fastmcp install your_server_file.py --name "My Analysis Tool"
536
+ # With extra packages and environment variables
537
+ fastmcp install server.py --with requests -v API_KEY=123 -f .env
538
  ```
539
 
540
+ ### Direct Execution (For Advanced Use Cases)
541
+
542
+ Run your server script directly for custom deployments or integrations outside of Claude. You manage the environment and dependencies yourself.
543
 
544
+ Add to your `your_server_file.py`:
545
+ ```python
546
+ if __name__ == "__main__":
547
+ mcp.run() # Assuming 'mcp' is your FastMCP instance
548
+ ```
549
+ Run with:
550
+ ```bash
551
+ python your_server_file.py
552
+ # or
553
+ uv run python your_server_file.py
554
+ ```
555
 
556
+ ### Server Object Names
557
 
558
+ If your `FastMCP` instance is not named `mcp`, `server`, or `app`, specify it using `file:object` syntax for the `dev` and `install` commands:
559
 
560
  ```bash
561
+ fastmcp dev my_module.py:my_mcp_instance
562
+ fastmcp install api.py:api_app
563
  ```
564
 
565
+ ## Examples
566
 
567
+ Explore the `examples/` directory for code samples demonstrating various features:
568
 
569
+ * `simple_echo.py`: Basic tool, resource, and prompt.
570
+ * `complex_inputs.py`: Using Pydantic models for tool inputs.
571
+ * `mount_example.py`: Mounting multiple FastMCP servers.
572
+ * `screenshot.py`: Tool returning an Image object.
573
+ * `text_me.py`: Tool interacting with an external API.
574
+ * `memory.py`: More complex example with database interaction.
575
 
576
+ ## Contributing
 
 
577
 
578
+ Contributions make the open-source community vibrant! We welcome improvements and features.
579
 
580
+ <details>
 
 
581
 
582
+ <summary><h3>Open Developer Guide</h3></summary>
583
 
584
+ #### Prerequisites
585
 
586
+ * Python 3.10+
587
+ * [uv](https://docs.astral.sh/uv/)
 
588
 
589
+ #### Setup
590
 
591
+ 1. Clone: `git clone https://github.com/jlowin/fastmcp.git && cd fastmcp`
592
+ 2. Install Env & Dependencies: `uv venv && uv sync --dev` (Activate the `.venv` after creation)
593
 
594
+ #### Testing
595
+
596
+ Run the test suite:
597
  ```bash
598
+ uv run pytest -vv
599
  ```
600
 
601
+ #### Formatting & Linting
602
 
603
+ We use `ruff` via `pre-commit`.
604
+ 1. Install hooks: `pre-commit install`
605
+ 2. Run checks: `pre-commit run --all-files`
606
 
607
+ #### Pull Requests
608
+
609
+ 1. Fork the repository.
610
+ 2. Create a feature branch.
611
+ 3. Make changes, commit, and push to your fork.
612
+ 4. Open a pull request against the `main` branch of `jlowin/fastmcp`.
613
 
614
+ Please open an issue or discussion for questions or suggestions!
615
 
616
+ </details>
src/fastmcp/__init__.py CHANGED
@@ -6,7 +6,14 @@ from importlib.metadata import version
6
  from fastmcp.server.server import FastMCP
7
  from fastmcp.server.context import Context
8
  from fastmcp.client import Client
 
9
  from . import client, settings
10
 
11
  __version__ = version("fastmcp")
12
- __all__ = ["FastMCP", "Context", "client", "settings"]
 
 
 
 
 
 
 
6
  from fastmcp.server.server import FastMCP
7
  from fastmcp.server.context import Context
8
  from fastmcp.client import Client
9
+ from fastmcp.utilities.types import Image
10
  from . import client, settings
11
 
12
  __version__ = version("fastmcp")
13
+ __all__ = [
14
+ "FastMCP",
15
+ "Context",
16
+ "client",
17
+ "settings",
18
+ "Image",
19
+ ]