@shuffleio/shuffle-mcps 0.0.37 → 0.0.38
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 +12 -12
- package/dist/{appsCache-H7SZLNQW.mjs → appsCache-32FX7WJE.mjs} +1 -1
- package/dist/{chunk-5ZQ2BL47.mjs → chunk-DCHKGFML.mjs} +77 -2
- package/dist/index.d.mts +9 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +2334 -1560
- package/dist/index.mjs +2289 -1617
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
|
|
3
|
-
<img src="https://security
|
|
3
|
+
<img src="https://shuffle.security/mcp/agent-icon.png" alt="Shuffle MCPs" width="96" />
|
|
4
4
|
|
|
5
5
|
# Shuffle MCPs
|
|
6
6
|
|
|
@@ -26,11 +26,11 @@ Turn 3,000+ SaaS tools into MCP servers your agents can use. One search, one cli
|
|
|
26
26
|
</tr>
|
|
27
27
|
<tr>
|
|
28
28
|
<td align="center" width="50%">
|
|
29
|
-
<img src="https://security
|
|
29
|
+
<img src="https://shuffle.security/mcp/search-preview.png" alt="Search 3,000+ integrations" width="380" style="border-radius: 12px;" />
|
|
30
30
|
<br/><sub><b>3. Search any of 3,000+ tools</b></sub>
|
|
31
31
|
</td>
|
|
32
32
|
<td align="center" width="50%">
|
|
33
|
-
<img src="https://security
|
|
33
|
+
<img src="https://shuffle.security/mcp/app-detail-preview.png" alt="Authenticate and use as MCP" width="380" style="border-radius: 12px;" />
|
|
34
34
|
<br/><sub><b>4. Authenticate — your agent uses it instantly</b></sub>
|
|
35
35
|
</td>
|
|
36
36
|
</tr>
|
|
@@ -38,7 +38,7 @@ Turn 3,000+ SaaS tools into MCP servers your agents can use. One search, one cli
|
|
|
38
38
|
|
|
39
39
|
|
|
40
40
|
|
|
41
|
-
> **See it live:** [security
|
|
41
|
+
> **See it live:** [shuffle.security/shuffle-mcp-demo](https://shuffle.security/shuffle-mcp-demo) — a fully working demo of every component in this package (inline search, search drawer, app detail drawer, auth, Try MCP, and Try individual actions). No login required.
|
|
42
42
|
|
|
43
43
|
> **No SDK required.** Once a tool is authenticated in Shuffle, it is live as an MCP server immediately — call it from any agent over plain HTTP. This npm package is the optional UI layer for embedding the search-and-connect flow inside your own product.
|
|
44
44
|
|
|
@@ -99,13 +99,13 @@ The library exports six React components — use one or all of them. They share
|
|
|
99
99
|
|
|
100
100
|
| Component | What it does | Live demo |
|
|
101
101
|
|---|---|---|
|
|
102
|
-
| [`<ShuffleMCP />`](#1-shufflemcp--inline-search) | Inline search box that merges Algolia's 3,000+ public app catalog with the current user's private apps | [/shuffle-mcp-demo §1](https://security
|
|
103
|
-
| [`<AppSearchDrawer />`](#2-appsearchdrawer--full-search-drawer) | Right-side drawer wrapping `<ShuffleMCP />` plus a "Your apps" status row. This is the exact "Add Ingestion Source" drawer used in production | [/shuffle-mcp-demo §2](https://security
|
|
104
|
-
| [`<AppDetailDrawer />`](#3-appdetaildrawer--single-app-config) | Right-side drawer for a single app: list/edit/test authentications and try the MCP `tools/call` endpoint inline | [/shuffle-mcp-demo §3](https://security
|
|
105
|
-
| [`<AgentUI />`](#4-agentui--start--debug-agents) | Standalone "What do you want to do?" hero prompt + live decision-by-decision debugger for `/api/v1/agent` runs. Drop-in replacement for the legacy Shuffle Core agent page | [/agents](https://security
|
|
106
|
-
| [`<AgentRunDrawer />`](#5-agentrundrawer--run-agent-side-panel) | Right-side drawer that hosts `<AgentUI />` in compact mode plus optional caller-provided **Permissions** and **Local LLM** tabs (slot-driven, no host context required) | [/shuffle-mcp-demo §1b](https://security
|
|
107
|
-
| [`<AgentActivityList />`](#6-agentactivitylist--past-executions) | Searchable, status-filterable list of past `/api/v1/agent` runs. Pair with `<AgentExecutionDrawer />` to inspect any row in the canonical Simple/Detailed view | [/shuffle-mcp-demo §8](https://security
|
|
108
|
-
| [`<AgentExecutionDrawer />`](#7-agentexecutiondrawer--inspect-one-run) | Right-side drawer that pre-loads a single `AgentRun` into `<AgentUI />` (no `authorization` token required) for read-only inspection | [/agents](https://security
|
|
102
|
+
| [`<ShuffleMCP />`](#1-shufflemcp--inline-search) | Inline search box that merges Algolia's 3,000+ public app catalog with the current user's private apps | [/shuffle-mcp-demo §1](https://shuffle.security/shuffle-mcp-demo) |
|
|
103
|
+
| [`<AppSearchDrawer />`](#2-appsearchdrawer--full-search-drawer) | Right-side drawer wrapping `<ShuffleMCP />` plus a "Your apps" status row. This is the exact "Add Ingestion Source" drawer used in production | [/shuffle-mcp-demo §2](https://shuffle.security/shuffle-mcp-demo) |
|
|
104
|
+
| [`<AppDetailDrawer />`](#3-appdetaildrawer--single-app-config) | Right-side drawer for a single app: list/edit/test authentications and try the MCP `tools/call` endpoint inline | [/shuffle-mcp-demo §3](https://shuffle.security/shuffle-mcp-demo) |
|
|
105
|
+
| [`<AgentUI />`](#4-agentui--start--debug-agents) | Standalone "What do you want to do?" hero prompt + live decision-by-decision debugger for `/api/v1/agent` runs. Drop-in replacement for the legacy Shuffle Core agent page | [/agents](https://shuffle.security/agents) |
|
|
106
|
+
| [`<AgentRunDrawer />`](#5-agentrundrawer--run-agent-side-panel) | Right-side drawer that hosts `<AgentUI />` in compact mode plus optional caller-provided **Permissions** and **Local LLM** tabs (slot-driven, no host context required) | [/shuffle-mcp-demo §1b](https://shuffle.security/shuffle-mcp-demo) |
|
|
107
|
+
| [`<AgentActivityList />`](#6-agentactivitylist--past-executions) | Searchable, status-filterable list of past `/api/v1/agent` runs. Pair with `<AgentExecutionDrawer />` to inspect any row in the canonical Simple/Detailed view | [/shuffle-mcp-demo §8](https://shuffle.security/shuffle-mcp-demo) |
|
|
108
|
+
| [`<AgentExecutionDrawer />`](#7-agentexecutiondrawer--inspect-one-run) | Right-side drawer that pre-loads a single `AgentRun` into `<AgentUI />` (no `authorization` token required) for read-only inspection | [/agents](https://shuffle.security/agents) |
|
|
109
109
|
|
|
110
110
|
### 1. `<ShuffleMCP />` — inline search
|
|
111
111
|
|
|
@@ -252,7 +252,7 @@ Useful props:
|
|
|
252
252
|
| `onRun` | `(info) => void` | Fires whenever a run finishes (success or failure) |
|
|
253
253
|
| `className` / `sx` / `contentSx` | `string` / `SxProps` | Style overrides for the root container and inner content column |
|
|
254
254
|
|
|
255
|
-
Reference page in production: [`src/pages/dashboard/AgentsPage.tsx`](../pages/dashboard/AgentsPage.tsx) (mounted at [`/agents`](https://security
|
|
255
|
+
Reference page in production: [`src/pages/dashboard/AgentsPage.tsx`](../pages/dashboard/AgentsPage.tsx) (mounted at [`/agents`](https://shuffle.security/agents)).
|
|
256
256
|
|
|
257
257
|
### 5. `<AgentRunDrawer />` — Run Agent side panel
|
|
258
258
|
|
|
@@ -175,11 +175,65 @@ var installFetchBreaker = () => {
|
|
|
175
175
|
});
|
|
176
176
|
};
|
|
177
177
|
|
|
178
|
+
// ../lib/platform.ts
|
|
179
|
+
var getPlatform = () => {
|
|
180
|
+
if (typeof window === "undefined") return "web";
|
|
181
|
+
const cap = window.Capacitor;
|
|
182
|
+
if (cap?.isNativePlatform && cap.isNativePlatform()) {
|
|
183
|
+
const platform = typeof cap.getPlatform === "function" ? cap.getPlatform() : "";
|
|
184
|
+
if (platform === "ios") return "ios";
|
|
185
|
+
if (platform === "android") return "android";
|
|
186
|
+
}
|
|
187
|
+
const ua = window.navigator?.userAgent || "";
|
|
188
|
+
if (/iPad|iPhone|iPod/.test(ua) || navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1) {
|
|
189
|
+
return "ios";
|
|
190
|
+
}
|
|
191
|
+
if (/android/i.test(ua)) {
|
|
192
|
+
return "android";
|
|
193
|
+
}
|
|
194
|
+
return "web";
|
|
195
|
+
};
|
|
196
|
+
var isCapacitorNative = () => {
|
|
197
|
+
if (typeof window === "undefined") return false;
|
|
198
|
+
const cap = window.Capacitor;
|
|
199
|
+
return Boolean(cap?.isNativePlatform && cap.isNativePlatform());
|
|
200
|
+
};
|
|
201
|
+
var isIosWebView = () => {
|
|
202
|
+
if (typeof window === "undefined") return false;
|
|
203
|
+
const cap = window.Capacitor;
|
|
204
|
+
if (cap?.isNativePlatform && cap.isNativePlatform()) {
|
|
205
|
+
return typeof cap.getPlatform === "function" ? cap.getPlatform() === "ios" : true;
|
|
206
|
+
}
|
|
207
|
+
const ua = window.navigator?.userAgent || "";
|
|
208
|
+
const isIosDevice = /iPad|iPhone|iPod/.test(ua) || navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1;
|
|
209
|
+
const isStandalonePwa = window.navigator.standalone === true || typeof window.matchMedia === "function" && window.matchMedia("(display-mode: standalone)").matches;
|
|
210
|
+
const isEmbeddedWebview = /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(ua);
|
|
211
|
+
return isIosDevice && (isStandalonePwa || isEmbeddedWebview);
|
|
212
|
+
};
|
|
213
|
+
var isAndroidWebView = () => {
|
|
214
|
+
if (typeof window === "undefined") return false;
|
|
215
|
+
const cap = window.Capacitor;
|
|
216
|
+
if (cap?.isNativePlatform && cap.isNativePlatform()) {
|
|
217
|
+
return typeof cap.getPlatform === "function" ? cap.getPlatform() === "android" : false;
|
|
218
|
+
}
|
|
219
|
+
const ua = window.navigator?.userAgent || "";
|
|
220
|
+
const isAndroidDevice = /android/i.test(ua);
|
|
221
|
+
const isStandalone = typeof window.matchMedia === "function" && window.matchMedia("(display-mode: standalone)").matches;
|
|
222
|
+
const isWebview = /;\s*wv|Version\/[\d.]+/i.test(ua) && isAndroidDevice;
|
|
223
|
+
return isAndroidDevice && (isStandalone || isWebview);
|
|
224
|
+
};
|
|
225
|
+
if (typeof window !== "undefined") {
|
|
226
|
+
window.isCapacitorNative = isCapacitorNative;
|
|
227
|
+
window.isIosWebView = isIosWebView;
|
|
228
|
+
window.isAndroidWebView = isAndroidWebView;
|
|
229
|
+
window.getPlatform = getPlatform;
|
|
230
|
+
}
|
|
231
|
+
|
|
178
232
|
// api.ts
|
|
179
233
|
installFetchBreaker();
|
|
180
234
|
var DEV_BACKEND = "https://tunnel.schemaless.org";
|
|
181
235
|
var PROD_BACKEND = "https://shuffler.io";
|
|
182
|
-
var CLOUD_DOMAINS = ["security.shuffler.io", "shutdown.no"];
|
|
236
|
+
var CLOUD_DOMAINS = ["shuffle.security", "www.shuffle.security", "security.shuffler.io", "shutdown.no", "www.shutdown.no"];
|
|
183
237
|
var getEnvVar = (key) => {
|
|
184
238
|
try {
|
|
185
239
|
const meta = new Function("try { return import.meta } catch { return undefined }")();
|
|
@@ -194,6 +248,7 @@ var isDevEnvironment = () => {
|
|
|
194
248
|
return hostname.includes("lovableproject.com") || hostname.includes("id-preview--") || hostname.endsWith(".lovable.app") || hostname.endsWith(".lovable.dev");
|
|
195
249
|
};
|
|
196
250
|
var isCloudDomain = () => {
|
|
251
|
+
if (isCapacitorNative()) return true;
|
|
197
252
|
const hostname = typeof window !== "undefined" ? window.location.hostname : "";
|
|
198
253
|
return CLOUD_DOMAINS.includes(hostname);
|
|
199
254
|
};
|
|
@@ -205,6 +260,7 @@ var getDefaultBaseUrl = () => {
|
|
|
205
260
|
return envUrl;
|
|
206
261
|
}
|
|
207
262
|
if (isDevEnvironment()) return DEV_BACKEND;
|
|
263
|
+
if (isCapacitorNative()) return PROD_BACKEND;
|
|
208
264
|
if (isCloudDomain()) return PROD_BACKEND;
|
|
209
265
|
if (typeof window !== "undefined") {
|
|
210
266
|
return window.location.origin;
|
|
@@ -225,8 +281,17 @@ var readCachedRegion = () => {
|
|
|
225
281
|
};
|
|
226
282
|
var cached = readCachedRegion();
|
|
227
283
|
var _regionUrl = cached.url;
|
|
284
|
+
var readCachedCustomHost = () => {
|
|
285
|
+
if (typeof window === "undefined") return null;
|
|
286
|
+
try {
|
|
287
|
+
const raw = localStorage.getItem("shuffle_custom_host_url");
|
|
288
|
+
return raw ? raw.trim().replace(/\/+$/, "") : null;
|
|
289
|
+
} catch {
|
|
290
|
+
return null;
|
|
291
|
+
}
|
|
292
|
+
};
|
|
228
293
|
var _trackedOrgId = cached.orgId;
|
|
229
|
-
var _hostBaseUrl =
|
|
294
|
+
var _hostBaseUrl = readCachedCustomHost();
|
|
230
295
|
var REGION_EVENT = "shuffle:region-url";
|
|
231
296
|
var _lastBroadcastUrl = cached.url;
|
|
232
297
|
var persistRegion = (url, orgId) => {
|
|
@@ -375,6 +440,14 @@ var getAuthHeader = (overrideOrgId) => {
|
|
|
375
440
|
}
|
|
376
441
|
return headers;
|
|
377
442
|
};
|
|
443
|
+
var hasShuffleAuth = () => {
|
|
444
|
+
try {
|
|
445
|
+
if (API_CONFIG.apiKey) return true;
|
|
446
|
+
return !!(localStorage.getItem("session_token") || localStorage.getItem("shuffle_user_info"));
|
|
447
|
+
} catch {
|
|
448
|
+
return false;
|
|
449
|
+
}
|
|
450
|
+
};
|
|
378
451
|
|
|
379
452
|
// appsCache.ts
|
|
380
453
|
var TTL_MS = 3e4;
|
|
@@ -431,6 +504,7 @@ var fetchAppsViaApiConfig = () => {
|
|
|
431
504
|
export {
|
|
432
505
|
registerProtectedOrigin,
|
|
433
506
|
installFetchBreaker,
|
|
507
|
+
isCapacitorNative,
|
|
434
508
|
isCloudDomain,
|
|
435
509
|
isCloud,
|
|
436
510
|
isOnprem,
|
|
@@ -444,6 +518,7 @@ export {
|
|
|
444
518
|
getApiUrl,
|
|
445
519
|
shuffleFetch,
|
|
446
520
|
getAuthHeader,
|
|
521
|
+
hasShuffleAuth,
|
|
447
522
|
fetchApps,
|
|
448
523
|
invalidateAppsCache,
|
|
449
524
|
fetchAppsViaApiConfig
|
package/dist/index.d.mts
CHANGED
|
@@ -359,6 +359,11 @@ interface AgentPreset {
|
|
|
359
359
|
id?: string;
|
|
360
360
|
icon?: string;
|
|
361
361
|
}>;
|
|
362
|
+
/**
|
|
363
|
+
* Tools this skill cannot run without. They are always selected and cannot
|
|
364
|
+
* be removed from the Tools chip row while the skill is active.
|
|
365
|
+
*/
|
|
366
|
+
requiredApps?: string[];
|
|
362
367
|
}
|
|
363
368
|
declare const AGENT_PRESETS: AgentPreset[];
|
|
364
369
|
interface AgentPresetsProps {
|
|
@@ -789,6 +794,8 @@ interface AgentActivityResponse {
|
|
|
789
794
|
interface AgentActivityParams {
|
|
790
795
|
cursor?: string;
|
|
791
796
|
limit?: number;
|
|
797
|
+
/** Optional page size sent as the `?top` query parameter. */
|
|
798
|
+
top?: number;
|
|
792
799
|
status?: string;
|
|
793
800
|
startTime?: string;
|
|
794
801
|
endTime?: string;
|
|
@@ -870,6 +877,8 @@ interface AgentActivityListProps extends ShuffleHostProps {
|
|
|
870
877
|
showStatusChips?: boolean;
|
|
871
878
|
/** Page size. Default: 50. */
|
|
872
879
|
limit?: number;
|
|
880
|
+
/** Optional page size sent as the `?top` query parameter. */
|
|
881
|
+
top?: number;
|
|
873
882
|
/** Empty-state heading. */
|
|
874
883
|
emptyTitle?: string;
|
|
875
884
|
/** Empty-state subtitle. */
|
package/dist/index.d.ts
CHANGED
|
@@ -359,6 +359,11 @@ interface AgentPreset {
|
|
|
359
359
|
id?: string;
|
|
360
360
|
icon?: string;
|
|
361
361
|
}>;
|
|
362
|
+
/**
|
|
363
|
+
* Tools this skill cannot run without. They are always selected and cannot
|
|
364
|
+
* be removed from the Tools chip row while the skill is active.
|
|
365
|
+
*/
|
|
366
|
+
requiredApps?: string[];
|
|
362
367
|
}
|
|
363
368
|
declare const AGENT_PRESETS: AgentPreset[];
|
|
364
369
|
interface AgentPresetsProps {
|
|
@@ -789,6 +794,8 @@ interface AgentActivityResponse {
|
|
|
789
794
|
interface AgentActivityParams {
|
|
790
795
|
cursor?: string;
|
|
791
796
|
limit?: number;
|
|
797
|
+
/** Optional page size sent as the `?top` query parameter. */
|
|
798
|
+
top?: number;
|
|
792
799
|
status?: string;
|
|
793
800
|
startTime?: string;
|
|
794
801
|
endTime?: string;
|
|
@@ -870,6 +877,8 @@ interface AgentActivityListProps extends ShuffleHostProps {
|
|
|
870
877
|
showStatusChips?: boolean;
|
|
871
878
|
/** Page size. Default: 50. */
|
|
872
879
|
limit?: number;
|
|
880
|
+
/** Optional page size sent as the `?top` query parameter. */
|
|
881
|
+
top?: number;
|
|
873
882
|
/** Empty-state heading. */
|
|
874
883
|
emptyTitle?: string;
|
|
875
884
|
/** Empty-state subtitle. */
|