Try the starter
1
Start the server
From a Flow project, run:Keep it running. The starter prints its MCP URL and a Claude Code connection command.
Terminal
2
Connect a client
- Claude Code
- Claude & ChatGPT
- Other MCP clients
Run the connection command printed by the starter. At its default port, it is:Use the printed URL if the server chose a different port. Restart the client if it
does not discover the newly added connection.
Terminal
3
Make a request
Ask the connected assistant:Check it worked: the host calls
Try this
get_menu and uses the returned menu to answer.
If you added the tool from Write a tool, ask about the opening hours too.Connecting a server lets you test it in a host. Publishing to that host’s public directory is
a separate submission and review process. Native plugin packages are another way
to deliver skills and an MCP connection.
Serve your own tools
The starter already includessrc/mcp.ts. In an existing Node project, install the optional
server SDK, then point mcpServer at your tools and agent folder.
Terminal
src/mcp.ts
node src/mcp.ts. It serves /mcp and the tools-only plugin endpoint
/mcp/plugin.
What the host receives
Defer less-used tools
Available in Framework 0.8.0. By default every tool is listed upfront. Mark an individual toolmcp: { deferred: true } to let assistants discover its schema when needed.
This affects MCP only: WhatsApp and other chat agents still receive their normal tools, and the
CLI keeps its ordinary commands.
For a minimal example, use this tool in the tools array passed to mcpServer above:
src/tools.ts
tools/list contains search_tools and execute_tool, plus
read_skill if the server has skills. It does not contain inspect_record upfront. With no
deferred tools, neither generated wrapper is added.
The assistant discovers and invokes the operation in two calls:
search_tools arguments
{ "tools": [...], "total": 1 } with matching deferred tools’ full descriptors: name,
description, input and output schemas, annotations and metadata. It matches keywords in names,
titles and descriptions; the default limit is five and the maximum is twenty. A search for
something unrelated returns an empty list. total counts all matches, including those past the limit.
execute_tool arguments
{ "id": "record-1" }. Execute invokes one existing tool,
validates its arguments and output, and preserves its formatting, verified identity, backend
credentials, cancellation signal and idempotency key. Its target’s sign-in and scope checks still
run before execution. It does not evaluate generated code.
Deferral manages context, not access. Known original tools remain directly callable. A generic
executor may invoke writes, so its host-visible annotations conservatively allow destructive
operations even when the selected target is read-only. Server authorization remains specific
to the target.
Choose exposure at deployment
An explicit server list replaces the tools’ flags:deferred to use the individual flags; use deferred: [] to put everything upfront.
Unknown names are refused when constructing the server. A hosting service can choose this list
from usage data before constructing each server handle. Selection stays fixed for that handle;
automatic promotion and demotion are not part of this release. Executed operations emit traces
under their own names, so usage can count direct and indirect calls together. This works on Flow
hosting and on your own infrastructure.
Both /mcp and /mcp/plugin apply the policy; the plugin endpoint keeps excluding standalone
skills. The CLI and mcpTools request the complete original catalog automatically. Other clients
can request it using tools/list metadata:
descriptor
to customize the wrappers, including their names, or supply a tool named search_tools or
execute_tool to replace the corresponding generated implementation. Custom SDK handlers remain
available through extend.
Add per-user sign-in
ConfiguremcpServer({ auth: { issuer, scopes, verify } }) against your authorization server.
Flow challenges calls that need sign-in, and the host starts its OAuth flow.
Authentication must be configured on the server to enforce those requirements. The café starter
has no accounts and runs without server authentication.
Use
context.key for the verified account and context.credentials.get("backend") for backend
access supplied by your credentials provider. Sharing a tool with a messaging agent does not
import the assistant’s private chat history.
Connect your existing login
OAuth providers, verified identities and backend credentials.
Use Flow's OAuth bridge
Connect an existing login page when you do not have an OAuth server.
Customize or extend it
Override instructions and tool descriptors, add your own SDK handlers throughextend, and
keep custom routes beside the generated ones. The CLI uses the same endpoint.
Use tools from another MCP server
Use tools from another MCP server
mcpTools({ name, url }) brings another server’s tools into your agent. Pin the descriptors in
mcp.lock.json so a remote change goes through your checks before reaching customers.Terminal
Package the same tools and skills as a plugin
Generate native packages that connect to the server’s tools-only endpoint.