@frontmcp/skills 1.8.6 → 1.9.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.
Files changed (77) hide show
  1. package/README.md +107 -155
  2. package/catalog/create-tool/SKILL.md +24 -24
  3. package/catalog/create-tool/examples/21-tool-with-availability-constraints.md +1 -1
  4. package/catalog/create-tool/examples/22-tool-with-ui-html-template.md +0 -1
  5. package/catalog/create-tool/examples/23-tool-with-ui-filesource-tsx.md +1 -3
  6. package/catalog/create-tool/examples/24-tool-with-ui-csp-and-bridge.md +4 -6
  7. package/catalog/create-tool/references/availability.md +10 -10
  8. package/catalog/create-tool/references/decorator-options.md +1 -1
  9. package/catalog/create-tool/references/ui-widgets.md +91 -42
  10. package/catalog/frontmcp-authorities/SKILL.md +5 -0
  11. package/catalog/frontmcp-channels/SKILL.md +17 -16
  12. package/catalog/frontmcp-channels/references/channel-sources.md +4 -4
  13. package/catalog/frontmcp-channels/references/channel-two-way.md +1 -1
  14. package/catalog/frontmcp-config/examples/configure-deployment-targets/distributed-ha-config.md +2 -0
  15. package/catalog/frontmcp-config/examples/configure-session/vercel-kv-session.md +1 -2
  16. package/catalog/frontmcp-config/examples/configure-throttle/distributed-redis-throttle.md +3 -3
  17. package/catalog/frontmcp-config/examples/configure-transport/custom-protocol-flags.md +0 -1
  18. package/catalog/frontmcp-config/examples/configure-transport/distributed-sessions-redis.md +0 -1
  19. package/catalog/frontmcp-config/examples/configure-transport/stateless-serverless.md +2 -3
  20. package/catalog/frontmcp-config/examples/configure-transport-protocol-presets/stateless-api-serverless.md +2 -3
  21. package/catalog/frontmcp-config/references/configure-auth.md +1 -1
  22. package/catalog/frontmcp-config/references/configure-deployment-targets.md +68 -16
  23. package/catalog/frontmcp-config/references/configure-http.md +11 -6
  24. package/catalog/frontmcp-config/references/configure-security-headers.md +18 -13
  25. package/catalog/frontmcp-config/references/configure-throttle-guard-config.md +4 -4
  26. package/catalog/frontmcp-config/references/configure-throttle.md +4 -2
  27. package/catalog/frontmcp-config/references/configure-transport.md +4 -5
  28. package/catalog/frontmcp-deployment/SKILL.md +19 -19
  29. package/catalog/frontmcp-deployment/examples/build-for-browser/react-provider-setup.md +5 -3
  30. package/catalog/frontmcp-deployment/examples/deploy-to-node/docker-compose-with-redis.md +1 -1
  31. package/catalog/frontmcp-deployment/examples/deploy-to-node/pm2-with-nginx.md +1 -1
  32. package/catalog/frontmcp-deployment/examples/deploy-to-vercel/vercel-with-kv.md +2 -0
  33. package/catalog/frontmcp-deployment/references/build-for-browser.md +46 -9
  34. package/catalog/frontmcp-deployment/references/build-for-mcpb.md +15 -8
  35. package/catalog/frontmcp-deployment/references/build-for-sdk.md +11 -10
  36. package/catalog/frontmcp-deployment/references/deploy-to-cloudflare.md +5 -1
  37. package/catalog/frontmcp-deployment/references/deploy-to-lambda.md +11 -10
  38. package/catalog/frontmcp-deployment/references/deploy-to-node.md +11 -11
  39. package/catalog/frontmcp-deployment/references/deploy-to-vercel.md +15 -7
  40. package/catalog/frontmcp-deployment/references/mcp-client-integration.md +12 -7
  41. package/catalog/frontmcp-deployment/references/protocol-versions.md +7 -3
  42. package/catalog/frontmcp-development/examples/create-agent/nested-agents-with-swarm.md +50 -10
  43. package/catalog/frontmcp-development/examples/openapi-adapter/ref-security-and-filtering.md +13 -7
  44. package/catalog/frontmcp-development/references/create-adapter.md +14 -0
  45. package/catalog/frontmcp-development/references/create-agent.md +82 -48
  46. package/catalog/frontmcp-development/references/create-plugin-hooks.md +15 -5
  47. package/catalog/frontmcp-development/references/create-plugin.md +23 -2
  48. package/catalog/frontmcp-development/references/create-skill-with-tools.md +7 -2
  49. package/catalog/frontmcp-development/references/create-skill.md +4 -0
  50. package/catalog/frontmcp-development/references/decorators-guide.md +10 -11
  51. package/catalog/frontmcp-development/references/official-adapters.md +1 -1
  52. package/catalog/frontmcp-development/references/official-plugins.md +138 -28
  53. package/catalog/frontmcp-development/references/openapi-adapter.md +52 -2
  54. package/catalog/frontmcp-guides/references/example-task-manager.md +2 -2
  55. package/catalog/frontmcp-guides/references/example-weather-api.md +2 -2
  56. package/catalog/frontmcp-observability/references/metrics-endpoint.md +3 -1
  57. package/catalog/frontmcp-production-readiness/examples/distributed-ha/ha-kubernetes-3-replicas.md +13 -1
  58. package/catalog/frontmcp-production-readiness/examples/production-node-sdk/package-json-config.md +2 -2
  59. package/catalog/frontmcp-production-readiness/references/common-checklist.md +3 -2
  60. package/catalog/frontmcp-production-readiness/references/distributed-ha.md +54 -24
  61. package/catalog/frontmcp-production-readiness/references/health-readiness-endpoints.md +3 -1
  62. package/catalog/frontmcp-setup/examples/nx-workflow/build-test-affected.md +2 -2
  63. package/catalog/frontmcp-setup/examples/nx-workflow/multi-server-deployment.md +9 -5
  64. package/catalog/frontmcp-setup/examples/nx-workflow/scaffold-and-generate.md +1 -1
  65. package/catalog/frontmcp-setup/examples/project-structure-nx/nx-generator-scaffolding.md +2 -2
  66. package/catalog/frontmcp-setup/references/frontmcp-skills-usage.md +28 -15
  67. package/catalog/frontmcp-setup/references/multi-app-composition.md +11 -8
  68. package/catalog/frontmcp-setup/references/nx-workflow.md +68 -28
  69. package/catalog/frontmcp-setup/references/project-structure-nx.md +7 -4
  70. package/catalog/frontmcp-setup/references/setup-project.md +15 -0
  71. package/catalog/frontmcp-setup/references/setup-redis.md +12 -3
  72. package/catalog/frontmcp-setup/references/setup-sqlite.md +21 -14
  73. package/catalog/frontmcp-testing/SKILL.md +28 -23
  74. package/catalog/frontmcp-testing/references/setup-testing.md +39 -2
  75. package/catalog/frontmcp-testing/references/test-auth.md +8 -0
  76. package/catalog/skills-manifest.json +14 -12
  77. package/package.json +1 -1
package/README.md CHANGED
@@ -1,195 +1,147 @@
1
1
  <div align="center">
2
2
 
3
+ <a href="https://frontmcp.dev">
3
4
  <picture>
4
- <source width="400" media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/agentfront/frontmcp/refs/heads/main/docs/assets/logo/frontmcp.dark.svg">
5
- <source width="400" media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/agentfront/frontmcp/refs/heads/main/docs/assets/logo/frontmcp.light.svg">
6
- <img width="400" alt="FrontMCP Logo" src="https://raw.githubusercontent.com/agentfront/frontmcp/refs/heads/main/docs/assets/logo/frontmcp.light.svg">
5
+ <source media="(prefers-color-scheme: dark)" srcset="docs/assets/readme/hero.svg">
6
+ <img src="docs/assets/readme/hero.light.svg" alt="FrontMCP - The TypeScript way to build MCP servers" width="100%">
7
7
  </picture>
8
- <hr>
8
+ </a>
9
9
 
10
- **The production-grade, TypeScript-first framework for building MCP servers — decorators, DI, auth, and Streamable HTTP, batteries included.**
10
+ [![NPM](https://img.shields.io/npm/v/@frontmcp/sdk.svg?style=flat-square&color=16A34A&labelColor=0b1117&label=npm)](https://www.npmjs.com/package/@frontmcp/sdk)
11
+ [![Node](https://img.shields.io/badge/node-%E2%89%A5%2024-16A34A?style=flat-square&labelColor=0b1117&logo=node.js&logoColor=white)](https://nodejs.org)
12
+ [![License](https://img.shields.io/github/license/agentfront/frontmcp.svg?style=flat-square&color=16A34A&labelColor=0b1117)](./LICENSE)
13
+ [![Snyk](https://img.shields.io/badge/snyk-monitored-16A34A?style=flat-square&labelColor=0b1117&logo=snyk&logoColor=white)](https://snyk.io/test/github/agentfront/frontmcp)
14
+ [![Discord](https://img.shields.io/badge/discord-join-16A34A?style=flat-square&labelColor=0b1117&logo=discord&logoColor=white)](https://discord.gg/53AHnJnmwR)
11
15
 
12
- [![NPM - @frontmcp/sdk](https://img.shields.io/npm/v/@frontmcp/sdk.svg?v=2)](https://www.npmjs.com/package/@frontmcp/sdk)
13
- [![Node](https://img.shields.io/badge/node-%3E%3D24-339933?logo=node.js&logoColor=white)](https://nodejs.org)
14
- [![License](https://img.shields.io/github/license/agentfront/frontmcp.svg?v=1)](https://github.com/agentfront/frontmcp/blob/main/LICENSE)
15
- [![Snyk](https://snyk.io/test/github/agentfront/frontmcp/badge.svg)](https://snyk.io/test/github/agentfront/frontmcp)
16
+ **[frontmcp.dev](https://frontmcp.dev)** &nbsp;&middot;&nbsp; **[Learn][docs-learn]** &nbsp;&middot;&nbsp; **[Reference][docs-reference]** &nbsp;&middot;&nbsp; **[Examples][docs-examples]** &nbsp;&middot;&nbsp; **[Playground][docs-playground]** &nbsp;&middot;&nbsp; **[Blog][docs-blog]**
16
17
 
17
- [Docs][docs-home] &bull; [Quickstart][docs-quickstart] &bull; [API Reference][docs-sdk-ref] &bull; [Discord](https://discord.gg/53AHnJnmwR)
18
+ <picture>
19
+ <source media="(prefers-color-scheme: dark)" srcset="docs/assets/readme/terminal.svg">
20
+ <img src="docs/assets/readme/terminal.light.svg" alt="npx frontmcp create my-app, then npm run dev: an MCP server running on localhost:3000" width="760">
21
+ </picture>
18
22
 
19
23
  </div>
20
24
 
21
- ---
25
+ <br>
26
+
27
+ ## Write a tool. Ship a server.
22
28
 
23
- FrontMCP turns the [Model Context Protocol](https://modelcontextprotocol.io) into a
24
- typed, declarative framework. You write clean `@Tool`, `@Resource`, and `@App`
25
- classes; FrontMCP handles the protocol, transport, dependency injection, sessions,
26
- auth, and execution flow — and the **same server runs locally and ships to
27
- production unchanged**.
29
+ Classes in, protocol out. FrontMCP handles transport, DI, sessions, auth and execution flow, and the same server runs locally and in production unchanged.
28
30
 
29
31
  ```ts
30
32
  import 'reflect-metadata';
31
33
 
32
- import { FrontMcp, LogLevel } from '@frontmcp/sdk';
34
+ import { App, FrontMcp, Tool, ToolContext, z } from '@frontmcp/sdk';
35
+
36
+ @Tool({
37
+ name: 'add',
38
+ description: 'Adds two numbers together',
39
+ inputSchema: { a: z.number(), b: z.number() },
40
+ })
41
+ class AddTool extends ToolContext {
42
+ async execute(input: { a: number; b: number }) {
43
+ return input.a + input.b;
44
+ }
45
+ }
33
46
 
34
- import HelloApp from './hello.app';
47
+ @App({ id: 'calc', name: 'Calculator', tools: [AddTool] })
48
+ class CalcApp {}
35
49
 
36
50
  @FrontMcp({
37
51
  info: { name: 'Demo', version: '0.1.0' },
38
- apps: [HelloApp],
52
+ apps: [CalcApp],
39
53
  http: { port: 3000 },
40
- logging: { level: LogLevel.Info },
41
54
  })
42
55
  export default class Server {}
43
56
  ```
44
57
 
45
- ## Why FrontMCP
46
-
47
- - **Typed by default** — decorators + Zod schemas give end-to-end types from input to output, with editor autocomplete and compile-time checks.
48
- - **Batteries included** — auth (OAuth/JWKS/DCR), sessions, transport, discovery, and DI are built in, not bolted on.
49
- - **Ship anywhere** — one codebase deploys to Node, Vercel, AWS Lambda, Cloudflare Workers, or a serverless bundle.
50
- - **Production-minded** — stateful/stateless sessions, high-availability transport, structured observability, and a 95%+ tested core.
51
- - **Extensible** — plugins, lifecycle hooks, OpenAPI adapters, and external MCP sub-apps when you outgrow the defaults.
58
+ <div align="center">
59
+ <picture>
60
+ <source media="(prefers-color-scheme: dark)" srcset="docs/assets/readme/features.svg">
61
+ <img src="docs/assets/readme/features.light.svg" alt="Typed end to end, auth built in, ship anywhere, every stage is a hook, tools with a face, one endpoint for any client" width="100%">
62
+ </picture>
63
+ </div>
52
64
 
53
- ## Installation
65
+ <br>
54
66
 
55
- **Node.js 24+** required.
67
+ ## Start
56
68
 
57
69
  ```bash
58
- # New project (recommended)
59
- npx frontmcp create my-app
60
-
61
- # Existing project
62
- npm i -D frontmcp @types/node@^24
63
- npx frontmcp init
70
+ npx frontmcp create my-app # new project (Node 24+)
71
+ npx frontmcp init # or add FrontMCP to an existing one
64
72
  ```
65
73
 
66
- > Full setup guide: [Installation][docs-install] &middot; [Quickstart][docs-quickstart]
67
-
68
- ## Capabilities
69
-
70
- **Build** — decorator-configured [`@FrontMcp` server][docs-server] and [`@App`][docs-apps]
71
- domains; typed [`@Tool`][docs-tools], [`@Resource`][docs-resources], and
72
- [`@Prompt`][docs-prompts] primitives; [`@Agent`][docs-agents] multi-step chains; and
73
- scoped [Providers / DI][docs-providers].
74
-
75
- **Secure** — [Remote & Local OAuth, JWKS, DCR, per-app auth][docs-auth] with
76
- stateful / stateless [sessions][docs-server] (JWT or UUID transport IDs).
77
-
78
- **Connect & operate** — [Streamable HTTP + SSE transport][docs-transport],
79
- every [MCP protocol revision][docs-protocol] from `2024-11-05` through
80
- `2026-07-28` on one endpoint, capability [discovery][docs-discovery],
81
- [elicitation][docs-elicitation], [hooks][docs-hooks], HTTP-discoverable
82
- [skills][docs-skills], [tool UI / MCP Apps][docs-ext-apps], an in-process
83
- [Direct Client][docs-direct] (`connectOpenAI` / `connectClaude`), and
84
- first-class [deployment][docs-deploy].
85
-
86
- **Extend & tooling** — official [plugins][docs-plugins] (Cache, Remember, CodeCall,
87
- Dashboard), the [OpenAPI adapter][docs-adapters], a [UI library][docs-ui] (HTML/React
88
- widgets, SSR, MCP Bridge), an [E2E testing framework][docs-testing], and a
89
- [CLI][docs-install] (`create`, `init`, `dev`, `build`, `inspect`, `doctor`).
90
-
91
- → Full reference: **[docs.agentfront.dev/frontmcp][docs-home]**
74
+ Then follow **[Learn][docs-learn]** on [frontmcp.dev](https://frontmcp.dev), or browse [Tools][docs-tools], [Resources][docs-resources], [Prompts][docs-prompts], [Agents][docs-agents], [Auth][docs-auth], [Plugins][docs-plugins], [Tool UI][docs-ext-apps], [Testing][docs-testing] and [Deployment][docs-deploy]. Try it live in the [Playground][docs-playground].
92
75
 
93
76
  ## Packages
94
77
 
95
- You install `frontmcp` (the CLI) and `@frontmcp/sdk`. Everything else is either
96
- pulled in for you or opt-in.
78
+ Install `frontmcp` (CLI) and `@frontmcp/sdk`. The rest is pulled in for you, or opt-in. Keep every `@frontmcp/*` package on the same version; a mismatch fails fast at boot ([why][docs-production]).
79
+
80
+ <details>
81
+ <summary><b>Core and extensions</b></summary>
82
+ <br>
83
+
84
+ | Package | What it does |
85
+ | --------------------------------------------------- | --------------------------------------------------------------- |
86
+ | [`frontmcp`](libs/cli) | CLI: `create`, `init`, `dev`, `build`, `inspect`, `doctor` |
87
+ | [`@frontmcp/sdk`](libs/sdk) | Core framework: decorators, DI, flows, transport, MCP protocol |
88
+ | [`@frontmcp/auth`](libs/auth) | OAuth, JWKS, DCR/CIMD, sessions, credential vault |
89
+ | [`@frontmcp/testing`](libs/testing) | E2E test framework with fixtures and matchers |
90
+ | [`@frontmcp/adapters`](libs/adapters) | Generate tools from an OpenAPI spec |
91
+ | [`@frontmcp/skills`](libs/skills) | Curated `SKILL.md` catalog for scaffolding and `skills install` |
92
+ | [`@frontmcp/guard`](libs/guard) | Rate limits, concurrency and policy guards |
93
+ | [`@frontmcp/observability`](libs/observability) | Structured logging, metrics and tracing |
94
+ | [`@frontmcp/react`](libs/react) | React hooks and client for a FrontMCP server |
95
+ | [`@frontmcp/ui`](libs/ui) / [`uipack`](libs/uipack) | Widgets, SSR renderers, MCP Bridge, themes |
96
+ | [`@frontmcp/edge`](libs/edge) | Run a server on Cloudflare Workers / V8 isolates |
97
+ | [`@frontmcp/storage-sqlite`](libs/storage-sqlite) | SQLite session, task and elicitation stores |
98
+ | [`@frontmcp/nx`](libs/nx-plugin) | Nx generators and executors |
99
+
100
+ Internal, published so the above resolve: [`protocol`](libs/protocol), [`di`](libs/di), [`utils`](libs/utils), [`lazy-zod`](libs/lazy-zod).
101
+
102
+ </details>
103
+
104
+ <details>
105
+ <summary><b>Official plugins</b></summary>
106
+ <br>
107
+
108
+ | Package | What it does |
109
+ | -------------------------------------------------------------------- | ----------------------------------------------- |
110
+ | [`@frontmcp/plugin-cache`](plugins/plugin-cache) | Cache tool results with a TTL |
111
+ | [`@frontmcp/plugin-remember`](plugins/plugin-remember) | Per-session memory (`this.remember`) |
112
+ | [`@frontmcp/plugin-approval`](plugins/plugin-approval) | Human approval gates before a tool runs |
113
+ | [`@frontmcp/plugin-codecall`](plugins/plugin-codecall) | Let the model compose tool calls as code |
114
+ | [`@frontmcp/plugin-dashboard`](plugins/plugin-dashboard) | Built-in web dashboard |
115
+ | [`@frontmcp/plugin-feature-flags`](plugins/plugin-feature-flags) | Toggle tools and apps at runtime |
116
+ | [`@frontmcp/plugin-skilled-openapi`](plugins/plugin-skilled-openapi) | OpenAPI to skills and meta-tools for big APIs |
117
+ | [`@frontmcp/plugin-webmcp`](plugins/plugin-webmcp) | Expose in-page tools to browser agents (WebMCP) |
118
+
119
+ </details>
120
+
121
+ <br>
97
122
 
98
- ### Core
99
-
100
- | Package | Description |
101
- | ----------------------------------- | --------------------------------------------------------------- |
102
- | [`frontmcp`](libs/cli) | The CLI — `create`, `init`, `dev`, `build`, `inspect`, `doctor` |
103
- | [`@frontmcp/sdk`](libs/sdk) | Core framework — decorators, DI, flows, transport, MCP protocol |
104
- | [`@frontmcp/auth`](libs/auth) | Authentication, OAuth, JWKS, DCR/CIMD, credential vault |
105
- | [`@frontmcp/testing`](libs/testing) | E2E test framework with fixtures and matchers |
106
-
107
- ### Extend
108
-
109
- | Package | Description |
110
- | ----------------------------------------------- | ------------------------------------------------------------- |
111
- | [`@frontmcp/plugins`](libs/plugins) | Plugin authoring toolkit + official plugin re-exports |
112
- | [`@frontmcp/adapters`](libs/adapters) | OpenAPI adapter — generate tools from an OpenAPI spec |
113
- | [`@frontmcp/skills`](libs/skills) | Curated SKILL.md catalog for scaffolding and `skills install` |
114
- | [`@frontmcp/guard`](libs/guard) | Policy/guard rules for tool inputs and outputs |
115
- | [`@frontmcp/observability`](libs/observability) | Structured logging, metrics, and tracing helpers |
116
-
117
- ### UI
118
-
119
- | Package | Description |
120
- | --------------------------------- | ----------------------------------------------------- |
121
- | [`@frontmcp/react`](libs/react) | React hooks + client for talking to a FrontMCP server |
122
- | [`@frontmcp/ui`](libs/ui) | React components, SSR renderers, MCP Bridge |
123
- | [`@frontmcp/uipack`](libs/uipack) | React-free themes, build tools, platform adapters |
124
-
125
- ### Runtime & storage
126
-
127
- | Package | Description |
128
- | ------------------------------------------------- | -------------------------------------------------------------- |
129
- | [`@frontmcp/edge`](libs/edge) | Run a server on Cloudflare Workers / V8 isolates from a config |
130
- | [`@frontmcp/storage-sqlite`](libs/storage-sqlite) | SQLite-backed session, task, and elicitation stores |
131
- | [`@frontmcp/nx`](libs/nx-plugin) | Nx generators and executors for FrontMCP workspaces |
132
-
133
- ### Internal
134
-
135
- Published so the packages above resolve, but not intended for direct use:
136
-
137
- | Package | Description |
138
- | ------------------------------------- | ------------------------------------------------------------ |
139
- | [`@frontmcp/protocol`](libs/protocol) | The single boundary to the upstream MCP SDK — protocol types |
140
- | [`@frontmcp/di`](libs/di) | Dependency injection container |
141
- | [`@frontmcp/utils`](libs/utils) | Shared utilities — naming, URI, crypto, FS |
142
- | [`@frontmcp/lazy-zod`](libs/lazy-zod) | Lazily-loaded Zod wrapper that keeps cold starts small |
143
-
144
- ### Official plugins
145
-
146
- | Package | Description |
147
- | -------------------------------------------------------------------- | -------------------------------------------- |
148
- | [`@frontmcp/plugin-cache`](plugins/plugin-cache) | Cache tool results with a TTL |
149
- | [`@frontmcp/plugin-remember`](plugins/plugin-remember) | Per-session memory (`this.remember`) |
150
- | [`@frontmcp/plugin-approval`](plugins/plugin-approval) | Human approval gates before a tool runs |
151
- | [`@frontmcp/plugin-codecall`](plugins/plugin-codecall) | Let the model compose tool calls as code |
152
- | [`@frontmcp/plugin-dashboard`](plugins/plugin-dashboard) | Built-in web dashboard |
153
- | [`@frontmcp/plugin-feature-flags`](plugins/plugin-feature-flags) | Toggle tools and apps at runtime |
154
- | [`@frontmcp/plugin-skilled-openapi`](plugins/plugin-skilled-openapi) | OpenAPI → skills + meta-tools for large APIs |
155
-
156
- ## Version Alignment
157
-
158
- Keep all `@frontmcp/*` packages on the same version. A clear **"version mismatch"** error is thrown at boot if versions drift. ([Production Build][docs-production])
159
-
160
- ## Contributing
123
+ <div align="center">
161
124
 
162
- PRs welcome! See [CONTRIBUTING.md](./CONTRIBUTING.md) for workflow, coding standards, and the PR checklist.
125
+ PRs welcome: see [CONTRIBUTING](./CONTRIBUTING.md). Released under the [Apache-2.0](./LICENSE) license.
163
126
 
164
- ## License
127
+ Docs also mirrored at [docs.agentfront.dev/frontmcp](https://docs.agentfront.dev/frontmcp).
165
128
 
166
- [Apache-2.0](./LICENSE)
129
+ </div>
167
130
 
168
131
  <!-- docs links -->
169
132
 
170
- [docs-home]: https://docs.agentfront.dev/frontmcp 'FrontMCP Docs'
171
- [docs-install]: https://docs.agentfront.dev/frontmcp/getting-started/installation 'Installation'
172
- [docs-quickstart]: https://docs.agentfront.dev/frontmcp/getting-started/quickstart 'Quickstart'
173
- [docs-sdk-ref]: https://docs.agentfront.dev/frontmcp/sdk-reference/decorators/overview 'SDK Reference'
174
- [docs-server]: https://docs.agentfront.dev/frontmcp/servers/server 'The FrontMCP Server'
175
- [docs-apps]: https://docs.agentfront.dev/frontmcp/servers/apps 'Apps'
176
- [docs-tools]: https://docs.agentfront.dev/frontmcp/servers/tools 'Tools'
177
- [docs-resources]: https://docs.agentfront.dev/frontmcp/servers/resources 'Resources'
178
- [docs-prompts]: https://docs.agentfront.dev/frontmcp/servers/prompts 'Prompts'
179
- [docs-agents]: https://docs.agentfront.dev/frontmcp/servers/agents 'Agents'
180
- [docs-elicitation]: https://docs.agentfront.dev/frontmcp/servers/elicitation 'Elicitation'
181
- [docs-skills]: https://docs.agentfront.dev/frontmcp/servers/skills 'Skills'
182
- [docs-discovery]: https://docs.agentfront.dev/frontmcp/servers/discovery 'Discovery'
183
- [docs-protocol]: https://docs.agentfront.dev/frontmcp/fundamentals/protocol-versions 'Protocol Versions'
184
- [docs-auth]: https://docs.agentfront.dev/frontmcp/authentication/overview 'Authentication'
185
- [docs-direct]: https://docs.agentfront.dev/frontmcp/deployment/direct-client 'Direct Client'
186
- [docs-transport]: https://docs.agentfront.dev/frontmcp/deployment/transport-security 'Transport'
187
- [docs-ext-apps]: https://docs.agentfront.dev/frontmcp/guides/building-tool-ui 'Tool UI / MCP Apps'
188
- [docs-hooks]: https://docs.agentfront.dev/frontmcp/sdk-reference/decorators/hooks 'Hooks'
189
- [docs-providers]: https://docs.agentfront.dev/frontmcp/extensibility/providers 'Providers'
190
- [docs-plugins]: https://docs.agentfront.dev/frontmcp/plugins/overview 'Plugins'
191
- [docs-adapters]: https://docs.agentfront.dev/frontmcp/adapters/overview 'Adapters'
192
- [docs-testing]: https://docs.agentfront.dev/frontmcp/testing/overview 'Testing'
193
- [docs-ui]: https://docs.agentfront.dev/frontmcp/react/overview 'React SDK'
194
- [docs-deploy]: https://docs.agentfront.dev/frontmcp/deployment/local-dev-server 'Deployment'
195
- [docs-production]: https://docs.agentfront.dev/frontmcp/deployment/production-build 'Production Build'
133
+ [docs-learn]: https://frontmcp.dev/learn 'Learn FrontMCP'
134
+ [docs-reference]: https://frontmcp.dev/reference 'Reference'
135
+ [docs-examples]: https://frontmcp.dev/examples 'Examples'
136
+ [docs-playground]: https://frontmcp.dev/playground 'Playground'
137
+ [docs-blog]: https://frontmcp.dev/blog 'Blog'
138
+ [docs-tools]: https://frontmcp.dev/reference/sdk/tool 'Tools'
139
+ [docs-resources]: https://frontmcp.dev/reference/sdk/resource 'Resources'
140
+ [docs-prompts]: https://frontmcp.dev/reference/sdk/prompt 'Prompts'
141
+ [docs-agents]: https://frontmcp.dev/reference/sdk/agent 'Agents'
142
+ [docs-auth]: https://frontmcp.dev/reference/auth/modes 'Authentication'
143
+ [docs-ext-apps]: https://frontmcp.dev/learn/tools-with-a-ui 'Tool UI / MCP Apps'
144
+ [docs-plugins]: https://frontmcp.dev/reference/plugins 'Plugins'
145
+ [docs-testing]: https://frontmcp.dev/reference/testing 'Testing'
146
+ [docs-deploy]: https://frontmcp.dev/reference/deployment/node 'Deployment'
147
+ [docs-production]: https://frontmcp.dev/reference/deployment/production-build 'Production Build'
@@ -32,8 +32,8 @@ when_to_use: |
32
32
  Trigger when creating or editing a `*.tool.ts` / `*.tool.tsx` file, adding a `@Tool`
33
33
  decorator, defining `inputSchema` / `outputSchema` for a tool, deriving `execute()`
34
34
  parameter or return types, wiring dependency injection into a tool, returning
35
- structured / media / resource content, adding a `ui:` block (HTML / MDX / React /
36
- FileSource), configuring throttling, declaring auth providers, restricting platforms
35
+ structured / media / resource content, adding a `ui:` block (FileSource / React /
36
+ HTML / Markdown), configuring throttling, declaring auth providers, restricting platforms
37
37
  via `availableWhen`, requesting interactive input via `this.elicit`, adding tool
38
38
  `annotations`, or registering a tool in `@App({ tools })`.
39
39
 
@@ -203,7 +203,7 @@ If a request seems to conflict with an inherited default (e.g., "wrap `inputSche
203
203
  │ See: examples/22-tool-with-ui-html-template.md
204
204
  ├── React widget (file) → ui: { template: { file: widgetPath } }
205
205
  │ See: examples/23-tool-with-ui-filesource-tsx.md
206
- ├── Calls other tools → widgetAccessible: true + window.FrontMcpBridge
206
+ ├── Calls other tools → window.FrontMcpBridge.callTool
207
207
  │ See: examples/24-tool-with-ui-csp-and-bridge.md
208
208
  └── Claude target → resourceMode is auto-detected; do not set
209
209
  See: references/ui-widgets.md
@@ -240,7 +240,7 @@ If a request seems to conflict with an inherited default (e.g., "wrap `inputSche
240
240
  | Tool restricted to one OS / runtime / target | [`21-tool-with-availability-constraints`](./examples/21-tool-with-availability-constraints.md) | `availableWhen` axes |
241
241
  | Tool with a quick inline HTML widget | [`22-tool-with-ui-html-template`](./examples/22-tool-with-ui-html-template.md) | `ui: { template: (ctx) => '<div>…</div>' }` |
242
242
  | Tool with a separate `.tsx` widget file | [`23-tool-with-ui-filesource-tsx`](./examples/23-tool-with-ui-filesource-tsx.md) | `FileSource` + `import.meta.url` anchoring |
243
- | Tool widget that calls other tools | [`24-tool-with-ui-csp-and-bridge`](./examples/24-tool-with-ui-csp-and-bridge.md) | `widgetAccessible: true` + `window.FrontMcpBridge.callTool` |
243
+ | Tool widget that calls other tools | [`24-tool-with-ui-csp-and-bridge`](./examples/24-tool-with-ui-csp-and-bridge.md) | `window.FrontMcpBridge.callTool` |
244
244
  | Tool that triggers a job + tracks it | [`25-tool-handing-off-to-job`](./examples/25-tool-handing-off-to-job.md) | Thin tool + heavy job — the right split |
245
245
  | Tool that returns a resource handle | [`26-tool-with-resource-link-output`](./examples/26-tool-with-resource-link-output.md) | `outputSchema: 'resource_link'` — the host fetches the resource |
246
246
  | Tool with `examples` metadata for discovery | [`27-tool-with-examples-metadata`](./examples/27-tool-with-examples-metadata.md) | `examples: [{ description, input, output? }]` |
@@ -269,26 +269,26 @@ Before considering a tool "done":
269
269
 
270
270
  ## References (deep dives)
271
271
 
272
- | Reference | Covers |
273
- | --------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
274
- | [`quick-start.md`](./references/quick-start.md) | 60-second tour: minimal tool, registration, calling it from a test |
275
- | [`decorator-options.md`](./references/decorator-options.md) | Every field on `@Tool({...})` — what it does, default, when to set it |
276
- | [`input-schema.md`](./references/input-schema.md) | Raw shape vs `z.object`, refinements, defaults, optional, describe |
277
- | [`output-schema.md`](./references/output-schema.md) | All supported output types: Zod shape, Zod schema, primitives, media, arrays |
278
- | [`derived-types.md`](./references/derived-types.md) | `ToolInputOf` / `ToolOutputOf` patterns, file layout, schema hoisting |
279
- | [`execution-context.md`](./references/execution-context.md) | `ToolContext` methods + properties — `this.get`, `this.fetch`, `this.notify`, `this.context`, etc. |
280
- | [`error-handling.md`](./references/error-handling.md) | `this.fail`, MCP error classes (`PublicMcpError`, `ResourceNotFoundError`), error flow, when to throw vs `fail` |
281
- | [`throttling.md`](./references/throttling.md) | `rateLimit`, `concurrency`, `timeout` — semantics, interaction, defaults |
282
- | [`auth-providers.md`](./references/auth-providers.md) | `authProviders` string shorthand vs full mapping, scopes, alias, credential vault basics |
283
- | [`availability.md`](./references/availability.md) | `availableWhen` axes (os / runtime / deployment / provider / target / surface / env), `missingAxes`, `isPlatform` |
284
- | [`elicitation.md`](./references/elicitation.md) | `this.elicit`, server-level enable, `ElicitationDisabledError`, accept / decline / cancel |
285
- | [`ui-widgets.md`](./references/ui-widgets.md) | `@Tool({ ui })` — template formats, `servingMode`, `resourceMode` host-detect, CSP, `widgetAccessible`, MCP Apps spec |
286
- | [`annotations.md`](./references/annotations.md) | `readOnlyHint`, `destructiveHint`, `idempotentHint`, `openWorldHint`, `title` |
287
- | [`function-style-builder.md`](./references/function-style-builder.md) | `tool({...})(handler)` — when to pick over a class, register, ctx parameter |
288
- | [`remote-and-esm.md`](./references/remote-and-esm.md) | `Tool.esm(...)` / `Tool.remote(...)` — load tools from ESM URLs or remote MCP servers |
289
- | [`registration.md`](./references/registration.md) | `@App({ tools })` vs `@FrontMcp({ tools })`, multi-app composition |
290
- | [`file-layout.md`](./references/file-layout.md) | Flat-sibling vs folder-per-tool, `<name>.schema.ts` / `<name>.tool.ts` / `<name>.tool.spec.ts` |
291
- | [`testing.md`](./references/testing.md) | Per-tool unit tests — `@frontmcp/testing`, mocking DI, asserting output validation |
272
+ | Reference | Covers |
273
+ | --------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
274
+ | [`quick-start.md`](./references/quick-start.md) | 60-second tour: minimal tool, registration, calling it from a test |
275
+ | [`decorator-options.md`](./references/decorator-options.md) | Every field on `@Tool({...})` — what it does, default, when to set it |
276
+ | [`input-schema.md`](./references/input-schema.md) | Raw shape vs `z.object`, refinements, defaults, optional, describe |
277
+ | [`output-schema.md`](./references/output-schema.md) | All supported output types: Zod shape, Zod schema, primitives, media, arrays |
278
+ | [`derived-types.md`](./references/derived-types.md) | `ToolInputOf` / `ToolOutputOf` patterns, file layout, schema hoisting |
279
+ | [`execution-context.md`](./references/execution-context.md) | `ToolContext` methods + properties — `this.get`, `this.fetch`, `this.notify`, `this.context`, etc. |
280
+ | [`error-handling.md`](./references/error-handling.md) | `this.fail`, MCP error classes (`PublicMcpError`, `ResourceNotFoundError`), error flow, when to throw vs `fail` |
281
+ | [`throttling.md`](./references/throttling.md) | `rateLimit`, `concurrency`, `timeout` — semantics, interaction, defaults |
282
+ | [`auth-providers.md`](./references/auth-providers.md) | `authProviders` string shorthand vs full mapping, scopes, alias, credential vault basics |
283
+ | [`availability.md`](./references/availability.md) | `availableWhen` axes (os / runtime / deployment / provider / target / surface / env), `missingAxes`, `isPlatform` |
284
+ | [`elicitation.md`](./references/elicitation.md) | `this.elicit`, server-level enable, `ElicitationDisabledError`, accept / decline / cancel |
285
+ | [`ui-widgets.md`](./references/ui-widgets.md) | `@Tool({ ui })` — template formats, `servingMode`, `resourceMode` host-detect, CSP, ignored options, MCP Apps spec |
286
+ | [`annotations.md`](./references/annotations.md) | `readOnlyHint`, `destructiveHint`, `idempotentHint`, `openWorldHint`, `title` |
287
+ | [`function-style-builder.md`](./references/function-style-builder.md) | `tool({...})(handler)` — when to pick over a class, register, ctx parameter |
288
+ | [`remote-and-esm.md`](./references/remote-and-esm.md) | `Tool.esm(...)` / `Tool.remote(...)` — load tools from ESM URLs or remote MCP servers |
289
+ | [`registration.md`](./references/registration.md) | `@App({ tools })` vs `@FrontMcp({ tools })`, multi-app composition |
290
+ | [`file-layout.md`](./references/file-layout.md) | Flat-sibling vs folder-per-tool, `<name>.schema.ts` / `<name>.tool.ts` / `<name>.tool.spec.ts` |
291
+ | [`testing.md`](./references/testing.md) | Per-tool unit tests — `@frontmcp/testing`, mocking DI, asserting output validation |
292
292
 
293
293
  ## Rules (constraints — read these once, then they're enforced)
294
294
 
@@ -83,7 +83,7 @@ export class RotateSecretsTool extends ToolContext {
83
83
  | `deployment` | `'serverless'`, `'standalone'`, `'distributed'`, `'browser'` |
84
84
  | `provider` | `'bare'`, `'docker'`, `'vercel'`, `'lambda'`, `'cloudflare'`, … |
85
85
  | `target` | `'cli'`, `'node'`, `'vercel'`, `'lambda'`, `'cloudflare'`, … (set by `frontmcp build --target`) |
86
- | `surface` | `'mcp'`, `'cli'`, `'agent'`, `'job'`, `'http-trigger'` — per-call axis |
86
+ | `surface` | `'mcp'`, `'cli'`, `'agent'`, `'job'`, `'http-trigger'`, `'webmcp'` — per-call axis |
87
87
  | `env` | `'production'`, `'development'`, `'test'` |
88
88
 
89
89
  Multiple axes are AND-ed. Multiple values within an axis are OR-ed.
@@ -38,7 +38,6 @@ type Out = { city: string; temperatureF: number; conditions: string };
38
38
  inputSchema,
39
39
  outputSchema,
40
40
  ui: {
41
- widgetDescription: 'Current weather card',
42
41
  // `html` escapes interpolated values — no manual escapeHtml needed
43
42
  template: (ctx: TemplateContext<In, Out>) => ctx.helpers.html`
44
43
  <div style="padding:16px;font-family:system-ui;border-radius:12px;background:#f5f7fa">
@@ -53,12 +53,10 @@ const widgetPath = fileURLToPath(new URL('./sales-chart.widget.tsx', import.meta
53
53
  inputSchema,
54
54
  outputSchema,
55
55
  ui: {
56
- widgetDescription: 'Monthly revenue chart',
57
56
  template: { file: widgetPath },
58
57
  // resourceMode is intentionally UNSET — framework host-detects: 'inline' for Claude
59
58
  // (React bundled in, widget renders under Claude's CSP), 'cdn' for OpenAI / ChatGPT /
60
59
  // Cursor / MCP Inspector (smaller payload from esm.sh). Issue #456.
61
- hydrate: false, // SSR-only — dodges React error #418 in iframe sandboxes
62
60
  },
63
61
  })
64
62
  export class SalesChartTool extends ToolContext {
@@ -111,5 +109,5 @@ export default function SalesChartWidget({ output }: Props) {
111
109
  - **`import.meta.url` anchoring** — relative paths in `FileSource` resolve against `process.cwd()`, not the tool file (#444). Running the server from a different directory breaks the widget at tool-call time. Anchoring fixes it once.
112
110
  - **Ship the widget** — the anchored path points next to the **compiled** file after a build, and tsc doesn't emit `*.widget.tsx`. `frontmcp build` copies widget files into the output (directly next to the bundle for the bundled `node` / `cli` / `lambda` / `vercel` targets, so keep widget file names unique); a plain `tsc` build needs its own copy step (#649).
113
111
  - **`resourceMode` unset** — leave it. The framework picks `'inline'` for Claude (React bundled into the widget — actually renders) and `'cdn'` for everyone else (smaller payload via esm.sh). Setting it explicitly only locks in one behavior across all clients.
114
- - **`hydrate: false`** — default. React SSR output is static HTML; the bridge IIFE handles any interactivity. Enabling hydration creates React error #418 in Claude's iframe sandbox where the client-side render diverges from the SSR render.
112
+ - **No `hydrate` option** — `ui.hydrate` is accepted but has no effect yet (startup logs a warning). The `.tsx` widget is bundled and mounted on the client by the generated entry.
115
113
  - **`*.widget.tsx` naming** — the scaffolded `tsconfig.json` excludes `**/*.widget.tsx` from the server typecheck (#445). The widget compiles via uipack/esbuild at render time with its own React-aware config.
@@ -2,10 +2,10 @@
2
2
  name: 24-tool-with-ui-csp-and-bridge
3
3
  level: advanced
4
4
  description: 'Interactive tool widget that fetches from an allow-listed CSP origin and invokes another tool via `window.FrontMcpBridge.callTool` — the full pattern for live-data widgets that need cross-tool composition.'
5
- tags: [ui, csp, widgetAccessible, FrontMcpBridge, interactive-widget]
5
+ tags: [ui, csp, callTool, FrontMcpBridge, interactive-widget]
6
6
  features:
7
7
  - "Restricting the widget's outbound `fetch` via `ui.csp.connectDomains` (emitted on the resource per #455)"
8
- - 'Opting the widget into cross-tool calls with `widgetAccessible: true` and using `window.FrontMcpBridge.callTool(name, args)` instead of host-specific APIs'
8
+ - 'Calling other tools from the widget with `window.FrontMcpBridge.callTool(name, args)` instead of host-specific APIs'
9
9
  - 'Building the markup with `ctx.helpers.html` and embedding initial data into the inline `<script>` via `trustedHtml(jsonEmbed(...))` (`jsonEmbed` escapes `<`, `>` and `&`)'
10
10
  - 'Surfacing in-flight status via `invocationStatus.invoking` / `invoked` so the host UI shows feedback'
11
11
  ---
@@ -58,8 +58,6 @@ type Out = { symbol: string; priceUsd: number; asOf: string };
58
58
  inputSchema,
59
59
  outputSchema,
60
60
  ui: {
61
- widgetDescription: 'Live stock quote with refresh',
62
- widgetAccessible: true, // required for window.FrontMcpBridge.callTool
63
61
  invocationStatus: { invoking: 'Fetching quote…', invoked: 'Quote loaded' },
64
62
  csp: {
65
63
  // CSP applies to the widget iframe — only allow fetches to our own market-data API.
@@ -117,13 +115,13 @@ export class ShowQuoteTool extends ToolContext {
117
115
  ## What This Demonstrates
118
116
 
119
117
  - Restricting the widget's outbound `fetch` via `ui.csp.connectDomains` (emitted on the resource per #455)
120
- - Opting the widget into cross-tool calls with `widgetAccessible: true` and using `window.FrontMcpBridge.callTool(name, args)` instead of host-specific APIs
118
+ - Calling other tools from the widget with `window.FrontMcpBridge.callTool(name, args)` instead of host-specific APIs
121
119
  - Building the markup with `ctx.helpers.html` and embedding initial data into the inline `<script>` via `trustedHtml(jsonEmbed(...))` (`jsonEmbed` escapes `<`, `>` and `&`)
122
120
  - Surfacing in-flight status via `invocationStatus.invoking` / `invoked` so the host UI shows feedback
123
121
 
124
122
  ## Why these choices
125
123
 
126
- - **`widgetAccessible: true`** — required for `window.FrontMcpBridge.callTool`. Without it, the bridge is read-only (the widget can read `getToolInput` / `getToolOutput` but can't invoke tools).
124
+ - **No `widgetAccessible` / `widgetDescription`** — both are accepted by the schema but nothing reads them yet (startup logs a warning), so they are left out. Whether the widget may call tools is decided by the host.
127
125
  - **`csp.connectDomains`** — limits what the widget can `fetch` to. Without a CSP, the host's default applies (which may block everything in Claude). With `connectDomains: ['https://api.market.example']`, only that origin is reachable.
128
126
  - **`window.FrontMcpBridge.callTool` not `window.openai.callTool`** — the bridge handles host detection. `window.openai.*` works on OpenAI Apps SDK but breaks everywhere else.
129
127
  - **`jsonEmbed` not `JSON.stringify`** — `JSON.stringify` doesn't escape `</script>` or `<!--` and can break out of the inline script tag. `jsonEmbed` writes `<`, `>` and `&` as `\u003c`, `\u003e`, `\u0026`.
@@ -26,15 +26,15 @@ On Linux / Windows servers, this tool simply doesn't exist — it's not in `tool
26
26
 
27
27
  ## Axes
28
28
 
29
- | Axis | Values | Source |
30
- | ------------ | ------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- |
31
- | `os` | `'darwin'`, `'linux'`, `'win32'` | `process.platform` (since #417 — was previously `platform`) |
32
- | `runtime` | `'node'`, `'browser'`, `'edge'`, `'bun'`, `'deno'` | Detected at boot |
33
- | `deployment` | `'serverless'`, `'standalone'`, `'distributed'`, `'browser'` | Detected from `frontmcp.config` / env |
34
- | `provider` | `'bare'`, `'docker'`, `'vercel'`, `'lambda'`, `'cloudflare'`, `'netlify'`, `'azure'`, `'gcp'`, `'fly'`, `'render'`, `'railway'` | Auto-detected; override with `FRONTMCP_PROVIDER=<name>` |
35
- | `target` | `'cli'`, `'node'`, `'vercel'`, `'lambda'`, `'cloudflare'`, `'browser'`, `'sdk'`, `'mcpb'`, `'distributed'` | Set by `frontmcp build --target <x>`; `'unknown'` in dev |
36
- | `surface` | `'mcp'`, `'cli'`, `'agent'`, `'job'`, `'http-trigger'` | Per-call axis — which entry point is invoking the tool |
37
- | `env` | `'production'`, `'development'`, `'test'` | `process.env.NODE_ENV` |
29
+ | Axis | Values | Source |
30
+ | ------------ | ------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
31
+ | `os` | `'darwin'`, `'linux'`, `'win32'` | `process.platform` (since #417 — was previously `platform`) |
32
+ | `runtime` | `'node'`, `'browser'`, `'edge'`, `'bun'`, `'deno'` | Detected at boot |
33
+ | `deployment` | `'serverless'`, `'standalone'`, `'distributed'`, `'browser'` | Detected from `frontmcp.config` / env |
34
+ | `provider` | `'bare'`, `'docker'`, `'vercel'`, `'lambda'`, `'cloudflare'`, `'netlify'`, `'azure'`, `'gcp'`, `'fly'`, `'render'`, `'railway'` | Auto-detected; override with `FRONTMCP_PROVIDER=<name>` |
35
+ | `target` | `'cli'`, `'node'`, `'vercel'`, `'lambda'`, `'cloudflare'`, `'browser'`, `'sdk'`, `'mcpb'`, `'distributed'` | Set by `frontmcp build --target <x>` in every artifact (`globalThis.FRONTMCP_BUILD_TARGET`; first to run wins, so a `cli` binary loading its server bundle stays `'cli'`); `'unknown'` in dev |
36
+ | `surface` | `'mcp'`, `'cli'`, `'agent'`, `'job'`, `'http-trigger'`, `'webmcp'` | Per-call axis — which entry point is invoking the tool |
37
+ | `env` | `'production'`, `'development'`, `'test'` | `NODE_ENV`, read live (a Worker's `[vars]` beats a bundler's inlined constant) |
38
38
 
39
39
  ## Semantics
40
40
 
@@ -100,7 +100,7 @@ These are fine for ergonomic branching. For tools that **shouldn't exist at all*
100
100
 
101
101
  This is the safest way to expose internal-only tools that you want an agent / job to call but don't want a user to invoke from a chat UI.
102
102
 
103
- An MCP client (and the in-process client of a CLI build, surface `'cli'`) never sees such a tool: it is absent from `tools/list`, and `tools/call` answers `Tool "rotate_secrets" not found`, exactly as for a tool that doesn't exist. Resources, resource templates, prompts, agents and skills (including the skills HTTP endpoints, which count as `'mcp'`) follow the same rule, and CodeCall applies its caller's surface to the tools it reaches. An agent's model calls its tools on `'agent'` (and is only offered those its `surface` allows), a job's or workflow step's `this.callTool()` on `'job'`, and a `@Channel` handling a webhook on `'http-trigger'`. A tool, resource or prompt calling `this.callTool()` is in-process dispatch: that call carries no surface and is not restricted. Code reads its call's surface with `getCallSurface()`. The process-wide axes (`os`, `runtime`, ...) answer `EntryUnavailableError` instead.
103
+ An MCP client (and the in-process client of a CLI build, surface `'cli'`) never sees such a tool: it is absent from `tools/list`, and `tools/call` answers `Tool "rotate_secrets" not found`, exactly as for a tool that doesn't exist. Resources, resource templates, prompts, agents and skills (including the skills HTTP endpoints, which count as `'mcp'`) follow the same rule, and CodeCall applies its caller's surface to the tools it reaches. An agent's model calls its tools on `'agent'` (and is only offered those its `surface` allows), a job's or workflow step's `this.callTool()` on `'job'`, a `@Channel` handling a webhook on `'http-trigger'`, and an in-browser agent calling through WebMCP (`@frontmcp/plugin-webmcp`) on `'webmcp'`. A tool, resource or prompt calling `this.callTool()` is in-process dispatch: that call carries no surface and is not restricted. Code reads its call's surface with `getCallSurface()`. The process-wide axes (`os`, `runtime`, ...) answer `EntryUnavailableError` instead.
104
104
 
105
105
  ## See also
106
106
 
@@ -43,7 +43,7 @@ Full surface of the `@Tool` decorator. Mandatory fields are bolded.
43
43
 
44
44
  - **`rateLimit` + `concurrency`** — independent. Rate-limit caps invocations over time; concurrency caps simultaneous in-flight. A "1 req/s with max 2 concurrent" tool is fine: bursts can run two at once, then back off.
45
45
  - **`timeout` + `rateLimit`** — orthogonal. Timeout wraps a single call; rate-limit wraps the rate of calls.
46
- - **`authProviders` + `ui.widgetAccessible`** — the widget bridge respects the tool's auth requirements. A widget that calls back to a tool requiring `authProviders: ['github']` will fail in the bridge if no GitHub session exists.
46
+ - **`authProviders` + widget tool calls** — a widget that calls back to a tool requiring `authProviders: ['github']` fails if no GitHub session exists. (`ui.widgetAccessible` is accepted but has no effect yet.)
47
47
  - **`availableWhen` + `visibility`** — `availableWhen` is a hard constraint (filtered out of `tools/list` AND blocked from execution when context doesn't match); `visibility: 'hidden'` is a soft hide (filtered from `tools/list` but still callable by name). `visibility: 'internal'` blocks external `tools/call` entirely (in-process `this.callTool` only).
48
48
  - **`ui.servingMode === 'static'` + `availableWhen`** — static widgets pre-compile at startup. If a tool is filtered out by `availableWhen`, its static widget isn't compiled either.
49
49