@prefecthq/fastmcp-ts 0.1.0 β†’ 1.0.0-rc.0

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 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 [`@modelcontextprotocol/sdk`](https://github.com/modelcontextprotocol/typescript-sdk).
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({ transport: 'http', url: 'http://maps-service/mcp' })
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: (params) => new AnthropicSamplingAdapter(new Anthropic()).handleSampling(params),
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', actionRef: 'run_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
- name: 'run_search',
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
- server.addProvider(new FormInput()) // auto-generated validated form from any Standard Schema
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/sdk`](https://www.npmjs.com/package/@modelcontextprotocol/sdk) | Official low-level MCP protocol implementation β€” this library's foundation |
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 |