@frontmcp/react 0.0.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.
Files changed (140) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +263 -0
  3. package/ai/createToolHandler.d.ts +10 -0
  4. package/ai/createToolHandler.d.ts.map +1 -0
  5. package/ai/index.d.ts +7 -0
  6. package/ai/index.d.ts.map +1 -0
  7. package/ai/index.js +416 -0
  8. package/ai/types.d.ts +52 -0
  9. package/ai/types.d.ts.map +1 -0
  10. package/ai/useAITools.d.ts +17 -0
  11. package/ai/useAITools.d.ts.map +1 -0
  12. package/ai/useTools.d.ts +19 -0
  13. package/ai/useTools.d.ts.map +1 -0
  14. package/api/api.types.d.ts +61 -0
  15. package/api/api.types.d.ts.map +1 -0
  16. package/api/createFetchClient.d.ts +9 -0
  17. package/api/createFetchClient.d.ts.map +1 -0
  18. package/api/index.d.ts +12 -0
  19. package/api/index.d.ts.map +1 -0
  20. package/api/index.js +402 -0
  21. package/api/parseOpenApiSpec.d.ts +9 -0
  22. package/api/parseOpenApiSpec.d.ts.map +1 -0
  23. package/api/useApiClient.d.ts +9 -0
  24. package/api/useApiClient.d.ts.map +1 -0
  25. package/components/AgentContent.d.ts +30 -0
  26. package/components/AgentContent.d.ts.map +1 -0
  27. package/components/AgentSearch.d.ts +35 -0
  28. package/components/AgentSearch.d.ts.map +1 -0
  29. package/components/ComponentRegistry.d.ts +36 -0
  30. package/components/ComponentRegistry.d.ts.map +1 -0
  31. package/components/DomResources.d.ts +16 -0
  32. package/components/DomResources.d.ts.map +1 -0
  33. package/components/DynamicRenderer.d.ts +19 -0
  34. package/components/DynamicRenderer.d.ts.map +1 -0
  35. package/components/OutputDisplay.d.ts +11 -0
  36. package/components/OutputDisplay.d.ts.map +1 -0
  37. package/components/PromptForm.d.ts +13 -0
  38. package/components/PromptForm.d.ts.map +1 -0
  39. package/components/ResourceViewer.d.ts +18 -0
  40. package/components/ResourceViewer.d.ts.map +1 -0
  41. package/components/ToolForm.d.ts +16 -0
  42. package/components/ToolForm.d.ts.map +1 -0
  43. package/components/index.d.ts +21 -0
  44. package/components/index.d.ts.map +1 -0
  45. package/components/mcpComponent.d.ts +48 -0
  46. package/components/mcpComponent.d.ts.map +1 -0
  47. package/esm/ai/index.mjs +393 -0
  48. package/esm/api/index.mjs +379 -0
  49. package/esm/index.mjs +1814 -0
  50. package/esm/package.json +111 -0
  51. package/esm/router/index.mjs +157 -0
  52. package/esm/state/index.mjs +450 -0
  53. package/hooks/index.d.ts +21 -0
  54. package/hooks/index.d.ts.map +1 -0
  55. package/hooks/useCallTool.d.ts +9 -0
  56. package/hooks/useCallTool.d.ts.map +1 -0
  57. package/hooks/useComponentTree.d.ts +21 -0
  58. package/hooks/useComponentTree.d.ts.map +1 -0
  59. package/hooks/useDynamicResource.d.ts +20 -0
  60. package/hooks/useDynamicResource.d.ts.map +1 -0
  61. package/hooks/useDynamicTool.d.ts +39 -0
  62. package/hooks/useDynamicTool.d.ts.map +1 -0
  63. package/hooks/useFrontMcp.d.ts +8 -0
  64. package/hooks/useFrontMcp.d.ts.map +1 -0
  65. package/hooks/useGetPrompt.d.ts +13 -0
  66. package/hooks/useGetPrompt.d.ts.map +1 -0
  67. package/hooks/useListPrompts.d.ts +10 -0
  68. package/hooks/useListPrompts.d.ts.map +1 -0
  69. package/hooks/useListResources.d.ts +14 -0
  70. package/hooks/useListResources.d.ts.map +1 -0
  71. package/hooks/useListTools.d.ts +10 -0
  72. package/hooks/useListTools.d.ts.map +1 -0
  73. package/hooks/useReadResource.d.ts +23 -0
  74. package/hooks/useReadResource.d.ts.map +1 -0
  75. package/hooks/useResolvedServer.d.ts +16 -0
  76. package/hooks/useResolvedServer.d.ts.map +1 -0
  77. package/hooks/useServer.d.ts +17 -0
  78. package/hooks/useServer.d.ts.map +1 -0
  79. package/hooks/useStoreResource.d.ts +22 -0
  80. package/hooks/useStoreResource.d.ts.map +1 -0
  81. package/index.d.ts +33 -0
  82. package/index.d.ts.map +1 -0
  83. package/index.js +1821 -0
  84. package/package.json +111 -0
  85. package/provider/FrontMcpContext.d.ts +6 -0
  86. package/provider/FrontMcpContext.d.ts.map +1 -0
  87. package/provider/FrontMcpProvider.d.ts +34 -0
  88. package/provider/FrontMcpProvider.d.ts.map +1 -0
  89. package/provider/index.d.ts +4 -0
  90. package/provider/index.d.ts.map +1 -0
  91. package/registry/DynamicRegistry.d.ts +55 -0
  92. package/registry/DynamicRegistry.d.ts.map +1 -0
  93. package/registry/ServerRegistry.d.ts +43 -0
  94. package/registry/ServerRegistry.d.ts.map +1 -0
  95. package/registry/createWrappedServer.d.ts +14 -0
  96. package/registry/createWrappedServer.d.ts.map +1 -0
  97. package/registry/index.d.ts +5 -0
  98. package/registry/index.d.ts.map +1 -0
  99. package/router/current-route.resource.d.ts +11 -0
  100. package/router/current-route.resource.d.ts.map +1 -0
  101. package/router/go-back.tool.d.ts +18 -0
  102. package/router/go-back.tool.d.ts.map +1 -0
  103. package/router/index.d.ts +9 -0
  104. package/router/index.d.ts.map +1 -0
  105. package/router/index.js +180 -0
  106. package/router/navigate.tool.d.ts +35 -0
  107. package/router/navigate.tool.d.ts.map +1 -0
  108. package/router/router-bridge.d.ts +20 -0
  109. package/router/router-bridge.d.ts.map +1 -0
  110. package/router/router.entries.d.ts +23 -0
  111. package/router/router.entries.d.ts.map +1 -0
  112. package/router/useRouterBridge.d.ts +7 -0
  113. package/router/useRouterBridge.d.ts.map +1 -0
  114. package/state/adapters/createStore.d.ts +15 -0
  115. package/state/adapters/createStore.d.ts.map +1 -0
  116. package/state/adapters/index.d.ts +7 -0
  117. package/state/adapters/index.d.ts.map +1 -0
  118. package/state/adapters/reduxAdapter.d.ts +21 -0
  119. package/state/adapters/reduxAdapter.d.ts.map +1 -0
  120. package/state/adapters/valtioAdapter.d.ts +19 -0
  121. package/state/adapters/valtioAdapter.d.ts.map +1 -0
  122. package/state/index.d.ts +15 -0
  123. package/state/index.d.ts.map +1 -0
  124. package/state/index.js +473 -0
  125. package/state/state.types.d.ts +48 -0
  126. package/state/state.types.d.ts.map +1 -0
  127. package/state/useReduxResource.d.ts +8 -0
  128. package/state/useReduxResource.d.ts.map +1 -0
  129. package/state/useStoreRegistration.d.ts +14 -0
  130. package/state/useStoreRegistration.d.ts.map +1 -0
  131. package/state/useStoreResource.d.ts +10 -0
  132. package/state/useStoreResource.d.ts.map +1 -0
  133. package/state/useValtioResource.d.ts +9 -0
  134. package/state/useValtioResource.d.ts.map +1 -0
  135. package/types.d.ts +127 -0
  136. package/types.d.ts.map +1 -0
  137. package/utils/index.d.ts +2 -0
  138. package/utils/index.d.ts.map +1 -0
  139. package/utils/zodToJsonSchema.d.ts +9 -0
  140. package/utils/zodToJsonSchema.d.ts.map +1 -0
@@ -0,0 +1,15 @@
1
+ /**
2
+ * createStore — generic pass-through adapter factory for any custom store.
3
+ *
4
+ * Accepts a StoreAdapter-compatible object directly.
5
+ */
6
+ import type { StoreAdapter } from '../../types';
7
+ export interface CreateStoreOptions {
8
+ name: string;
9
+ getState: () => unknown;
10
+ subscribe: (cb: () => void) => () => void;
11
+ selectors?: Record<string, (state: unknown) => unknown>;
12
+ actions?: Record<string, (...args: unknown[]) => unknown>;
13
+ }
14
+ export declare function createStore(options: CreateStoreOptions): StoreAdapter;
15
+ //# sourceMappingURL=createStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createStore.d.ts","sourceRoot":"","sources":["../../../src/state/adapters/createStore.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,OAAO,CAAC;IACxB,SAAS,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAC;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC;IACxD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,CAAC;CAC3D;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,YAAY,CAQrE"}
@@ -0,0 +1,7 @@
1
+ export { reduxStore } from './reduxAdapter';
2
+ export type { ReduxStoreOptions } from './reduxAdapter';
3
+ export { valtioStore } from './valtioAdapter';
4
+ export type { ValtioStoreOptions } from './valtioAdapter';
5
+ export { createStore } from './createStore';
6
+ export type { CreateStoreOptions } from './createStore';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/state/adapters/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,YAAY,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * reduxStore — adapter factory that normalizes a Redux store to the
3
+ * common StoreAdapter interface for provider-level registration.
4
+ */
5
+ import type { StoreAdapter } from '../../types';
6
+ export interface ReduxStoreOptions {
7
+ /** Redux store instance. */
8
+ store: {
9
+ getState(): unknown;
10
+ dispatch(action: unknown): unknown;
11
+ subscribe(fn: () => void): () => void;
12
+ };
13
+ /** Logical name (defaults to 'redux'). */
14
+ name?: string;
15
+ /** Named selectors — each becomes a sub-resource. */
16
+ selectors?: Record<string, (state: unknown) => unknown>;
17
+ /** Named action creators — each becomes a dynamic tool that auto-dispatches. */
18
+ actions?: Record<string, (...args: unknown[]) => unknown>;
19
+ }
20
+ export declare function reduxStore(options: ReduxStoreOptions): StoreAdapter;
21
+ //# sourceMappingURL=reduxAdapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reduxAdapter.d.ts","sourceRoot":"","sources":["../../../src/state/adapters/reduxAdapter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,WAAW,iBAAiB;IAChC,4BAA4B;IAC5B,KAAK,EAAE;QACL,QAAQ,IAAI,OAAO,CAAC;QACpB,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC;QACnC,SAAS,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;KACvC,CAAC;IACF,0CAA0C;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC;IACxD,gFAAgF;IAChF,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,CAAC;CAC3D;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,YAAY,CAsBnE"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * valtioStore — adapter factory that normalizes a Valtio proxy to the
3
+ * common StoreAdapter interface for provider-level registration.
4
+ */
5
+ import type { StoreAdapter } from '../../types';
6
+ export interface ValtioStoreOptions {
7
+ /** Valtio proxy object. */
8
+ proxy: Record<string, unknown>;
9
+ /** User-provided subscribe function from valtio/utils. */
10
+ subscribe: (proxy: Record<string, unknown>, cb: () => void) => () => void;
11
+ /** Logical name (defaults to 'valtio'). */
12
+ name?: string;
13
+ /** Named deep path selectors (dot notation, e.g., 'user.name'). */
14
+ paths?: Record<string, string>;
15
+ /** Named mutations — each becomes a dynamic tool. */
16
+ mutations?: Record<string, (...args: unknown[]) => void>;
17
+ }
18
+ export declare function valtioStore(options: ValtioStoreOptions): StoreAdapter;
19
+ //# sourceMappingURL=valtioAdapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"valtioAdapter.d.ts","sourceRoot":"","sources":["../../../src/state/adapters/valtioAdapter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,WAAW,kBAAkB;IACjC,2BAA2B;IAC3B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,0DAA0D;IAC1D,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAAE,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAC;IAC1E,2CAA2C;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,qDAAqD;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC,CAAC;CAC1D;AAYD,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,YAAY,CA4BrE"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @frontmcp/react/state — State management integration for FrontMCP.
3
+ *
4
+ * Exposes Redux, Valtio, or any store as MCP resources (with deep selectors)
5
+ * and actions as MCP tools that agents can invoke.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ export { useStoreResource } from './useStoreResource';
10
+ export { useReduxResource } from './useReduxResource';
11
+ export { useValtioResource } from './useValtioResource';
12
+ export type { StoreResourceOptions, ReduxResourceOptions, ValtioResourceOptions } from './state.types';
13
+ export { reduxStore, valtioStore, createStore } from './adapters';
14
+ export type { ReduxStoreOptions, ValtioStoreOptions, CreateStoreOptions } from './adapters';
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/state/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,YAAY,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACvG,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAClE,YAAY,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC"}
package/state/index.js ADDED
@@ -0,0 +1,473 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // libs/react/src/state/index.ts
21
+ var state_exports = {};
22
+ __export(state_exports, {
23
+ createStore: () => createStore,
24
+ reduxStore: () => reduxStore,
25
+ useReduxResource: () => useReduxResource,
26
+ useStoreResource: () => useStoreResource,
27
+ useValtioResource: () => useValtioResource,
28
+ valtioStore: () => valtioStore
29
+ });
30
+ module.exports = __toCommonJS(state_exports);
31
+
32
+ // libs/react/src/state/useStoreResource.ts
33
+ var import_react2 = require("react");
34
+
35
+ // libs/react/src/provider/FrontMcpContext.ts
36
+ var import_react = require("react");
37
+
38
+ // libs/react/src/components/ComponentRegistry.ts
39
+ var ComponentRegistry = class {
40
+ entries = /* @__PURE__ */ new Map();
41
+ register(uri, component, meta) {
42
+ const name = extractName(uri);
43
+ this.entries.set(uri, { uri, name, component, description: meta?.description });
44
+ }
45
+ registerAll(map) {
46
+ for (const [uri, component] of Object.entries(map)) {
47
+ this.register(uri, component);
48
+ }
49
+ }
50
+ get(uri) {
51
+ return this.entries.get(uri)?.component;
52
+ }
53
+ /**
54
+ * Resolve a shorthand name like `'UserCard'` by trying
55
+ * `component://UserCard`, `element://UserCard`, `page://UserCard`.
56
+ */
57
+ resolve(type) {
58
+ const exact = this.entries.get(type);
59
+ if (exact) return exact.component;
60
+ for (const protocol of ["component://", "element://", "page://"]) {
61
+ const entry = this.entries.get(`${protocol}${type}`);
62
+ if (entry) return entry.component;
63
+ }
64
+ return void 0;
65
+ }
66
+ has(uri) {
67
+ return this.entries.has(uri);
68
+ }
69
+ list() {
70
+ return Array.from(this.entries.values()).map(({ uri, name, description }) => ({
71
+ uri,
72
+ name,
73
+ description
74
+ }));
75
+ }
76
+ clear() {
77
+ this.entries.clear();
78
+ }
79
+ };
80
+ function extractName(uri) {
81
+ const idx = uri.indexOf("://");
82
+ return idx >= 0 ? uri.slice(idx + 3) : uri;
83
+ }
84
+
85
+ // libs/react/src/registry/DynamicRegistry.ts
86
+ var DynamicRegistry = class {
87
+ tools = /* @__PURE__ */ new Map();
88
+ resources = /* @__PURE__ */ new Map();
89
+ toolRefCounts = /* @__PURE__ */ new Map();
90
+ resourceRefCounts = /* @__PURE__ */ new Map();
91
+ listeners = /* @__PURE__ */ new Set();
92
+ version = 0;
93
+ /**
94
+ * Register a dynamic tool. Returns an unregister function
95
+ * suitable for useEffect cleanup.
96
+ *
97
+ * Multiple registrations of the same name are ref-counted:
98
+ * subsequent registrations update the definition but the tool
99
+ * is only removed when every registrant has unregistered.
100
+ */
101
+ registerTool(def) {
102
+ const existing = this.toolRefCounts.get(def.name) ?? 0;
103
+ this.toolRefCounts.set(def.name, existing + 1);
104
+ this.tools.set(def.name, def);
105
+ if (existing === 0) {
106
+ this.notify();
107
+ }
108
+ let called = false;
109
+ return () => {
110
+ if (called) return;
111
+ called = true;
112
+ this.unregisterTool(def.name);
113
+ };
114
+ }
115
+ unregisterTool(name) {
116
+ const count = this.toolRefCounts.get(name);
117
+ if (count == null) return;
118
+ if (count <= 1) {
119
+ this.toolRefCounts.delete(name);
120
+ this.tools.delete(name);
121
+ this.notify();
122
+ } else {
123
+ this.toolRefCounts.set(name, count - 1);
124
+ }
125
+ }
126
+ /**
127
+ * Register a dynamic resource. Returns an unregister function
128
+ * suitable for useEffect cleanup.
129
+ *
130
+ * Multiple registrations of the same URI are ref-counted.
131
+ */
132
+ registerResource(def) {
133
+ const existing = this.resourceRefCounts.get(def.uri) ?? 0;
134
+ this.resourceRefCounts.set(def.uri, existing + 1);
135
+ this.resources.set(def.uri, def);
136
+ if (existing === 0) {
137
+ this.notify();
138
+ }
139
+ let called = false;
140
+ return () => {
141
+ if (called) return;
142
+ called = true;
143
+ this.unregisterResource(def.uri);
144
+ };
145
+ }
146
+ unregisterResource(uri) {
147
+ const count = this.resourceRefCounts.get(uri);
148
+ if (count == null) return;
149
+ if (count <= 1) {
150
+ this.resourceRefCounts.delete(uri);
151
+ this.resources.delete(uri);
152
+ this.notify();
153
+ } else {
154
+ this.resourceRefCounts.set(uri, count - 1);
155
+ }
156
+ }
157
+ /** Update the execute function for an existing tool (for stale closure prevention). */
158
+ updateToolExecute(name, execute) {
159
+ const existing = this.tools.get(name);
160
+ if (existing) {
161
+ existing.execute = execute;
162
+ }
163
+ }
164
+ /** Update the read function for an existing resource and notify subscribers. */
165
+ updateResourceRead(uri, read) {
166
+ const existing = this.resources.get(uri);
167
+ if (existing) {
168
+ existing.read = read;
169
+ this.notify();
170
+ }
171
+ }
172
+ getTools() {
173
+ return [...this.tools.values()];
174
+ }
175
+ getResources() {
176
+ return [...this.resources.values()];
177
+ }
178
+ findTool(name) {
179
+ return this.tools.get(name);
180
+ }
181
+ findResource(uri) {
182
+ return this.resources.get(uri);
183
+ }
184
+ hasTool(name) {
185
+ return this.tools.has(name);
186
+ }
187
+ hasResource(uri) {
188
+ return this.resources.has(uri);
189
+ }
190
+ subscribe(listener) {
191
+ this.listeners.add(listener);
192
+ return () => {
193
+ this.listeners.delete(listener);
194
+ };
195
+ }
196
+ getVersion() {
197
+ return this.version;
198
+ }
199
+ clear() {
200
+ if (this.tools.size === 0 && this.resources.size === 0) return;
201
+ this.tools.clear();
202
+ this.resources.clear();
203
+ this.toolRefCounts.clear();
204
+ this.resourceRefCounts.clear();
205
+ this.notify();
206
+ }
207
+ notify() {
208
+ this.version++;
209
+ this.listeners.forEach((l) => {
210
+ l();
211
+ });
212
+ }
213
+ };
214
+
215
+ // libs/react/src/provider/FrontMcpContext.ts
216
+ var defaultDynamicRegistry = new DynamicRegistry();
217
+ var FrontMcpContext = (0, import_react.createContext)({
218
+ name: "default",
219
+ registry: new ComponentRegistry(),
220
+ dynamicRegistry: defaultDynamicRegistry,
221
+ getDynamicRegistry: () => defaultDynamicRegistry,
222
+ connect: async () => {
223
+ }
224
+ });
225
+
226
+ // libs/react/src/state/useStoreResource.ts
227
+ var VALID_NAME_RE = /^[a-zA-Z0-9_-]+$/;
228
+ function useStoreResource(options) {
229
+ const { name, getState, subscribe, selectors, actions } = options;
230
+ const { getDynamicRegistry } = (0, import_react2.useContext)(FrontMcpContext);
231
+ const dynamicRegistry = getDynamicRegistry(options.server);
232
+ if (!name || !VALID_NAME_RE.test(name)) {
233
+ throw new Error(`useStoreResource: invalid store name "${name}". Names must match ${VALID_NAME_RE}.`);
234
+ }
235
+ const getStateRef = (0, import_react2.useRef)(getState);
236
+ getStateRef.current = getState;
237
+ const readState = (0, import_react2.useCallback)(
238
+ async () => ({
239
+ contents: [
240
+ {
241
+ uri: `state://${name}`,
242
+ mimeType: "application/json",
243
+ text: JSON.stringify(getStateRef.current() ?? null)
244
+ }
245
+ ]
246
+ }),
247
+ [name]
248
+ );
249
+ (0, import_react2.useEffect)(() => {
250
+ const unregister = dynamicRegistry.registerResource({
251
+ uri: `state://${name}`,
252
+ name: `${name}-state`,
253
+ description: `Full state of ${name} store`,
254
+ mimeType: "application/json",
255
+ read: readState
256
+ });
257
+ const unsubscribe = subscribe(() => {
258
+ dynamicRegistry.updateResourceRead(`state://${name}`, readState);
259
+ });
260
+ return () => {
261
+ unregister();
262
+ unsubscribe();
263
+ };
264
+ }, [dynamicRegistry, name, subscribe, readState]);
265
+ (0, import_react2.useEffect)(() => {
266
+ if (!selectors) return;
267
+ const cleanups = [];
268
+ const selectorUris = [];
269
+ for (const [key, selector] of Object.entries(selectors)) {
270
+ if (!key || !VALID_NAME_RE.test(key)) {
271
+ throw new Error(`useStoreResource: invalid selector key "${key}". Keys must match ${VALID_NAME_RE}.`);
272
+ }
273
+ const uri = `state://${name}/${key}`;
274
+ const selectorRef = { current: selector };
275
+ const readSelector = async () => ({
276
+ contents: [
277
+ {
278
+ uri,
279
+ mimeType: "application/json",
280
+ text: JSON.stringify(selectorRef.current(getStateRef.current()) ?? null)
281
+ }
282
+ ]
283
+ });
284
+ selectorUris.push({ uri, readSelector });
285
+ cleanups.push(
286
+ dynamicRegistry.registerResource({
287
+ uri,
288
+ name: `${name}-${key}`,
289
+ description: `Selector "${key}" from ${name} store`,
290
+ mimeType: "application/json",
291
+ read: readSelector
292
+ })
293
+ );
294
+ }
295
+ const unsubscribe = subscribe(() => {
296
+ for (const { uri, readSelector } of selectorUris) {
297
+ dynamicRegistry.updateResourceRead(uri, readSelector);
298
+ }
299
+ });
300
+ cleanups.push(unsubscribe);
301
+ return () => {
302
+ cleanups.forEach((fn) => {
303
+ fn();
304
+ });
305
+ };
306
+ }, [dynamicRegistry, name, selectors, subscribe]);
307
+ (0, import_react2.useEffect)(() => {
308
+ if (!actions) return;
309
+ const cleanups = [];
310
+ for (const [key, action] of Object.entries(actions)) {
311
+ const toolName = `${name}_${key}`;
312
+ const execute = async (args) => {
313
+ const argsArray = args["args"];
314
+ const result = await (Array.isArray(argsArray) ? action(...argsArray) : action(args));
315
+ return {
316
+ content: [{ type: "text", text: JSON.stringify({ success: true, result }) }]
317
+ };
318
+ };
319
+ cleanups.push(
320
+ dynamicRegistry.registerTool({
321
+ name: toolName,
322
+ description: `Action "${key}" on ${name} store`,
323
+ inputSchema: {
324
+ type: "object",
325
+ properties: {
326
+ args: { type: "array", description: "Arguments to pass to the action" }
327
+ }
328
+ },
329
+ execute
330
+ })
331
+ );
332
+ }
333
+ return () => {
334
+ cleanups.forEach((fn) => {
335
+ fn();
336
+ });
337
+ };
338
+ }, [dynamicRegistry, name, actions]);
339
+ }
340
+
341
+ // libs/react/src/state/useReduxResource.ts
342
+ var import_react3 = require("react");
343
+ function useReduxResource(options) {
344
+ const { store, name = "redux", selectors, actions, server } = options;
345
+ const wrappedActions = (0, import_react3.useMemo)(() => {
346
+ if (!actions) return void 0;
347
+ const wrapped = {};
348
+ for (const [key, actionCreator] of Object.entries(actions)) {
349
+ wrapped[key] = (...args) => {
350
+ const action = actionCreator(...args);
351
+ return store.dispatch(action);
352
+ };
353
+ }
354
+ return wrapped;
355
+ }, [actions, store]);
356
+ useStoreResource({
357
+ name,
358
+ getState: store.getState.bind(store),
359
+ subscribe: store.subscribe.bind(store),
360
+ selectors,
361
+ actions: wrappedActions,
362
+ server
363
+ });
364
+ }
365
+
366
+ // libs/react/src/state/useValtioResource.ts
367
+ var import_react4 = require("react");
368
+ function getByPath(obj, path) {
369
+ const parts = path.split(".");
370
+ let current = obj;
371
+ for (const part of parts) {
372
+ if (current == null || typeof current !== "object") return void 0;
373
+ current = current[part];
374
+ }
375
+ return current;
376
+ }
377
+ function useValtioResource(options) {
378
+ const { proxy, subscribe: valtioSubscribe, name = "valtio", paths, mutations, server } = options;
379
+ const selectors = (0, import_react4.useMemo)(() => {
380
+ if (!paths) return void 0;
381
+ const sels = {};
382
+ for (const [key, path] of Object.entries(paths)) {
383
+ sels[key] = (state) => getByPath(state, path);
384
+ }
385
+ return sels;
386
+ }, [paths]);
387
+ const subscribe = (0, import_react4.useMemo)(() => (cb) => valtioSubscribe(proxy, cb), [proxy, valtioSubscribe]);
388
+ const actions = (0, import_react4.useMemo)(() => {
389
+ if (!mutations) return void 0;
390
+ const wrapped = {};
391
+ for (const [key, mutation] of Object.entries(mutations)) {
392
+ wrapped[key] = (...args) => mutation(...args);
393
+ }
394
+ return wrapped;
395
+ }, [mutations]);
396
+ const getState = (0, import_react4.useMemo)(() => () => JSON.parse(JSON.stringify(proxy)), [proxy]);
397
+ useStoreResource({
398
+ name,
399
+ getState,
400
+ subscribe,
401
+ selectors,
402
+ actions,
403
+ server
404
+ });
405
+ }
406
+
407
+ // libs/react/src/state/adapters/reduxAdapter.ts
408
+ function reduxStore(options) {
409
+ const { store, name = "redux", selectors, actions: rawActions } = options;
410
+ let actions;
411
+ if (rawActions) {
412
+ actions = {};
413
+ for (const [key, actionCreator] of Object.entries(rawActions)) {
414
+ actions[key] = (...args) => {
415
+ const action = actionCreator(...args);
416
+ return store.dispatch(action);
417
+ };
418
+ }
419
+ }
420
+ return {
421
+ name,
422
+ getState: store.getState.bind(store),
423
+ subscribe: store.subscribe.bind(store),
424
+ selectors,
425
+ actions
426
+ };
427
+ }
428
+
429
+ // libs/react/src/state/adapters/valtioAdapter.ts
430
+ function getByPath2(obj, path) {
431
+ const parts = path.split(".");
432
+ let current = obj;
433
+ for (const part of parts) {
434
+ if (current == null || typeof current !== "object") return void 0;
435
+ current = current[part];
436
+ }
437
+ return current;
438
+ }
439
+ function valtioStore(options) {
440
+ const { proxy, subscribe: valtioSubscribe, name = "valtio", paths, mutations } = options;
441
+ let selectors;
442
+ if (paths) {
443
+ selectors = {};
444
+ for (const [key, path] of Object.entries(paths)) {
445
+ selectors[key] = (state) => getByPath2(state, path);
446
+ }
447
+ }
448
+ let actions;
449
+ if (mutations) {
450
+ actions = {};
451
+ for (const [key, mutation] of Object.entries(mutations)) {
452
+ actions[key] = (...args) => mutation(...args);
453
+ }
454
+ }
455
+ return {
456
+ name,
457
+ getState: () => JSON.parse(JSON.stringify(proxy)),
458
+ subscribe: (cb) => valtioSubscribe(proxy, cb),
459
+ selectors,
460
+ actions
461
+ };
462
+ }
463
+
464
+ // libs/react/src/state/adapters/createStore.ts
465
+ function createStore(options) {
466
+ return {
467
+ name: options.name,
468
+ getState: options.getState,
469
+ subscribe: options.subscribe,
470
+ selectors: options.selectors,
471
+ actions: options.actions
472
+ };
473
+ }
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Shared types for state management integration.
3
+ */
4
+ export interface StoreResourceOptions {
5
+ /** Name prefix for resources and tools (e.g., 'redux' → state://redux). */
6
+ name: string;
7
+ /** Returns the current state snapshot. */
8
+ getState: () => unknown;
9
+ /** Subscribes to state changes. Returns an unsubscribe function. */
10
+ subscribe: (cb: () => void) => () => void;
11
+ /** Named selectors — each becomes a sub-resource state://{name}/{key}. */
12
+ selectors?: Record<string, (state: unknown) => unknown>;
13
+ /** Named actions — each becomes a dynamic tool {name}_{key}. */
14
+ actions?: Record<string, (...args: unknown[]) => unknown>;
15
+ /** Target a specific named server. */
16
+ server?: string;
17
+ }
18
+ export interface ReduxResourceOptions {
19
+ /** Redux store with standard getState/dispatch/subscribe interface. */
20
+ store: {
21
+ getState(): unknown;
22
+ dispatch(action: unknown): unknown;
23
+ subscribe(fn: () => void): () => void;
24
+ };
25
+ /** Name prefix (defaults to 'redux'). */
26
+ name?: string;
27
+ /** Named selectors — each becomes a sub-resource. */
28
+ selectors?: Record<string, (state: unknown) => unknown>;
29
+ /** Named action creators — each becomes a dynamic tool that dispatches. */
30
+ actions?: Record<string, (...args: unknown[]) => unknown>;
31
+ /** Target a specific named server. */
32
+ server?: string;
33
+ }
34
+ export interface ValtioResourceOptions {
35
+ /** Valtio proxy object. */
36
+ proxy: Record<string, unknown>;
37
+ /** User-provided subscribe function from valtio/utils. */
38
+ subscribe: (proxy: Record<string, unknown>, cb: () => void) => () => void;
39
+ /** Name prefix (defaults to 'valtio'). */
40
+ name?: string;
41
+ /** Named deep path selectors (dot notation, e.g., 'user.name'). */
42
+ paths?: Record<string, string>;
43
+ /** Named mutations — each becomes a dynamic tool. */
44
+ mutations?: Record<string, (...args: unknown[]) => void>;
45
+ /** Target a specific named server. */
46
+ server?: string;
47
+ }
48
+ //# sourceMappingURL=state.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.types.d.ts","sourceRoot":"","sources":["../../src/state/state.types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,oBAAoB;IACnC,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,OAAO,CAAC;IACxB,oEAAoE;IACpE,SAAS,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAC;IAC1C,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC;IACxD,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,CAAC;IAC1D,sCAAsC;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,uEAAuE;IACvE,KAAK,EAAE;QACL,QAAQ,IAAI,OAAO,CAAC;QACpB,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC;QACnC,SAAS,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;KACvC,CAAC;IACF,yCAAyC;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC;IACxD,2EAA2E;IAC3E,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,CAAC;IAC1D,sCAAsC;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,qBAAqB;IACpC,2BAA2B;IAC3B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,0DAA0D;IAC1D,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAAE,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAC;IAC1E,0CAA0C;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,qDAAqD;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC,CAAC;IACzD,sCAAsC;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * useReduxResource — thin wrapper around useStoreResource for Redux stores.
3
+ *
4
+ * Accepts a standard Redux store and dispatches action creators as MCP tools.
5
+ */
6
+ import type { ReduxResourceOptions } from './state.types';
7
+ export declare function useReduxResource(options: ReduxResourceOptions): void;
8
+ //# sourceMappingURL=useReduxResource.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useReduxResource.d.ts","sourceRoot":"","sources":["../../src/state/useReduxResource.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAE1D,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAwBpE"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * useStoreRegistration — internal hook that takes StoreAdapter[] and a
3
+ * DynamicRegistry, then registers all resources/tools.
4
+ *
5
+ * Reuses the same registration logic as useStoreResource:
6
+ * - For each adapter: register main resource state://{name}, selector
7
+ * sub-resources, and action tools
8
+ * - Subscribe to store changes, call updateResourceRead on change
9
+ * - Cleanup on unmount
10
+ */
11
+ import type { DynamicRegistry } from '../registry/DynamicRegistry';
12
+ import type { StoreAdapter } from '../types';
13
+ export declare function useStoreRegistration(stores: StoreAdapter[], dynamicRegistry: DynamicRegistry): void;
14
+ //# sourceMappingURL=useStoreRegistration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useStoreRegistration.d.ts","sourceRoot":"","sources":["../../src/state/useStoreRegistration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAU7C,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,YAAY,EAAE,EAAE,eAAe,EAAE,eAAe,GAAG,IAAI,CAkHnG"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * useStoreResource — generic hook that exposes any state store as MCP
3
+ * resources (with optional deep selectors) and actions as tools.
4
+ *
5
+ * This is the core hook; useReduxResource and useValtioResource are
6
+ * thin wrappers around it.
7
+ */
8
+ import type { StoreResourceOptions } from './state.types';
9
+ export declare function useStoreResource(options: StoreResourceOptions): void;
10
+ //# sourceMappingURL=useStoreResource.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useStoreResource.d.ts","sourceRoot":"","sources":["../../src/state/useStoreResource.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAI1D,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI,CA0IpE"}