@decocms/mesh-sdk 1.2.1 → 1.2.3
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 +10 -10
- package/package.json +7 -4
- package/src/context/index.ts +5 -1
- package/src/context/project-context.tsx +68 -29
- package/src/hooks/index.ts +10 -0
- package/src/hooks/use-collections.ts +179 -63
- package/src/hooks/use-connection.ts +50 -4
- package/src/hooks/use-mcp-client.ts +81 -11
- package/src/hooks/use-mcp-prompts.ts +16 -6
- package/src/hooks/use-mcp-resources.ts +15 -5
- package/src/hooks/use-virtual-mcp.ts +64 -0
- package/src/index.ts +119 -4
- package/src/lib/bridge-transport.test.ts +368 -0
- package/src/lib/bridge-transport.ts +6 -0
- package/src/lib/constants.test.ts +26 -0
- package/src/lib/constants.ts +193 -36
- package/src/lib/default-model.ts +281 -0
- package/src/lib/mcp-oauth.ts +139 -17
- package/src/lib/query-keys.ts +20 -4
- package/src/lib/server-client-bridge.ts +4 -0
- package/src/lib/usage.test.ts +229 -0
- package/src/lib/usage.ts +187 -0
- package/src/plugins/index.ts +15 -0
- package/src/plugins/plugin-context-provider.tsx +99 -0
- package/src/plugins/topbar-portal.tsx +118 -0
- package/src/types/ai-providers.ts +86 -0
- package/src/types/connection.ts +43 -20
- package/src/types/decopilot-events.test.ts +78 -0
- package/src/types/decopilot-events.ts +171 -0
- package/src/types/index.ts +48 -1
- package/src/types/virtual-mcp.test.ts +202 -0
- package/src/types/virtual-mcp.ts +514 -109
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @decocms/mesh-sdk
|
|
2
2
|
|
|
3
|
-
SDK for building external apps that integrate with
|
|
3
|
+
SDK for building external apps that integrate with Studio MCP servers. Provides React hooks and utilities for managing connections, authenticating with OAuth, and calling MCP tools.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -22,7 +22,7 @@ npm install sonner
|
|
|
22
22
|
|
|
23
23
|
### 1. Create an API Key
|
|
24
24
|
|
|
25
|
-
In
|
|
25
|
+
In Studio, call the `API_KEY_CREATE` tool to create an API key with the appropriate scopes for the connections you want to access. The API key will be used to authenticate your external app.
|
|
26
26
|
|
|
27
27
|
```typescript
|
|
28
28
|
// Example: Create an API key via MCP
|
|
@@ -35,7 +35,7 @@ await client.callTool({
|
|
|
35
35
|
});
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
-
### 2. Server-Side: Connect to
|
|
38
|
+
### 2. Server-Side: Connect to Studio
|
|
39
39
|
|
|
40
40
|
```typescript
|
|
41
41
|
// server.ts (Node.js / Bun / your backend)
|
|
@@ -213,12 +213,12 @@ const result = await specificClient.callTool({
|
|
|
213
213
|
|
|
214
214
|
### `createMCPClient(options)` - Server-Side
|
|
215
215
|
|
|
216
|
-
Creates and connects an MCP client to a
|
|
216
|
+
Creates and connects an MCP client to a Studio server. **Use on server only** - don't expose your API key to the client.
|
|
217
217
|
|
|
218
218
|
```typescript
|
|
219
219
|
// server-side only
|
|
220
220
|
const client = await createMCPClient({
|
|
221
|
-
meshUrl: "https://
|
|
221
|
+
meshUrl: "https://studio.example.com", // Required for external apps
|
|
222
222
|
connectionId: "self", // "self" for management API, or connection ID
|
|
223
223
|
orgId: "org_xxx", // Organization ID
|
|
224
224
|
token: process.env.MESH_API_KEY, // API key from environment
|
|
@@ -227,7 +227,7 @@ const client = await createMCPClient({
|
|
|
227
227
|
|
|
228
228
|
### `useMCPClient(options)` - Client-Side (Same-Origin Only)
|
|
229
229
|
|
|
230
|
-
React hook version of `createMCPClient`. Uses Suspense. **Only use when running on the same origin as
|
|
230
|
+
React hook version of `createMCPClient`. Uses Suspense. **Only use when running on the same origin as Studio** (e.g., inside Studio app itself).
|
|
231
231
|
|
|
232
232
|
```typescript
|
|
233
233
|
// client-side - only for same-origin apps
|
|
@@ -249,7 +249,7 @@ Triggers OAuth authentication flow for an MCP connection. **This runs client-sid
|
|
|
249
249
|
```typescript
|
|
250
250
|
// client-side - safe to use in browser
|
|
251
251
|
const result = await authenticateMcp({
|
|
252
|
-
meshUrl: "https://
|
|
252
|
+
meshUrl: "https://studio.example.com", // Required for external apps
|
|
253
253
|
connectionId: "conn_xxx", // Connection to authenticate
|
|
254
254
|
callbackUrl: "https://your-app.com/oauth/callback", // Your OAuth callback URL
|
|
255
255
|
timeout: 120000, // Timeout in ms (default: 120000)
|
|
@@ -274,9 +274,9 @@ Check if a connection is authenticated. Can be used on either server or client.
|
|
|
274
274
|
|
|
275
275
|
```typescript
|
|
276
276
|
const status = await isConnectionAuthenticated({
|
|
277
|
-
url: "https://
|
|
277
|
+
url: "https://studio.example.com/mcp/conn_xxx",
|
|
278
278
|
token: "bearer_token", // Optional
|
|
279
|
-
meshUrl: "https://
|
|
279
|
+
meshUrl: "https://studio.example.com", // For API calls
|
|
280
280
|
});
|
|
281
281
|
|
|
282
282
|
console.log(status.isAuthenticated); // boolean
|
|
@@ -286,7 +286,7 @@ console.log(status.hasOAuthToken); // boolean
|
|
|
286
286
|
|
|
287
287
|
### Collection Hooks - Client-Side (Same-Origin Only)
|
|
288
288
|
|
|
289
|
-
When using with `ProjectContextProvider`, you get access to collection hooks. **Only use when running on the same origin as
|
|
289
|
+
When using with `ProjectContextProvider`, you get access to collection hooks. **Only use when running on the same origin as Studio** (e.g., inside Studio app or plugins).
|
|
290
290
|
|
|
291
291
|
```typescript
|
|
292
292
|
// client-side - only for same-origin apps (inside Mesh)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@decocms/mesh-sdk",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.3",
|
|
4
4
|
"description": "SDK for building external apps that integrate with Mesh MCP servers",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -11,16 +11,19 @@
|
|
|
11
11
|
".": "./src/index.ts",
|
|
12
12
|
"./hooks": "./src/hooks/index.ts",
|
|
13
13
|
"./context": "./src/context/index.ts",
|
|
14
|
-
"./types": "./src/types/index.ts"
|
|
14
|
+
"./types": "./src/types/index.ts",
|
|
15
|
+
"./plugins": "./src/plugins/index.ts"
|
|
15
16
|
},
|
|
16
17
|
"dependencies": {
|
|
17
18
|
"@decocms/bindings": "^1.1.1",
|
|
18
|
-
"@
|
|
19
|
+
"@decocms/mcp-utils": "workspace:*",
|
|
20
|
+
"@modelcontextprotocol/sdk": "1.29.0",
|
|
19
21
|
"zod": "^4.0.0"
|
|
20
22
|
},
|
|
21
23
|
"peerDependencies": {
|
|
22
24
|
"@tanstack/react-query": ">=5.0.0",
|
|
23
25
|
"react": ">=18.0.0",
|
|
26
|
+
"react-dom": ">=18.0.0",
|
|
24
27
|
"sonner": ">=2.0.0"
|
|
25
28
|
},
|
|
26
29
|
"peerDependenciesMeta": {
|
|
@@ -41,7 +44,7 @@
|
|
|
41
44
|
],
|
|
42
45
|
"repository": {
|
|
43
46
|
"type": "git",
|
|
44
|
-
"url": "git+https://github.com/decocms/
|
|
47
|
+
"url": "git+https://github.com/decocms/studio.git",
|
|
45
48
|
"directory": "packages/mesh-sdk"
|
|
46
49
|
},
|
|
47
50
|
"license": "MIT",
|
package/src/context/index.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
export {
|
|
2
2
|
ProjectContextProvider,
|
|
3
3
|
useProjectContext,
|
|
4
|
+
useOrg,
|
|
5
|
+
useCurrentProject,
|
|
4
6
|
Locator,
|
|
5
|
-
ORG_ADMIN_PROJECT_SLUG,
|
|
6
7
|
type ProjectContextProviderProps,
|
|
7
8
|
type ProjectLocator,
|
|
8
9
|
type LocatorStructured,
|
|
10
|
+
type OrganizationData,
|
|
11
|
+
type ProjectData,
|
|
12
|
+
type ProjectUI,
|
|
9
13
|
} from "./project-context";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { createContext, useContext, type PropsWithChildren } from "react";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* A ProjectLocator is an ID-based string that identifies a project in an organization.
|
|
5
5
|
*
|
|
6
|
-
* format: <
|
|
6
|
+
* format: <orgId>/<projectId>
|
|
7
7
|
*/
|
|
8
8
|
export type ProjectLocator = `${string}/${string}`;
|
|
9
9
|
|
|
@@ -12,14 +12,8 @@ export type LocatorStructured = {
|
|
|
12
12
|
project: string;
|
|
13
13
|
};
|
|
14
14
|
|
|
15
|
-
export const ORG_ADMIN_PROJECT_SLUG = "org-admin";
|
|
16
|
-
|
|
17
15
|
export const Locator = {
|
|
18
16
|
from({ org, project }: LocatorStructured): ProjectLocator {
|
|
19
|
-
if (org?.includes("/") || project.includes("/")) {
|
|
20
|
-
throw new Error("Org or project cannot contain slashes");
|
|
21
|
-
}
|
|
22
|
-
|
|
23
17
|
return `${org}/${project}` as ProjectLocator;
|
|
24
18
|
},
|
|
25
19
|
parse(locator: ProjectLocator): LocatorStructured {
|
|
@@ -32,27 +26,58 @@ export const Locator = {
|
|
|
32
26
|
}
|
|
33
27
|
return { org, project };
|
|
34
28
|
},
|
|
35
|
-
isOrgAdminProject(locator: ProjectLocator): boolean {
|
|
36
|
-
return locator.split("/")[1] === ORG_ADMIN_PROJECT_SLUG;
|
|
37
|
-
},
|
|
38
|
-
adminProject(org: string): ProjectLocator {
|
|
39
|
-
return `${org}/${ORG_ADMIN_PROJECT_SLUG}`;
|
|
40
|
-
},
|
|
41
29
|
} as const;
|
|
42
30
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Project UI customization
|
|
33
|
+
*/
|
|
34
|
+
export interface ProjectUI {
|
|
35
|
+
banner: string | null;
|
|
36
|
+
bannerColor: string | null;
|
|
37
|
+
icon: string | null;
|
|
38
|
+
themeColor: string | null;
|
|
39
|
+
pinnedViews?: Array<{
|
|
40
|
+
connectionId: string;
|
|
41
|
+
toolName: string;
|
|
42
|
+
label: string;
|
|
43
|
+
icon: string | null;
|
|
44
|
+
}> | null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Organization data in context
|
|
49
|
+
*/
|
|
50
|
+
export interface OrganizationData {
|
|
51
|
+
id: string;
|
|
52
|
+
name: string;
|
|
53
|
+
slug: string;
|
|
54
|
+
logo: string | null;
|
|
55
|
+
}
|
|
55
56
|
|
|
57
|
+
/**
|
|
58
|
+
* Project data in context
|
|
59
|
+
* Includes full project info when loaded from storage
|
|
60
|
+
*/
|
|
61
|
+
export interface ProjectData {
|
|
62
|
+
/** Project ID */
|
|
63
|
+
id: string;
|
|
64
|
+
/** Organization ID (only available when loaded from storage) */
|
|
65
|
+
organizationId?: string;
|
|
66
|
+
/** Project slug */
|
|
67
|
+
slug: string;
|
|
68
|
+
/** Project display name */
|
|
69
|
+
name?: string;
|
|
70
|
+
/** Project description */
|
|
71
|
+
description?: string | null;
|
|
72
|
+
/** Enabled plugins */
|
|
73
|
+
enabledPlugins?: string[] | null;
|
|
74
|
+
/** UI customization */
|
|
75
|
+
ui?: ProjectUI | null;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
interface ProjectContextType {
|
|
79
|
+
org: OrganizationData;
|
|
80
|
+
project: ProjectData;
|
|
56
81
|
locator: ProjectLocator;
|
|
57
82
|
}
|
|
58
83
|
|
|
@@ -69,9 +94,23 @@ export const useProjectContext = () => {
|
|
|
69
94
|
return context;
|
|
70
95
|
};
|
|
71
96
|
|
|
97
|
+
/**
|
|
98
|
+
* Convenience hook to get organization data
|
|
99
|
+
*/
|
|
100
|
+
export const useOrg = () => {
|
|
101
|
+
return useProjectContext().org;
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Convenience hook to get current project data
|
|
106
|
+
*/
|
|
107
|
+
export const useCurrentProject = () => {
|
|
108
|
+
return useProjectContext().project;
|
|
109
|
+
};
|
|
110
|
+
|
|
72
111
|
export type ProjectContextProviderProps = {
|
|
73
|
-
org:
|
|
74
|
-
project:
|
|
112
|
+
org: OrganizationData;
|
|
113
|
+
project: ProjectData;
|
|
75
114
|
};
|
|
76
115
|
|
|
77
116
|
export const ProjectContextProvider = ({
|
|
@@ -79,7 +118,7 @@ export const ProjectContextProvider = ({
|
|
|
79
118
|
org,
|
|
80
119
|
project,
|
|
81
120
|
}: PropsWithChildren<ProjectContextProviderProps>) => {
|
|
82
|
-
const locator = Locator.from({ org: org.
|
|
121
|
+
const locator = Locator.from({ org: org.id, project: project.id });
|
|
83
122
|
|
|
84
123
|
const value = { org, project, locator };
|
|
85
124
|
|
package/src/hooks/index.ts
CHANGED
|
@@ -3,9 +3,14 @@ export {
|
|
|
3
3
|
useCollectionItem,
|
|
4
4
|
useCollectionList,
|
|
5
5
|
useCollectionActions,
|
|
6
|
+
buildWhereExpression,
|
|
7
|
+
buildOrderByExpression,
|
|
8
|
+
buildCollectionQueryKey,
|
|
9
|
+
EMPTY_COLLECTION_LIST_RESULT,
|
|
6
10
|
type CollectionEntity,
|
|
7
11
|
type CollectionFilter,
|
|
8
12
|
type UseCollectionListOptions,
|
|
13
|
+
type CollectionQueryKey,
|
|
9
14
|
} from "./use-collections";
|
|
10
15
|
|
|
11
16
|
// Connection hooks
|
|
@@ -21,8 +26,10 @@ export {
|
|
|
21
26
|
export {
|
|
22
27
|
createMCPClient,
|
|
23
28
|
useMCPClient,
|
|
29
|
+
useMCPClientOptional,
|
|
24
30
|
type CreateMcpClientOptions,
|
|
25
31
|
type UseMcpClientOptions,
|
|
32
|
+
type UseMcpClientOptionalOptions,
|
|
26
33
|
} from "./use-mcp-client";
|
|
27
34
|
|
|
28
35
|
// MCP tools hooks
|
|
@@ -67,7 +74,10 @@ export {
|
|
|
67
74
|
export {
|
|
68
75
|
useVirtualMCPs,
|
|
69
76
|
useVirtualMCP,
|
|
77
|
+
virtualMcpItemQueryOptions,
|
|
70
78
|
useVirtualMCPActions,
|
|
79
|
+
useVirtualMCPsLastUsed,
|
|
71
80
|
type VirtualMCPFilter,
|
|
72
81
|
type UseVirtualMCPsOptions,
|
|
82
|
+
type VirtualMCPLastUsed,
|
|
73
83
|
} from "./use-virtual-mcp";
|