@prefecthq/fastmcp-ts 0.1.0 β 1.0.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -14
- package/dist/cli/index.cjs +18766 -18217
- package/dist/cli/index.cjs.map +1 -1
- package/dist/client.d.ts +568 -45
- package/dist/client.js +740 -182
- package/dist/client.js.map +1 -1
- package/dist/server.d.ts +441 -30
- package/dist/server.js +827 -330
- package/dist/server.js.map +1 -1
- package/package.json +9 -3
package/README.md
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
The TypeScript framework for building [Model Context Protocol](https://modelcontextprotocol.io) servers, clients, and apps. The official TypeScript counterpart to [FastMCP for Python](https://github.com/PrefectHQ/fastmcp) - built and maintained with π by the same team at [Prefect](https://prefect.io).
|
|
4
4
|
|
|
5
|
-
Built on the official [
|
|
5
|
+
Built on version 2 of the official [MCP TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk) β the scoped `@modelcontextprotocol/server` and `@modelcontextprotocol/client` packages. FastMCP handles the protocol plumbing so you can focus on what your server actually does.
|
|
6
|
+
|
|
7
|
+
FastMCP 1.0 speaks both MCP protocol generations: the 2025 legacy era and the 2026-07-28 modern era. A server serves both at once, and a client negotiates one. Upgrading from 0.x keeps your existing code running β the client defaults to the legacy era until you opt into the modern one. The [migration guide](docs/migration.mdx) covers the upgrade path.
|
|
6
8
|
|
|
7
9
|
## Installation
|
|
8
10
|
|
|
@@ -58,6 +60,13 @@ await server.run() // stdio (default)
|
|
|
58
60
|
// await server.run({ transport: 'http', port: 3000 })
|
|
59
61
|
```
|
|
60
62
|
|
|
63
|
+
Save this file as `server.ts`. Installing `@prefecthq/fastmcp-ts` also installs the `fastmcp` CLI. Use it to inspect the server and call a tool, with no build step:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
npx fastmcp inspect --file server.ts
|
|
67
|
+
npx fastmcp call add --file server.ts a=1 b=2
|
|
68
|
+
```
|
|
69
|
+
|
|
61
70
|
### Context
|
|
62
71
|
|
|
63
72
|
Handlers access logging, progress, LLM sampling, user elicitation, and per-session state through an ambient context with no prop-drilling.
|
|
@@ -85,7 +94,7 @@ server.tool(
|
|
|
85
94
|
maxTokens: 512,
|
|
86
95
|
})
|
|
87
96
|
|
|
88
|
-
return content.text
|
|
97
|
+
return content.type === 'text' ? content.text : ''
|
|
89
98
|
}
|
|
90
99
|
)
|
|
91
100
|
```
|
|
@@ -121,7 +130,7 @@ const weather = new FastMCP({ name: 'weather' })
|
|
|
121
130
|
weather.tool({ name: 'forecast', description: 'Get a forecast', input: z.object({ city: z.string() }) }, ({ city }) => `Forecast for ${city}`)
|
|
122
131
|
|
|
123
132
|
// Wrap a remote server as a mountable instance
|
|
124
|
-
const maps = await createProxy({
|
|
133
|
+
const maps = await createProxy({ type: 'http', url: 'http://maps-service/mcp' })
|
|
125
134
|
|
|
126
135
|
const gateway = new FastMCP({ name: 'gateway' })
|
|
127
136
|
gateway.mount(weather, 'weather') // β weather_forecast
|
|
@@ -168,7 +177,7 @@ import Anthropic from '@anthropic-ai/sdk'
|
|
|
168
177
|
|
|
169
178
|
const client = await Client.connect('http://localhost:3000', {
|
|
170
179
|
handlers: {
|
|
171
|
-
sampling:
|
|
180
|
+
sampling: new AnthropicSamplingAdapter(new Anthropic()).asHandler(),
|
|
172
181
|
},
|
|
173
182
|
})
|
|
174
183
|
```
|
|
@@ -201,7 +210,6 @@ FastMCP ships a server-side component library for building interactive UIs rende
|
|
|
201
210
|
|
|
202
211
|
```typescript
|
|
203
212
|
import { FastMCPApp, Column, Row, Text, Input, Button, Table } from '@prefecthq/fastmcp-ts/server'
|
|
204
|
-
import { z } from 'zod'
|
|
205
213
|
|
|
206
214
|
const app = new FastMCPApp({ name: 'search-app', version: '1.0.0' })
|
|
207
215
|
|
|
@@ -213,19 +221,15 @@ app.entrypoint(
|
|
|
213
221
|
Text('Product Search'),
|
|
214
222
|
Row({}, [
|
|
215
223
|
Input({ name: 'query', placeholder: 'Search productsβ¦' }),
|
|
216
|
-
Button({ label: 'Search',
|
|
224
|
+
Button({ label: 'Search', action: app.toolRef('run_search') }),
|
|
217
225
|
]),
|
|
218
226
|
])
|
|
219
227
|
)
|
|
220
228
|
|
|
221
229
|
// Backend tool: hidden from the LLM, callable only from within the rendered UI
|
|
222
230
|
app.backendTool(
|
|
223
|
-
{
|
|
224
|
-
|
|
225
|
-
description: 'Execute the search query',
|
|
226
|
-
input: z.object({ query: z.string() }),
|
|
227
|
-
},
|
|
228
|
-
async ({ query }) => {
|
|
231
|
+
{ name: 'run_search', description: 'Execute the search query' },
|
|
232
|
+
async ({ query }: { query: string }) => {
|
|
229
233
|
const rows = await db.search(query)
|
|
230
234
|
return Table({ columns: ['Name', 'Price', 'Stock'], rows })
|
|
231
235
|
}
|
|
@@ -247,7 +251,15 @@ const server = new FastMCP({ name: 'my-server' })
|
|
|
247
251
|
server.addProvider(new Approval()) // confirm/deny card injected back into the conversation
|
|
248
252
|
server.addProvider(new Choice()) // clickable option list
|
|
249
253
|
server.addProvider(new FileUpload()) // drag-and-drop file picker; file bytes never pass through the LLM
|
|
250
|
-
|
|
254
|
+
|
|
255
|
+
// Auto-generated, validated form from any Standard Schema
|
|
256
|
+
server.addProvider(
|
|
257
|
+
new FormInput({
|
|
258
|
+
name: 'contact_form',
|
|
259
|
+
description: 'Contact form',
|
|
260
|
+
schema: z.object({ name: z.string(), email: z.string() }),
|
|
261
|
+
}),
|
|
262
|
+
)
|
|
251
263
|
```
|
|
252
264
|
|
|
253
265
|
### Generative UI
|
|
@@ -277,6 +289,8 @@ fastmcp run server.ts --transport http --port 3000
|
|
|
277
289
|
fastmcp inspect --file server.ts
|
|
278
290
|
fastmcp inspect --url http://localhost:3000
|
|
279
291
|
fastmcp inspect --file server.ts --json
|
|
292
|
+
fastmcp inspect --file server.ts --modern # negotiate the 2026-07-28 protocol era over stdio
|
|
293
|
+
fastmcp inspect --file server.ts --pin 2026-07-28 # require that exact era
|
|
280
294
|
|
|
281
295
|
# Call a tool, read a resource, or get a prompt
|
|
282
296
|
fastmcp call add --file server.ts a=1 b=2
|
|
@@ -298,12 +312,15 @@ fastmcp install claude-desktop server.ts
|
|
|
298
312
|
fastmcp discover
|
|
299
313
|
```
|
|
300
314
|
|
|
315
|
+
`fastmcp inspect`, `fastmcp list`, and `fastmcp call` connect over stdio by default, when you pass `--file` or `--command`. Add `--modern` to negotiate the newer 2026-07-28 protocol era. A `--url` connection negotiates the protocol version automatically, so `--modern` is not needed for HTTP. `--pin <version>` works on every transport, including HTTP. It forces that exact protocol revision. The connection fails if the server does not offer it.
|
|
316
|
+
|
|
301
317
|
---
|
|
302
318
|
|
|
303
319
|
## Ecosystem
|
|
304
320
|
|
|
305
321
|
| Package | Role |
|
|
306
322
|
|---|---|
|
|
307
|
-
| [`@modelcontextprotocol/
|
|
323
|
+
| [`@modelcontextprotocol/server`](https://www.npmjs.com/package/@modelcontextprotocol/server) | Official MCP TypeScript SDK v2 β the server-side protocol implementation FastMCP builds on |
|
|
324
|
+
| [`@modelcontextprotocol/client`](https://www.npmjs.com/package/@modelcontextprotocol/client) | Official MCP TypeScript SDK v2 β the client-side protocol implementation FastMCP builds on |
|
|
308
325
|
| [`fastmcp` (PyPI)](https://github.com/PrefectHQ/fastmcp) | The Python original this project models its API after |
|
|
309
326
|
| [`@modelcontextprotocol/ext-apps`](https://github.com/modelcontextprotocol/ext-apps) | Official MCP Apps extension β foundation for the Apps pillar |
|