@leanmcp/ui 0.3.0 → 0.3.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 CHANGED
@@ -1,6 +1,42 @@
1
- # @leanmcp/ui
2
-
3
- **MCP-Native UI SDK for React** - Build rich, interactive MCP Apps with first-class tool integration.
1
+ <p align="center">
2
+ <img
3
+ src="https://raw.githubusercontent.com/LeanMCP/leanmcp-sdk/refs/heads/main/assets/logo.svg"
4
+ alt="LeanMCP Logo"
5
+ width="400"
6
+ />
7
+ </p>
8
+
9
+ <p align="center">
10
+ <strong>@leanmcp/ui</strong><br/>
11
+ MCP-Native UI SDK for React — Build rich, interactive MCP Apps with first-class tool integration.
12
+ </p>
13
+
14
+ <p align="center">
15
+ <a href="https://www.npmjs.com/package/@leanmcp/ui">
16
+ <img src="https://img.shields.io/npm/v/@leanmcp/ui" alt="npm version" />
17
+ </a>
18
+ <a href="https://www.npmjs.com/package/@leanmcp/ui">
19
+ <img src="https://img.shields.io/npm/dm/@leanmcp/ui" alt="npm downloads" />
20
+ </a>
21
+ <a href="https://docs.leanmcp.com/sdk/ui">
22
+ <img src="https://img.shields.io/badge/Docs-leanmcp-0A66C2?" />
23
+ </a>
24
+ <a href="https://discord.com/invite/DsRcA3GwPy">
25
+ <img src="https://img.shields.io/badge/Discord-Join-5865F2?logo=discord&logoColor=white" />
26
+ </a>
27
+ <a href="https://x.com/LeanMcp">
28
+ <img src="https://img.shields.io/badge/@LeanMCP-f5f5f5?logo=x&logoColor=000000" />
29
+ </a>
30
+ </p>
31
+
32
+ ## Features
33
+
34
+ - **MCP-Native Components** — ToolButton, ToolSelect, ToolForm, ToolDataGrid, and more
35
+ - **First-Class Tool Integration** — Components that natively call MCP tools
36
+ - **ChatGPT Apps Support** — Build apps that work inside ChatGPT with `@GPTApp`
37
+ - **Streaming Support** — Handle partial/streaming tool responses
38
+ - **Theming** — Automatic host theme adaptation (light/dark)
39
+ - **Testing Utilities** — `MockAppProvider` for unit testing
4
40
 
5
41
  ## Installation
6
42
 
@@ -126,6 +162,42 @@ function MyApp() {
126
162
  />
127
163
  ```
128
164
 
165
+ ## Server-Side Integration
166
+
167
+ Use `@UIApp` decorator to register your React component as an MCP resource.
168
+
169
+ > **Note:** Use a relative path string for the `component` property, not an imported component. This avoids importing React components on the server side.
170
+
171
+ ```typescript
172
+ // mcp/dashboard/index.ts
173
+ import { UIApp } from '@leanmcp/core';
174
+
175
+ export class DashboardService {
176
+ @UIApp({
177
+ component: './Dashboard', // Path relative to this file
178
+ name: 'dashboard',
179
+ title: 'Analytics Dashboard'
180
+ })
181
+ dashboard() {}
182
+ }
183
+ ```
184
+
185
+ ## ChatGPT Integration
186
+
187
+ Use `@GPTApp` for ChatGPT-specific apps:
188
+
189
+ ```typescript
190
+ import { GPTApp } from '@leanmcp/ui';
191
+
192
+ export class SlackService {
193
+ @GPTApp({
194
+ component: './SlackApp', // Path relative to this file
195
+ name: 'slack-composer'
196
+ })
197
+ slackComposer() {}
198
+ }
199
+ ```
200
+
129
201
  ## Theming
130
202
 
131
203
  The SDK uses CSS variables compatible with MCP host theming. Import the styles:
@@ -155,6 +227,19 @@ test('renders tool result', () => {
155
227
  });
156
228
  ```
157
229
 
230
+ ## Documentation
231
+
232
+ - [Full Documentation](https://docs.leanmcp.com/sdk/ui)
233
+ - [Component Reference](https://docs.leanmcp.com/sdk/ui-components)
234
+ - [Hooks Reference](https://docs.leanmcp.com/sdk/ui-hooks)
235
+ - [ChatGPT Apps Guide](https://docs.leanmcp.com/sdk/ui-gpt-apps)
236
+
237
+ ## Related Packages
238
+
239
+ - [@leanmcp/core](https://www.npmjs.com/package/@leanmcp/core) — Core MCP server functionality
240
+ - [@leanmcp/cli](https://www.npmjs.com/package/@leanmcp/cli) — CLI for project scaffolding
241
+ - [@leanmcp/auth](https://www.npmjs.com/package/@leanmcp/auth) — Authentication decorators
242
+
158
243
  ## License
159
244
 
160
245
  MIT
package/dist/index.js CHANGED
@@ -1689,6 +1689,10 @@ function useResource(uri, options = {}) {
1689
1689
  fetchResource
1690
1690
  ]);
1691
1691
  React26.useEffect(() => {
1692
+ if (intervalRef.current) {
1693
+ clearInterval(intervalRef.current);
1694
+ intervalRef.current = null;
1695
+ }
1692
1696
  if (refreshInterval && refreshInterval > 0 && isConnected && !skip) {
1693
1697
  intervalRef.current = setInterval(() => {
1694
1698
  fetchResource().catch(() => {
@@ -2619,7 +2623,10 @@ function useToolSubscription(toolName, options = {}) {
2619
2623
  setIsPolling(false);
2620
2624
  }, []);
2621
2625
  const start = React26.useCallback(() => {
2622
- stop();
2626
+ if (intervalRef.current) {
2627
+ clearInterval(intervalRef.current);
2628
+ intervalRef.current = null;
2629
+ }
2623
2630
  setIsPolling(true);
2624
2631
  toolHook.call(args).catch(() => {
2625
2632
  });
@@ -2630,8 +2637,7 @@ function useToolSubscription(toolName, options = {}) {
2630
2637
  }, [
2631
2638
  toolHook.call,
2632
2639
  args,
2633
- interval,
2634
- stop
2640
+ interval
2635
2641
  ]);
2636
2642
  const refresh = React26.useCallback(async () => {
2637
2643
  return toolHook.call(args);