@withone/mcp 1.0.0 → 1.1.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 +31 -8
- package/build/client.js +39 -0
- package/build/helpers.js +22 -0
- package/build/index.js +8 -2
- package/build/schemas.js +21 -3
- package/package.json +1 -1
- package/build/client.d.ts +0 -102
- package/build/helpers.d.ts +0 -53
- package/build/index.d.ts +0 -10
- package/build/schemas.d.ts +0 -285
- package/build/server.d.ts +0 -27
- package/build/server.js +0 -215
- package/build/types.d.ts +0 -182
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<img src="https://assets.withone.ai/banners/mcp.png?v=
|
|
1
|
+
<img src="https://assets.withone.ai/banners/mcp.png?v=3" alt="One MCP — Connect your agents to every app through a single MCP." style="border-radius: 5px;">
|
|
2
2
|
|
|
3
3
|
<h3 align="center">One MCP Server</h3>
|
|
4
4
|
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
<a href="https://npmjs.com/package/@withone/mcp"><img src="https://img.shields.io/npm/v/%40withone%2Fmcp" alt="npm version"></a>
|
|
21
21
|
</p>
|
|
22
22
|
|
|
23
|
-
Connect your AI agents to
|
|
23
|
+
Connect your AI agents to 500+ apps through a single [MCP](https://modelcontextprotocol.io) server. Search for actions, read documentation, and execute API calls across platforms, without having to manage OAuth tokens or API keys.
|
|
24
24
|
|
|
25
25
|
```bash
|
|
26
26
|
npm install -g @withone/cli
|
|
@@ -31,7 +31,7 @@ That's it. The [One CLI](https://www.npmjs.com/package/@withone/cli) will prompt
|
|
|
31
31
|
|
|
32
32
|
## Capabilities
|
|
33
33
|
|
|
34
|
-
- **
|
|
34
|
+
- **500+ platforms.** Gmail, Slack, Shopify, HubSpot, Stripe, Linear, QuickBooks, and [more](https://app.withone.ai/tools).
|
|
35
35
|
- **Natural language execution.** "read my last gmail email", "send a message to #general on Slack"
|
|
36
36
|
- **Code generation.** "build a form to send emails using Gmail", "create a dashboard that lists my Linear projects"
|
|
37
37
|
- **No tool bloat.** Only 4 tools exposed regardless of how many platforms or actions you connect. Actions are search-based, so your agent's context window stays clean.
|
|
@@ -60,11 +60,30 @@ The server exposes four MCP tools:
|
|
|
60
60
|
|
|
61
61
|
| Tool | Description |
|
|
62
62
|
|------|-------------|
|
|
63
|
-
| `list_one_integrations` | List available platforms and active connections |
|
|
63
|
+
| `list_one_integrations` | List available platforms and active connections, each with the `access` it confers (full, methods, or specific actions) |
|
|
64
64
|
| `search_one_platform_actions` | Search for actions on a specific platform |
|
|
65
65
|
| `get_one_action_knowledge` | Get detailed documentation for an action |
|
|
66
66
|
| `execute_one_action` | Execute an API action on a connected platform |
|
|
67
67
|
|
|
68
|
+
## Remote MCP Server
|
|
69
|
+
|
|
70
|
+
Prefer not to run anything locally? One hosts a remote MCP server at **`https://mcp.withone.ai/mcp`**. Point any MCP client that supports remote (HTTP) servers at that URL and authenticate with One via OAuth. There's no `npm install` and no `ONE_SECRET` to manage. You approve access in One's consent screen, where you can scope exactly which connections, actions, and permission levels the agent gets. Those choices are surfaced back to the agent through each connection's `access` field, so it knows what it can run without searching.
|
|
71
|
+
|
|
72
|
+
Add it to your client's MCP configuration. The endpoint speaks the Streamable HTTP transport:
|
|
73
|
+
|
|
74
|
+
```json
|
|
75
|
+
{
|
|
76
|
+
"mcpServers": {
|
|
77
|
+
"one": {
|
|
78
|
+
"type": "http",
|
|
79
|
+
"url": "https://mcp.withone.ai/mcp"
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Some clients omit `type` and take the URL alone; UI-based clients (custom connectors) just need the URL itself. On first connect, your client opens a browser to authenticate and authorize with One. After that, the same four tools are available.
|
|
86
|
+
|
|
68
87
|
## Manual Installation
|
|
69
88
|
|
|
70
89
|
If you prefer to configure the server manually instead of using `one init`, install the package directly:
|
|
@@ -115,6 +134,14 @@ ONE_KNOWLEDGE_AGENT=true
|
|
|
115
134
|
|
|
116
135
|
All defaults preserve current behavior. If no access control env vars are set, the server starts with full access and all tools available.
|
|
117
136
|
|
|
137
|
+
Whatever you configure here is surfaced back to the agent: `list_one_integrations` stamps each connection with an `access` field so the agent knows up front what it can run there, without spending a turn searching. It is one of:
|
|
138
|
+
|
|
139
|
+
| `access` | When |
|
|
140
|
+
|---|---|
|
|
141
|
+
| `{ "policy": "full" }` | No action allowlist and `ONE_PERMISSIONS=admin` — every action is runnable. |
|
|
142
|
+
| `{ "policy": "methods", "methods": ["GET", ...] }` | No action allowlist, but `ONE_PERMISSIONS` is `read`/`write` — only these HTTP methods are runnable. |
|
|
143
|
+
| `{ "policy": "actions", "actions": [{ "actionId", "title", "method" }] }` | `ONE_ACTION_IDS` is set — exactly these actions (the ones on that connection's platform) are runnable, so no search is needed. |
|
|
144
|
+
|
|
118
145
|
## Manual Configuration
|
|
119
146
|
|
|
120
147
|
If you used `one init`, the configuration below is already done for you. These examples are for reference or manual setups.
|
|
@@ -146,10 +173,6 @@ Add the following to your MCP config:
|
|
|
146
173
|
}
|
|
147
174
|
```
|
|
148
175
|
|
|
149
|
-
### Remote MCP Server
|
|
150
|
-
|
|
151
|
-
The remote MCP server is available at [https://mcp.withone.ai](https://mcp.withone.ai).
|
|
152
|
-
|
|
153
176
|
### Docker
|
|
154
177
|
|
|
155
178
|
```bash
|
package/build/client.js
CHANGED
|
@@ -21,6 +21,7 @@ export class OneClient {
|
|
|
21
21
|
connections = [];
|
|
22
22
|
connectors = [];
|
|
23
23
|
isInitialized = false;
|
|
24
|
+
allowedActionsCache = null;
|
|
24
25
|
constructor(optionsOrSecret, baseUrl = "https://api.withone.ai") {
|
|
25
26
|
if (typeof optionsOrSecret === 'string') {
|
|
26
27
|
// Legacy constructor: (secret, baseUrl)
|
|
@@ -222,6 +223,44 @@ export class OneClient {
|
|
|
222
223
|
throw error;
|
|
223
224
|
}
|
|
224
225
|
}
|
|
226
|
+
/**
|
|
227
|
+
* Resolves an allowlist of action ids to their metadata (title, method, and
|
|
228
|
+
* owning platform), so `list_one_integrations` can report each connection's
|
|
229
|
+
* enumerated actions. `"*"` (unrestricted) resolves to an empty list — there
|
|
230
|
+
* is no allowlist to enumerate. Ids that fail to resolve or carry no platform
|
|
231
|
+
* are skipped rather than failing the whole call. The result is cached: the
|
|
232
|
+
* allowlist is fixed for the process lifetime.
|
|
233
|
+
* @param actionIds - The configured `ONE_ACTION_IDS` allowlist
|
|
234
|
+
* @returns Resolved metadata for every enumerable allowed action
|
|
235
|
+
*/
|
|
236
|
+
async resolveAllowedActions(actionIds) {
|
|
237
|
+
if (actionIds.includes("*")) {
|
|
238
|
+
return [];
|
|
239
|
+
}
|
|
240
|
+
if (this.allowedActionsCache) {
|
|
241
|
+
return this.allowedActionsCache;
|
|
242
|
+
}
|
|
243
|
+
const resolved = await Promise.all(actionIds.map(async (actionId) => {
|
|
244
|
+
try {
|
|
245
|
+
const action = await this.getActionDetails(actionId);
|
|
246
|
+
if (!action.connectionPlatform) {
|
|
247
|
+
return null;
|
|
248
|
+
}
|
|
249
|
+
return {
|
|
250
|
+
actionId,
|
|
251
|
+
title: action.title,
|
|
252
|
+
method: action.method,
|
|
253
|
+
platform: action.connectionPlatform
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
catch (error) {
|
|
257
|
+
console.error(`Failed to resolve allowed action ${actionId}:`, error);
|
|
258
|
+
return null;
|
|
259
|
+
}
|
|
260
|
+
}));
|
|
261
|
+
this.allowedActionsCache = resolved.filter((a) => a !== null);
|
|
262
|
+
return this.allowedActionsCache;
|
|
263
|
+
}
|
|
225
264
|
/**
|
|
226
265
|
* Executes a passthrough request to a third-party API through One
|
|
227
266
|
* @param args - The execution arguments containing all request details
|
package/build/helpers.js
CHANGED
|
@@ -148,3 +148,25 @@ export function isMethodAllowed(method, permissions) {
|
|
|
148
148
|
export function isActionAllowed(actionId, allowedActionIds) {
|
|
149
149
|
return allowedActionIds.includes("*") || allowedActionIds.includes(actionId);
|
|
150
150
|
}
|
|
151
|
+
/**
|
|
152
|
+
* What the current access config lets the agent run on a connection of
|
|
153
|
+
* `platform`, so `list_one_integrations` can surface it without a search.
|
|
154
|
+
* Mirrors the One core `resolve_connection_access` precedence:
|
|
155
|
+
* an action allowlist wins (report the enumerated actions on this platform),
|
|
156
|
+
* else a non-`admin` permission level reports its method set, else full.
|
|
157
|
+
* `resolvedAllowed` is the allowlisted actions already resolved to their
|
|
158
|
+
* metadata and method-filtered by the permission level.
|
|
159
|
+
*/
|
|
160
|
+
export function computeConnectionAccess(platform, permissions, allowedActionIds, resolvedAllowed) {
|
|
161
|
+
if (!allowedActionIds.includes("*")) {
|
|
162
|
+
const actions = resolvedAllowed
|
|
163
|
+
.filter(a => a.platform === platform)
|
|
164
|
+
.map(({ actionId, title, method }) => ({ actionId, title, method }));
|
|
165
|
+
return { policy: "actions", actions };
|
|
166
|
+
}
|
|
167
|
+
const methods = PERMISSION_METHODS[permissions];
|
|
168
|
+
if (methods !== null) {
|
|
169
|
+
return { policy: "methods", methods };
|
|
170
|
+
}
|
|
171
|
+
return { policy: "full" };
|
|
172
|
+
}
|
package/build/index.js
CHANGED
|
@@ -11,7 +11,7 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
|
11
11
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
12
12
|
import { ErrorCode, McpError, } from '@modelcontextprotocol/sdk/types.js';
|
|
13
13
|
import { OneClient } from './client.js';
|
|
14
|
-
import { buildActionKnowledgeWithGuidance, filterByPermissions, isMethodAllowed, isActionAllowed, } from './helpers.js';
|
|
14
|
+
import { buildActionKnowledgeWithGuidance, filterByPermissions, isMethodAllowed, isActionAllowed, computeConnectionAccess, } from './helpers.js';
|
|
15
15
|
import { listOneIntegrationsToolConfig, searchOnePlatformActionsToolConfig, getOneActionKnowledgeToolConfig, executeOneActionToolConfig } from './schemas.js';
|
|
16
16
|
const SERVER_NAME = "one-mcp-server";
|
|
17
17
|
const SERVER_VERSION = "1.0.0";
|
|
@@ -97,11 +97,17 @@ async function handleGetIntegrations(args) {
|
|
|
97
97
|
const connectedPlatforms = new Set(activeConnections.map(conn => conn.platform));
|
|
98
98
|
activePlatforms = activePlatforms.filter(def => connectedPlatforms.has(def.platform));
|
|
99
99
|
}
|
|
100
|
+
// Resolve the action allowlist to per-platform metadata (method-filtered by
|
|
101
|
+
// the permission level) once, so each connection can report the exact
|
|
102
|
+
// actions it may run. Only needed when an action allowlist is set.
|
|
103
|
+
const resolvedAllowed = (await oneClient.resolveAllowedActions(ONE_ACTION_IDS))
|
|
104
|
+
.filter(action => isMethodAllowed(action.method, ONE_PERMISSIONS));
|
|
100
105
|
const structuredResponse = {
|
|
101
106
|
connections: activeConnections.map(conn => ({
|
|
102
107
|
platform: conn.platform,
|
|
103
108
|
key: conn.key,
|
|
104
|
-
tags: conn.tags ?? []
|
|
109
|
+
tags: conn.tags ?? [],
|
|
110
|
+
access: computeConnectionAccess(conn.platform, ONE_PERMISSIONS, ONE_ACTION_IDS, resolvedAllowed)
|
|
105
111
|
})),
|
|
106
112
|
availablePlatforms: activePlatforms.map(def => ({
|
|
107
113
|
platform: def.platform,
|
package/build/schemas.js
CHANGED
|
@@ -44,12 +44,30 @@ export const executeOneActionInputSchema = {
|
|
|
44
44
|
/**
|
|
45
45
|
* Output schemas for list_one_integrations tool
|
|
46
46
|
*/
|
|
47
|
+
const connectionAccessSchema = z.union([
|
|
48
|
+
z.object({
|
|
49
|
+
policy: z.literal("full")
|
|
50
|
+
}),
|
|
51
|
+
z.object({
|
|
52
|
+
policy: z.literal("methods"),
|
|
53
|
+
methods: z.array(z.string())
|
|
54
|
+
}),
|
|
55
|
+
z.object({
|
|
56
|
+
policy: z.literal("actions"),
|
|
57
|
+
actions: z.array(z.object({
|
|
58
|
+
actionId: z.string(),
|
|
59
|
+
title: z.string(),
|
|
60
|
+
method: z.string()
|
|
61
|
+
}))
|
|
62
|
+
})
|
|
63
|
+
]).describe("What the access config lets you run on this connection: `full`, an allowed `methods` set, or a specific `actions` list. When `actions`, those are exactly what may run, so no search is needed.");
|
|
47
64
|
export const listOneIntegrationsOutputSchema = {
|
|
48
65
|
connections: z.array(z.object({
|
|
49
66
|
platform: z.string(),
|
|
50
67
|
key: z.string(),
|
|
51
|
-
tags: z.array(z.string())
|
|
52
|
-
|
|
68
|
+
tags: z.array(z.string()),
|
|
69
|
+
access: connectionAccessSchema
|
|
70
|
+
})).describe("Array of user's active connections, each with the access the current config confers"),
|
|
53
71
|
availablePlatforms: z.array(z.object({
|
|
54
72
|
platform: z.string(),
|
|
55
73
|
name: z.string(),
|
|
@@ -81,7 +99,7 @@ export const searchOnePlatformActionsOutputSchema = {
|
|
|
81
99
|
*/
|
|
82
100
|
export const listOneIntegrationsToolConfig = {
|
|
83
101
|
title: "List One Integrations",
|
|
84
|
-
description: "List all available One integrations and platforms. ALWAYS call this tool first in any workflow to discover what platforms and connections are available. This returns the connections that the user has and all available One platforms in kebab-case format (e.g., 'ship-station', 'shopify') which you'll need for subsequent tool calls.",
|
|
102
|
+
description: "List all available One integrations and platforms. ALWAYS call this tool first in any workflow to discover what platforms and connections are available. This returns the connections that the user has and all available One platforms in kebab-case format (e.g., 'ship-station', 'shopify') which you'll need for subsequent tool calls. Each connection carries an `access` field describing what you may run on it: `full`, a set of allowed HTTP `methods`, or a specific list of `actions` (each with `actionId`, `title`, `method`). When a connection is action-scoped, its `actions` are exactly what may run, so you need not search.",
|
|
85
103
|
inputSchema: listOneIntegrationsInputSchema,
|
|
86
104
|
outputSchema: listOneIntegrationsOutputSchema
|
|
87
105
|
};
|
package/package.json
CHANGED
package/build/client.d.ts
DELETED
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pica API Client
|
|
3
|
-
*
|
|
4
|
-
* This module provides a TypeScript client for interacting with the Pica API.
|
|
5
|
-
*
|
|
6
|
-
* @fileoverview Pica API client with authentication and data management
|
|
7
|
-
* @author Pica
|
|
8
|
-
*/
|
|
9
|
-
import { Connection, ConnectionDefinition, AvailableAction, ActionDetails, GetPicaActionKnowledgeResponse, ExecutePicaActionArgs, ExecutePassthroughResponse } from './types.js';
|
|
10
|
-
export type IdentityType = 'user' | 'team' | 'organization' | 'project';
|
|
11
|
-
export interface PicaClientOptions {
|
|
12
|
-
secret: string;
|
|
13
|
-
baseUrl?: string;
|
|
14
|
-
identity?: string;
|
|
15
|
-
identityType?: IdentityType;
|
|
16
|
-
connectionKeys?: string[];
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Client for interacting with the Pica API
|
|
20
|
-
*/
|
|
21
|
-
export declare class PicaClient {
|
|
22
|
-
private readonly secret;
|
|
23
|
-
private readonly baseUrl;
|
|
24
|
-
private readonly identity?;
|
|
25
|
-
private readonly identityType?;
|
|
26
|
-
private readonly connectionKeys?;
|
|
27
|
-
private connections;
|
|
28
|
-
private connectors;
|
|
29
|
-
private isInitialized;
|
|
30
|
-
constructor(options: PicaClientOptions);
|
|
31
|
-
constructor(secret: string, baseUrl?: string);
|
|
32
|
-
/**
|
|
33
|
-
* Initializes the client by fetching connections and available connectors
|
|
34
|
-
* @throws {Error} If initialization fails completely
|
|
35
|
-
*/
|
|
36
|
-
initialize(): Promise<void>;
|
|
37
|
-
/**
|
|
38
|
-
* Generates standard headers for API requests
|
|
39
|
-
*/
|
|
40
|
-
generateHeaders(): Record<string, string>;
|
|
41
|
-
/**
|
|
42
|
-
* Fetches user connections from the API
|
|
43
|
-
*/
|
|
44
|
-
private fetchConnections;
|
|
45
|
-
/**
|
|
46
|
-
* Fetches available connection definitions from the API
|
|
47
|
-
*/
|
|
48
|
-
private fetchConnectionDefinitions;
|
|
49
|
-
/**
|
|
50
|
-
* Searches for actions on a specific platform using a query
|
|
51
|
-
* @param platform - The platform name to search actions for
|
|
52
|
-
* @param query - The search query to find relevant actions
|
|
53
|
-
* @param agentType - The type of agent context (execute or knowledge)
|
|
54
|
-
* @returns Array of top 5 most relevant actions for the platform
|
|
55
|
-
* @throws {Error} If platform or query is not provided or API request fails
|
|
56
|
-
*/
|
|
57
|
-
searchAvailableActions(platform: string, query: string, agentType?: "execute" | "knowledge"): Promise<AvailableAction[]>;
|
|
58
|
-
/**
|
|
59
|
-
* Gets full action details by ID
|
|
60
|
-
* @param actionId - The action ID to get details for
|
|
61
|
-
* @returns The full action object
|
|
62
|
-
* @throws {Error} If action ID is not provided or API request fails
|
|
63
|
-
*/
|
|
64
|
-
getActionDetails(actionId: string): Promise<ActionDetails>;
|
|
65
|
-
/**
|
|
66
|
-
* Gets knowledge for a specific action by ID
|
|
67
|
-
* @param actionId - The action ID to get knowledge for
|
|
68
|
-
* @returns The knowledge string for the action
|
|
69
|
-
* @throws {Error} If action ID is not provided or API request fails
|
|
70
|
-
*/
|
|
71
|
-
getActionKnowledge(actionId: string): Promise<GetPicaActionKnowledgeResponse>;
|
|
72
|
-
/**
|
|
73
|
-
* Executes a passthrough request to a third-party API through Pica
|
|
74
|
-
* @param args - The execution arguments containing all request details
|
|
75
|
-
* @returns Object containing sanitized request config and response data
|
|
76
|
-
* @throws {Error} If the request fails
|
|
77
|
-
*/
|
|
78
|
-
executePassthroughRequest(args: ExecutePicaActionArgs, preloadedAction?: ActionDetails): Promise<ExecutePassthroughResponse>;
|
|
79
|
-
/**
|
|
80
|
-
* Gets the base URL for the Pica API
|
|
81
|
-
* @returns The base URL for the Pica API
|
|
82
|
-
*/
|
|
83
|
-
getBaseUrl(): string;
|
|
84
|
-
/**
|
|
85
|
-
* Gets the current user's connections
|
|
86
|
-
* @returns Array of user connections
|
|
87
|
-
*/
|
|
88
|
-
getUserConnections(): Connection[];
|
|
89
|
-
/**
|
|
90
|
-
* Gets available connectors/platforms
|
|
91
|
-
* @returns Array of available connection definitions
|
|
92
|
-
*/
|
|
93
|
-
getAvailableConnectors(): ConnectionDefinition[];
|
|
94
|
-
/**
|
|
95
|
-
* Checks if the client has been initialized
|
|
96
|
-
*/
|
|
97
|
-
isClientInitialized(): boolean;
|
|
98
|
-
/**
|
|
99
|
-
* Refreshes connections and connectors data
|
|
100
|
-
*/
|
|
101
|
-
refresh(): Promise<void>;
|
|
102
|
-
}
|
package/build/helpers.d.ts
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Utility Helper Functions
|
|
3
|
-
*
|
|
4
|
-
* This module contains reusable utility functions used throughout the Pica MCP server.
|
|
5
|
-
*
|
|
6
|
-
* @fileoverview Utility functions for data processing and API interactions
|
|
7
|
-
* @author Pica
|
|
8
|
-
*/
|
|
9
|
-
import { PermissionLevel } from './types.js';
|
|
10
|
-
/**
|
|
11
|
-
* Paginates through API results by repeatedly calling a fetch function until all data is retrieved.
|
|
12
|
-
* @param fetchFn - Function that fetches paginated data, takes skip and limit parameters
|
|
13
|
-
* @param limit - Maximum number of items to fetch per request (default: 100)
|
|
14
|
-
* @returns Promise that resolves to an array of all paginated results
|
|
15
|
-
*/
|
|
16
|
-
export declare function paginateResults<T>(fetchFn: (skip: number, limit: number) => Promise<{
|
|
17
|
-
rows: T[];
|
|
18
|
-
total: number;
|
|
19
|
-
skip: number;
|
|
20
|
-
limit: number;
|
|
21
|
-
}>, limit?: number): Promise<T[]>;
|
|
22
|
-
/**
|
|
23
|
-
* Generic function to fetch paginated data from any API endpoint
|
|
24
|
-
* @param baseUrl - The base URL for the API endpoint (without query parameters)
|
|
25
|
-
* @param headers - Headers to include in the request
|
|
26
|
-
* @param additionalParams - Optional additional parameters to include in the request
|
|
27
|
-
* @returns Promise that resolves to an array of all paginated results
|
|
28
|
-
*/
|
|
29
|
-
export declare function fetchPaginatedData<T>(baseUrl: string, headers: Record<string, string>, additionalParams?: Record<string, string | number | boolean>): Promise<T[]>;
|
|
30
|
-
/**
|
|
31
|
-
* Builds action knowledge with API request structure guidance.
|
|
32
|
-
* @param knowledge - The raw knowledge content for the action
|
|
33
|
-
* @param method - The HTTP method for the action
|
|
34
|
-
* @param baseUrl - The base URL for Pica API
|
|
35
|
-
* @param platform - The platform name (used for connection key)
|
|
36
|
-
* @param actionId - The action ID
|
|
37
|
-
* @returns Complete formatted knowledge with API guidance
|
|
38
|
-
*/
|
|
39
|
-
export declare function buildActionKnowledgeWithGuidance(knowledge: string, method: string, baseUrl: string, platform: string, actionId: string): string;
|
|
40
|
-
/**
|
|
41
|
-
* Replaces path variables in a template string with actual values.
|
|
42
|
-
* Path variables can be in either format: {variableName} or {{variableName}} and will be replaced with corresponding values.
|
|
43
|
-
* @param path - The template string containing path variables in {variableName} or {{variableName}} format
|
|
44
|
-
* @param variables - Object containing variable names as keys and their replacement values
|
|
45
|
-
* @returns The path string with all variables replaced by their encoded values
|
|
46
|
-
* @throws Error if any required variable is missing, null, undefined, or empty string
|
|
47
|
-
*/
|
|
48
|
-
export declare function replacePathVariables(path: string, variables: Record<string, string | number | boolean>): string;
|
|
49
|
-
export declare function filterByPermissions<T extends {
|
|
50
|
-
method: string;
|
|
51
|
-
}>(actions: T[], permissions: PermissionLevel): T[];
|
|
52
|
-
export declare function isMethodAllowed(method: string, permissions: PermissionLevel): boolean;
|
|
53
|
-
export declare function isActionAllowed(actionId: string, allowedActionIds: string[]): boolean;
|
package/build/index.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Pica MCP Server - Main Entry Point
|
|
4
|
-
*
|
|
5
|
-
* This is the main MCP (Model Context Protocol) server implementation for Pica.
|
|
6
|
-
*
|
|
7
|
-
* @fileoverview Main MCP server implementation with Pica API integration
|
|
8
|
-
* @author Pica
|
|
9
|
-
*/
|
|
10
|
-
export { createPicaServer, type CreatePicaServerOptions } from './server.js';
|
package/build/schemas.d.ts
DELETED
|
@@ -1,285 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MCP Tool Schemas
|
|
3
|
-
*
|
|
4
|
-
* This file contains all tool schema definitions for MCP tools using zod.
|
|
5
|
-
* Centralizing schemas here improves maintainability and reusability.
|
|
6
|
-
*
|
|
7
|
-
* @fileoverview Complete tool schema definitions for all MCP tools
|
|
8
|
-
* @author Pica
|
|
9
|
-
*/
|
|
10
|
-
import { z } from 'zod';
|
|
11
|
-
/**
|
|
12
|
-
* Schema for listing Pica integrations (no parameters required)
|
|
13
|
-
*/
|
|
14
|
-
export declare const listPicaIntegrationsInputSchema: {};
|
|
15
|
-
/**
|
|
16
|
-
* Schema for searching platform actions
|
|
17
|
-
*/
|
|
18
|
-
export declare const searchPicaPlatformActionsInputSchema: {
|
|
19
|
-
platform: z.ZodString;
|
|
20
|
-
query: z.ZodString;
|
|
21
|
-
agentType: z.ZodOptional<z.ZodEnum<["execute", "knowledge"]>>;
|
|
22
|
-
};
|
|
23
|
-
/**
|
|
24
|
-
* Schema for getting action knowledge
|
|
25
|
-
*/
|
|
26
|
-
export declare const getPicaActionKnowledgeInputSchema: {
|
|
27
|
-
actionId: z.ZodString;
|
|
28
|
-
platform: z.ZodString;
|
|
29
|
-
};
|
|
30
|
-
/**
|
|
31
|
-
* Schema for executing Pica actions
|
|
32
|
-
*/
|
|
33
|
-
export declare const executePicaActionInputSchema: {
|
|
34
|
-
platform: z.ZodString;
|
|
35
|
-
actionId: z.ZodString;
|
|
36
|
-
connectionKey: z.ZodString;
|
|
37
|
-
data: z.ZodOptional<z.ZodAny>;
|
|
38
|
-
pathVariables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
|
|
39
|
-
queryParams: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
|
|
40
|
-
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
41
|
-
isFormData: z.ZodOptional<z.ZodBoolean>;
|
|
42
|
-
isFormUrlEncoded: z.ZodOptional<z.ZodBoolean>;
|
|
43
|
-
};
|
|
44
|
-
/**
|
|
45
|
-
* Output schemas for list_pica_integrations tool
|
|
46
|
-
*/
|
|
47
|
-
export declare const listPicaIntegrationsOutputSchema: {
|
|
48
|
-
connections: z.ZodArray<z.ZodObject<{
|
|
49
|
-
platform: z.ZodString;
|
|
50
|
-
key: z.ZodString;
|
|
51
|
-
tags: z.ZodArray<z.ZodString, "many">;
|
|
52
|
-
}, "strip", z.ZodTypeAny, {
|
|
53
|
-
key: string;
|
|
54
|
-
platform: string;
|
|
55
|
-
tags: string[];
|
|
56
|
-
}, {
|
|
57
|
-
key: string;
|
|
58
|
-
platform: string;
|
|
59
|
-
tags: string[];
|
|
60
|
-
}>, "many">;
|
|
61
|
-
availablePlatforms: z.ZodArray<z.ZodObject<{
|
|
62
|
-
platform: z.ZodString;
|
|
63
|
-
name: z.ZodString;
|
|
64
|
-
category: z.ZodString;
|
|
65
|
-
}, "strip", z.ZodTypeAny, {
|
|
66
|
-
platform: string;
|
|
67
|
-
name: string;
|
|
68
|
-
category: string;
|
|
69
|
-
}, {
|
|
70
|
-
platform: string;
|
|
71
|
-
name: string;
|
|
72
|
-
category: string;
|
|
73
|
-
}>, "many">;
|
|
74
|
-
summary: z.ZodObject<{
|
|
75
|
-
connectedCount: z.ZodNumber;
|
|
76
|
-
availableCount: z.ZodNumber;
|
|
77
|
-
}, "strip", z.ZodTypeAny, {
|
|
78
|
-
connectedCount: number;
|
|
79
|
-
availableCount: number;
|
|
80
|
-
}, {
|
|
81
|
-
connectedCount: number;
|
|
82
|
-
availableCount: number;
|
|
83
|
-
}>;
|
|
84
|
-
};
|
|
85
|
-
/**
|
|
86
|
-
* Output schemas for search_pica_platform_actions tool
|
|
87
|
-
*/
|
|
88
|
-
export declare const searchPicaPlatformActionsOutputSchema: {
|
|
89
|
-
actions: z.ZodArray<z.ZodObject<{
|
|
90
|
-
actionId: z.ZodString;
|
|
91
|
-
title: z.ZodString;
|
|
92
|
-
method: z.ZodString;
|
|
93
|
-
path: z.ZodString;
|
|
94
|
-
}, "strip", z.ZodTypeAny, {
|
|
95
|
-
method: string;
|
|
96
|
-
actionId: string;
|
|
97
|
-
path: string;
|
|
98
|
-
title: string;
|
|
99
|
-
}, {
|
|
100
|
-
method: string;
|
|
101
|
-
actionId: string;
|
|
102
|
-
path: string;
|
|
103
|
-
title: string;
|
|
104
|
-
}>, "many">;
|
|
105
|
-
metadata: z.ZodObject<{
|
|
106
|
-
platform: z.ZodString;
|
|
107
|
-
query: z.ZodString;
|
|
108
|
-
count: z.ZodNumber;
|
|
109
|
-
}, "strip", z.ZodTypeAny, {
|
|
110
|
-
query: string;
|
|
111
|
-
platform: string;
|
|
112
|
-
count: number;
|
|
113
|
-
}, {
|
|
114
|
-
query: string;
|
|
115
|
-
platform: string;
|
|
116
|
-
count: number;
|
|
117
|
-
}>;
|
|
118
|
-
};
|
|
119
|
-
/**
|
|
120
|
-
* Tool configuration objects for registerTool
|
|
121
|
-
*/
|
|
122
|
-
export declare const listPicaIntegrationsToolConfig: {
|
|
123
|
-
title: string;
|
|
124
|
-
description: string;
|
|
125
|
-
inputSchema: {};
|
|
126
|
-
outputSchema: {
|
|
127
|
-
connections: z.ZodArray<z.ZodObject<{
|
|
128
|
-
platform: z.ZodString;
|
|
129
|
-
key: z.ZodString;
|
|
130
|
-
tags: z.ZodArray<z.ZodString, "many">;
|
|
131
|
-
}, "strip", z.ZodTypeAny, {
|
|
132
|
-
key: string;
|
|
133
|
-
platform: string;
|
|
134
|
-
tags: string[];
|
|
135
|
-
}, {
|
|
136
|
-
key: string;
|
|
137
|
-
platform: string;
|
|
138
|
-
tags: string[];
|
|
139
|
-
}>, "many">;
|
|
140
|
-
availablePlatforms: z.ZodArray<z.ZodObject<{
|
|
141
|
-
platform: z.ZodString;
|
|
142
|
-
name: z.ZodString;
|
|
143
|
-
category: z.ZodString;
|
|
144
|
-
}, "strip", z.ZodTypeAny, {
|
|
145
|
-
platform: string;
|
|
146
|
-
name: string;
|
|
147
|
-
category: string;
|
|
148
|
-
}, {
|
|
149
|
-
platform: string;
|
|
150
|
-
name: string;
|
|
151
|
-
category: string;
|
|
152
|
-
}>, "many">;
|
|
153
|
-
summary: z.ZodObject<{
|
|
154
|
-
connectedCount: z.ZodNumber;
|
|
155
|
-
availableCount: z.ZodNumber;
|
|
156
|
-
}, "strip", z.ZodTypeAny, {
|
|
157
|
-
connectedCount: number;
|
|
158
|
-
availableCount: number;
|
|
159
|
-
}, {
|
|
160
|
-
connectedCount: number;
|
|
161
|
-
availableCount: number;
|
|
162
|
-
}>;
|
|
163
|
-
};
|
|
164
|
-
};
|
|
165
|
-
export declare const searchPicaPlatformActionsToolConfig: {
|
|
166
|
-
title: string;
|
|
167
|
-
description: string;
|
|
168
|
-
inputSchema: {
|
|
169
|
-
platform: z.ZodString;
|
|
170
|
-
query: z.ZodString;
|
|
171
|
-
agentType: z.ZodOptional<z.ZodEnum<["execute", "knowledge"]>>;
|
|
172
|
-
};
|
|
173
|
-
outputSchema: {
|
|
174
|
-
actions: z.ZodArray<z.ZodObject<{
|
|
175
|
-
actionId: z.ZodString;
|
|
176
|
-
title: z.ZodString;
|
|
177
|
-
method: z.ZodString;
|
|
178
|
-
path: z.ZodString;
|
|
179
|
-
}, "strip", z.ZodTypeAny, {
|
|
180
|
-
method: string;
|
|
181
|
-
actionId: string;
|
|
182
|
-
path: string;
|
|
183
|
-
title: string;
|
|
184
|
-
}, {
|
|
185
|
-
method: string;
|
|
186
|
-
actionId: string;
|
|
187
|
-
path: string;
|
|
188
|
-
title: string;
|
|
189
|
-
}>, "many">;
|
|
190
|
-
metadata: z.ZodObject<{
|
|
191
|
-
platform: z.ZodString;
|
|
192
|
-
query: z.ZodString;
|
|
193
|
-
count: z.ZodNumber;
|
|
194
|
-
}, "strip", z.ZodTypeAny, {
|
|
195
|
-
query: string;
|
|
196
|
-
platform: string;
|
|
197
|
-
count: number;
|
|
198
|
-
}, {
|
|
199
|
-
query: string;
|
|
200
|
-
platform: string;
|
|
201
|
-
count: number;
|
|
202
|
-
}>;
|
|
203
|
-
};
|
|
204
|
-
};
|
|
205
|
-
export declare const getPicaActionKnowledgeToolConfig: {
|
|
206
|
-
title: string;
|
|
207
|
-
description: string;
|
|
208
|
-
inputSchema: {
|
|
209
|
-
actionId: z.ZodString;
|
|
210
|
-
platform: z.ZodString;
|
|
211
|
-
};
|
|
212
|
-
};
|
|
213
|
-
export declare const executePicaActionToolConfig: {
|
|
214
|
-
title: string;
|
|
215
|
-
description: string;
|
|
216
|
-
inputSchema: {
|
|
217
|
-
platform: z.ZodString;
|
|
218
|
-
actionId: z.ZodString;
|
|
219
|
-
connectionKey: z.ZodString;
|
|
220
|
-
data: z.ZodOptional<z.ZodAny>;
|
|
221
|
-
pathVariables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
|
|
222
|
-
queryParams: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
|
|
223
|
-
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
224
|
-
isFormData: z.ZodOptional<z.ZodBoolean>;
|
|
225
|
-
isFormUrlEncoded: z.ZodOptional<z.ZodBoolean>;
|
|
226
|
-
};
|
|
227
|
-
};
|
|
228
|
-
/**
|
|
229
|
-
* Zod object schemas for type inference (for internal use)
|
|
230
|
-
*/
|
|
231
|
-
export declare const listPicaIntegrationsZodSchema: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
|
|
232
|
-
export declare const searchPicaPlatformActionsZodSchema: z.ZodObject<{
|
|
233
|
-
platform: z.ZodString;
|
|
234
|
-
query: z.ZodString;
|
|
235
|
-
agentType: z.ZodOptional<z.ZodEnum<["execute", "knowledge"]>>;
|
|
236
|
-
}, "strip", z.ZodTypeAny, {
|
|
237
|
-
query: string;
|
|
238
|
-
platform: string;
|
|
239
|
-
agentType?: "execute" | "knowledge" | undefined;
|
|
240
|
-
}, {
|
|
241
|
-
query: string;
|
|
242
|
-
platform: string;
|
|
243
|
-
agentType?: "execute" | "knowledge" | undefined;
|
|
244
|
-
}>;
|
|
245
|
-
export declare const getPicaActionKnowledgeZodSchema: z.ZodObject<{
|
|
246
|
-
actionId: z.ZodString;
|
|
247
|
-
platform: z.ZodString;
|
|
248
|
-
}, "strip", z.ZodTypeAny, {
|
|
249
|
-
actionId: string;
|
|
250
|
-
platform: string;
|
|
251
|
-
}, {
|
|
252
|
-
actionId: string;
|
|
253
|
-
platform: string;
|
|
254
|
-
}>;
|
|
255
|
-
export declare const executePicaActionZodSchema: z.ZodObject<{
|
|
256
|
-
platform: z.ZodString;
|
|
257
|
-
actionId: z.ZodString;
|
|
258
|
-
connectionKey: z.ZodString;
|
|
259
|
-
data: z.ZodOptional<z.ZodAny>;
|
|
260
|
-
pathVariables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
|
|
261
|
-
queryParams: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
|
|
262
|
-
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
263
|
-
isFormData: z.ZodOptional<z.ZodBoolean>;
|
|
264
|
-
isFormUrlEncoded: z.ZodOptional<z.ZodBoolean>;
|
|
265
|
-
}, "strip", z.ZodTypeAny, {
|
|
266
|
-
actionId: string;
|
|
267
|
-
connectionKey: string;
|
|
268
|
-
platform: string;
|
|
269
|
-
headers?: Record<string, string> | undefined;
|
|
270
|
-
data?: any;
|
|
271
|
-
pathVariables?: Record<string, string | number | boolean> | undefined;
|
|
272
|
-
queryParams?: Record<string, any> | undefined;
|
|
273
|
-
isFormData?: boolean | undefined;
|
|
274
|
-
isFormUrlEncoded?: boolean | undefined;
|
|
275
|
-
}, {
|
|
276
|
-
actionId: string;
|
|
277
|
-
connectionKey: string;
|
|
278
|
-
platform: string;
|
|
279
|
-
headers?: Record<string, string> | undefined;
|
|
280
|
-
data?: any;
|
|
281
|
-
pathVariables?: Record<string, string | number | boolean> | undefined;
|
|
282
|
-
queryParams?: Record<string, any> | undefined;
|
|
283
|
-
isFormData?: boolean | undefined;
|
|
284
|
-
isFormUrlEncoded?: boolean | undefined;
|
|
285
|
-
}>;
|
package/build/server.d.ts
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pica MCP Server Factory
|
|
3
|
-
*
|
|
4
|
-
* Exports a factory function that registers all Pica tools on a provided McpServer instance.
|
|
5
|
-
*
|
|
6
|
-
* @fileoverview createPicaServer() factory for reuse across stdio and HTTP transports
|
|
7
|
-
* @author Pica
|
|
8
|
-
*/
|
|
9
|
-
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
10
|
-
import { PermissionLevel } from './types.js';
|
|
11
|
-
export interface CreatePicaServerOptions {
|
|
12
|
-
secret: string;
|
|
13
|
-
baseUrl?: string;
|
|
14
|
-
identity?: string;
|
|
15
|
-
identityType?: 'user' | 'team' | 'organization' | 'project';
|
|
16
|
-
permissions?: PermissionLevel;
|
|
17
|
-
connectionKeys?: string[];
|
|
18
|
-
actionIds?: string[];
|
|
19
|
-
knowledgeAgent?: boolean;
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Registers all Pica MCP tools on the provided server instance.
|
|
23
|
-
*
|
|
24
|
-
* @param server - An McpServer instance to register tools on
|
|
25
|
-
* @param options - Configuration options (secret is required, rest have sensible defaults)
|
|
26
|
-
*/
|
|
27
|
-
export declare function createPicaServer(server: McpServer, options: CreatePicaServerOptions): Promise<void>;
|
package/build/server.js
DELETED
|
@@ -1,215 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pica MCP Server Factory
|
|
3
|
-
*
|
|
4
|
-
* Exports a factory function that registers all Pica tools on a provided McpServer instance.
|
|
5
|
-
*
|
|
6
|
-
* @fileoverview createPicaServer() factory for reuse across stdio and HTTP transports
|
|
7
|
-
* @author Pica
|
|
8
|
-
*/
|
|
9
|
-
import { ErrorCode, McpError, } from '@modelcontextprotocol/sdk/types.js';
|
|
10
|
-
import { PicaClient } from './client.js';
|
|
11
|
-
import { buildActionKnowledgeWithGuidance, filterByPermissions, isMethodAllowed, isActionAllowed, } from './helpers.js';
|
|
12
|
-
import { listPicaIntegrationsToolConfig, searchPicaPlatformActionsToolConfig, getPicaActionKnowledgeToolConfig, executePicaActionToolConfig, } from './schemas.js';
|
|
13
|
-
/**
|
|
14
|
-
* Registers all Pica MCP tools on the provided server instance.
|
|
15
|
-
*
|
|
16
|
-
* @param server - An McpServer instance to register tools on
|
|
17
|
-
* @param options - Configuration options (secret is required, rest have sensible defaults)
|
|
18
|
-
*/
|
|
19
|
-
export async function createPicaServer(server, options) {
|
|
20
|
-
const { secret, baseUrl, identity, identityType, permissions = 'admin', connectionKeys = ['*'], actionIds = ['*'], knowledgeAgent = false, } = options;
|
|
21
|
-
const picaClient = new PicaClient({
|
|
22
|
-
secret,
|
|
23
|
-
baseUrl,
|
|
24
|
-
identity,
|
|
25
|
-
identityType,
|
|
26
|
-
connectionKeys,
|
|
27
|
-
});
|
|
28
|
-
let picaInitialized = false;
|
|
29
|
-
let initializationPromise = null;
|
|
30
|
-
const initializePica = async () => {
|
|
31
|
-
if (picaInitialized) {
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
if (initializationPromise) {
|
|
35
|
-
return initializationPromise;
|
|
36
|
-
}
|
|
37
|
-
initializationPromise = (async () => {
|
|
38
|
-
try {
|
|
39
|
-
await picaClient.initialize();
|
|
40
|
-
picaInitialized = true;
|
|
41
|
-
}
|
|
42
|
-
catch (error) {
|
|
43
|
-
console.error("Failed to initialize Pica client:", error);
|
|
44
|
-
initializationPromise = null;
|
|
45
|
-
throw error;
|
|
46
|
-
}
|
|
47
|
-
})();
|
|
48
|
-
return initializationPromise;
|
|
49
|
-
};
|
|
50
|
-
// --- Tool handlers ---
|
|
51
|
-
async function handleGetIntegrations(_args) {
|
|
52
|
-
try {
|
|
53
|
-
const connectedIntegrations = picaClient.getUserConnections();
|
|
54
|
-
const availableIntegrations = picaClient.getAvailableConnectors();
|
|
55
|
-
const activeConnections = connectedIntegrations.filter(conn => conn.active);
|
|
56
|
-
let activePlatforms = availableIntegrations.filter(def => def.active && !def.deprecated);
|
|
57
|
-
if (!connectionKeys.includes("*")) {
|
|
58
|
-
const connectedPlatforms = new Set(activeConnections.map(conn => conn.platform));
|
|
59
|
-
activePlatforms = activePlatforms.filter(def => connectedPlatforms.has(def.platform));
|
|
60
|
-
}
|
|
61
|
-
const structuredResponse = {
|
|
62
|
-
connections: activeConnections.map(conn => ({
|
|
63
|
-
platform: conn.platform,
|
|
64
|
-
key: conn.key,
|
|
65
|
-
tags: conn.tags ?? [],
|
|
66
|
-
})),
|
|
67
|
-
availablePlatforms: activePlatforms.map(def => ({
|
|
68
|
-
platform: def.platform,
|
|
69
|
-
name: def.name,
|
|
70
|
-
category: def.category,
|
|
71
|
-
})),
|
|
72
|
-
summary: {
|
|
73
|
-
connectedCount: activeConnections.length,
|
|
74
|
-
availableCount: activePlatforms.length,
|
|
75
|
-
},
|
|
76
|
-
};
|
|
77
|
-
return {
|
|
78
|
-
content: [
|
|
79
|
-
{
|
|
80
|
-
type: "text",
|
|
81
|
-
text: JSON.stringify(structuredResponse, null, 2),
|
|
82
|
-
},
|
|
83
|
-
],
|
|
84
|
-
structuredContent: structuredResponse,
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
catch (error) {
|
|
88
|
-
throw new McpError(ErrorCode.InternalError, `Failed to retrieve integrations: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
async function handleSearchPlatformActions(args) {
|
|
92
|
-
try {
|
|
93
|
-
const agentType = knowledgeAgent ? "knowledge" : args.agentType;
|
|
94
|
-
let actions = await picaClient.searchAvailableActions(args.platform, args.query, agentType);
|
|
95
|
-
actions = filterByPermissions(actions, permissions);
|
|
96
|
-
actions = actions.filter(a => isActionAllowed(a.systemId, actionIds));
|
|
97
|
-
const cleanedActions = actions.map(action => ({
|
|
98
|
-
actionId: action.systemId,
|
|
99
|
-
title: action.title,
|
|
100
|
-
method: action.method,
|
|
101
|
-
path: action.path,
|
|
102
|
-
}));
|
|
103
|
-
if (cleanedActions.length === 0) {
|
|
104
|
-
const suggestionsText = `No actions found for platform '${args.platform}' matching query '${args.query}'.
|
|
105
|
-
|
|
106
|
-
SUGGESTIONS:
|
|
107
|
-
- Try a more general query (e.g., 'list', 'get', 'search', 'create')
|
|
108
|
-
- Verify the platform name is correct
|
|
109
|
-
- Check that actions exist for this platform using list_pica_integrations
|
|
110
|
-
|
|
111
|
-
EXAMPLES OF GOOD QUERIES:
|
|
112
|
-
- "search contacts"
|
|
113
|
-
- "send email"
|
|
114
|
-
- "create customer"
|
|
115
|
-
- "list orders"`;
|
|
116
|
-
return {
|
|
117
|
-
content: [
|
|
118
|
-
{
|
|
119
|
-
type: "text",
|
|
120
|
-
text: suggestionsText,
|
|
121
|
-
},
|
|
122
|
-
],
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
const structuredResponse = {
|
|
126
|
-
actions: cleanedActions,
|
|
127
|
-
metadata: {
|
|
128
|
-
platform: args.platform,
|
|
129
|
-
query: args.query,
|
|
130
|
-
count: cleanedActions.length,
|
|
131
|
-
},
|
|
132
|
-
};
|
|
133
|
-
const responseText = `Found ${cleanedActions.length} action(s) for platform '${args.platform}' matching query '${args.query}':
|
|
134
|
-
|
|
135
|
-
${JSON.stringify(structuredResponse, null, 2)}
|
|
136
|
-
|
|
137
|
-
NEXT STEP: Use get_pica_action_knowledge with an actionId to get detailed documentation before building requests or executing actions.`;
|
|
138
|
-
return {
|
|
139
|
-
content: [
|
|
140
|
-
{
|
|
141
|
-
type: "text",
|
|
142
|
-
text: responseText,
|
|
143
|
-
},
|
|
144
|
-
],
|
|
145
|
-
structuredContent: structuredResponse,
|
|
146
|
-
};
|
|
147
|
-
}
|
|
148
|
-
catch (error) {
|
|
149
|
-
throw new McpError(ErrorCode.InternalError, `Failed to search platform actions: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
async function handleGetActionKnowledge(args) {
|
|
153
|
-
try {
|
|
154
|
-
const actionId = args.actionId;
|
|
155
|
-
if (!isActionAllowed(actionId, actionIds)) {
|
|
156
|
-
throw new McpError(ErrorCode.InvalidRequest, `Action "${actionId}" is not in the allowed action list`);
|
|
157
|
-
}
|
|
158
|
-
const { knowledge, method } = await picaClient.getActionKnowledge(actionId);
|
|
159
|
-
const knowledgeWithGuidance = buildActionKnowledgeWithGuidance(knowledge, method, picaClient.getBaseUrl(), args.platform, actionId);
|
|
160
|
-
return {
|
|
161
|
-
content: [
|
|
162
|
-
{
|
|
163
|
-
type: "text",
|
|
164
|
-
text: knowledgeWithGuidance,
|
|
165
|
-
},
|
|
166
|
-
],
|
|
167
|
-
};
|
|
168
|
-
}
|
|
169
|
-
catch (error) {
|
|
170
|
-
throw new McpError(ErrorCode.InternalError, `Failed to retrieve action knowledge: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
async function handleExecutePicaAction(args) {
|
|
174
|
-
try {
|
|
175
|
-
if (!isActionAllowed(args.actionId, actionIds)) {
|
|
176
|
-
throw new McpError(ErrorCode.InvalidRequest, `Action "${args.actionId}" is not in the allowed action list`);
|
|
177
|
-
}
|
|
178
|
-
const actionDetails = await picaClient.getActionDetails(args.actionId);
|
|
179
|
-
if (!isMethodAllowed(actionDetails.method, permissions)) {
|
|
180
|
-
throw new McpError(ErrorCode.InvalidRequest, `Method "${actionDetails.method}" is not allowed under "${permissions}" permission level`);
|
|
181
|
-
}
|
|
182
|
-
const result = await picaClient.executePassthroughRequest(args, actionDetails);
|
|
183
|
-
return {
|
|
184
|
-
content: [
|
|
185
|
-
{
|
|
186
|
-
type: "text",
|
|
187
|
-
text: JSON.stringify(result, null, 2),
|
|
188
|
-
},
|
|
189
|
-
],
|
|
190
|
-
};
|
|
191
|
-
}
|
|
192
|
-
catch (error) {
|
|
193
|
-
throw new McpError(ErrorCode.InternalError, `Failed to execute Pica action: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
// --- Register tools ---
|
|
197
|
-
server.registerTool("list_pica_integrations", listPicaIntegrationsToolConfig, async (args) => {
|
|
198
|
-
await initializePica();
|
|
199
|
-
return await handleGetIntegrations(args);
|
|
200
|
-
});
|
|
201
|
-
server.registerTool("search_pica_platform_actions", searchPicaPlatformActionsToolConfig, async (args) => {
|
|
202
|
-
await initializePica();
|
|
203
|
-
return await handleSearchPlatformActions(args);
|
|
204
|
-
});
|
|
205
|
-
server.registerTool("get_pica_action_knowledge", getPicaActionKnowledgeToolConfig, async (args) => {
|
|
206
|
-
await initializePica();
|
|
207
|
-
return await handleGetActionKnowledge(args);
|
|
208
|
-
});
|
|
209
|
-
if (!knowledgeAgent) {
|
|
210
|
-
server.registerTool("execute_pica_action", executePicaActionToolConfig, async (args) => {
|
|
211
|
-
await initializePica();
|
|
212
|
-
return await handleExecutePicaAction(args);
|
|
213
|
-
});
|
|
214
|
-
}
|
|
215
|
-
}
|
package/build/types.d.ts
DELETED
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Type definitions for the Pica MCP Server
|
|
3
|
-
*
|
|
4
|
-
* This file contains all TypeScript interfaces and types used throughout the application.
|
|
5
|
-
*
|
|
6
|
-
* @fileoverview Core type definitions for Pica API integration
|
|
7
|
-
* @author Pica
|
|
8
|
-
*/
|
|
9
|
-
/**
|
|
10
|
-
* API response structure for paginated endpoints
|
|
11
|
-
*/
|
|
12
|
-
export interface PaginatedResponse<T> {
|
|
13
|
-
rows: T[];
|
|
14
|
-
total: number;
|
|
15
|
-
skip: number;
|
|
16
|
-
limit: number;
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Definition of an available platform/connector that users can connect to
|
|
20
|
-
*/
|
|
21
|
-
export interface ConnectionDefinition {
|
|
22
|
-
name: string;
|
|
23
|
-
key: string;
|
|
24
|
-
platform: string;
|
|
25
|
-
platformVersion: string;
|
|
26
|
-
description: string;
|
|
27
|
-
category: string;
|
|
28
|
-
image: string;
|
|
29
|
-
tags: string[];
|
|
30
|
-
oauth: boolean;
|
|
31
|
-
createdAt: number;
|
|
32
|
-
updatedAt: number;
|
|
33
|
-
version: string;
|
|
34
|
-
active: boolean;
|
|
35
|
-
deprecated: boolean;
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Represents an active user connection to a platform
|
|
39
|
-
*/
|
|
40
|
-
export interface Connection {
|
|
41
|
-
key: string;
|
|
42
|
-
platform: string;
|
|
43
|
-
tags: string[];
|
|
44
|
-
active: boolean;
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Available action from search endpoint (uses systemId)
|
|
48
|
-
*/
|
|
49
|
-
export interface AvailableAction {
|
|
50
|
-
systemId: string;
|
|
51
|
-
title: string;
|
|
52
|
-
tags?: string[];
|
|
53
|
-
knowledge?: string;
|
|
54
|
-
path: string;
|
|
55
|
-
method: string;
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Action details from knowledge endpoint (uses _id)
|
|
59
|
-
*/
|
|
60
|
-
export interface ActionDetails {
|
|
61
|
-
_id: string;
|
|
62
|
-
title: string;
|
|
63
|
-
tags?: string[];
|
|
64
|
-
knowledge?: string;
|
|
65
|
-
path: string;
|
|
66
|
-
method: string;
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Arguments for list_pica_integrations tool
|
|
70
|
-
*/
|
|
71
|
-
export interface ListPicaIntegrationsArgs {
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Arguments for search_pica_platform_actions tool
|
|
75
|
-
*/
|
|
76
|
-
export interface SearchPicaPlatformActionsArgs {
|
|
77
|
-
platform: string;
|
|
78
|
-
query: string;
|
|
79
|
-
agentType?: "execute" | "knowledge";
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Arguments for get_pica_action_knowledge tool
|
|
83
|
-
*/
|
|
84
|
-
export interface GetPicaActionKnowledgeArgs {
|
|
85
|
-
actionId: string;
|
|
86
|
-
platform: string;
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* Response for get_pica_action_knowledge tool
|
|
90
|
-
*/
|
|
91
|
-
export interface GetPicaActionKnowledgeResponse {
|
|
92
|
-
knowledge: string;
|
|
93
|
-
method: string;
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* Action object structure for create_pica_request tool
|
|
97
|
-
*/
|
|
98
|
-
export interface ActionObject {
|
|
99
|
-
_id: string;
|
|
100
|
-
path: string;
|
|
101
|
-
method: string;
|
|
102
|
-
tags?: string[];
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* Arguments for create_pica_request tool
|
|
106
|
-
*/
|
|
107
|
-
export interface ExecutePicaActionArgs {
|
|
108
|
-
platform: string;
|
|
109
|
-
actionId: string;
|
|
110
|
-
connectionKey: string;
|
|
111
|
-
data?: any;
|
|
112
|
-
pathVariables?: Record<string, string | number | boolean>;
|
|
113
|
-
queryParams?: Record<string, any>;
|
|
114
|
-
headers?: Record<string, any>;
|
|
115
|
-
isFormData?: boolean;
|
|
116
|
-
isFormUrlEncoded?: boolean;
|
|
117
|
-
}
|
|
118
|
-
/**
|
|
119
|
-
* HTTP request configuration for axios
|
|
120
|
-
*/
|
|
121
|
-
export interface RequestConfig {
|
|
122
|
-
url: string;
|
|
123
|
-
method: string;
|
|
124
|
-
headers: Record<string, string>;
|
|
125
|
-
params?: Record<string, string>;
|
|
126
|
-
data?: unknown;
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* Sanitized version of request config with sensitive data redacted
|
|
130
|
-
*/
|
|
131
|
-
export interface SanitizedRequestConfig {
|
|
132
|
-
url: string;
|
|
133
|
-
method: string;
|
|
134
|
-
headers: Record<string, string>;
|
|
135
|
-
params?: Record<string, string>;
|
|
136
|
-
data?: unknown;
|
|
137
|
-
}
|
|
138
|
-
/**
|
|
139
|
-
* Response from executePassthroughRequest
|
|
140
|
-
*/
|
|
141
|
-
export interface ExecutePassthroughResponse {
|
|
142
|
-
requestConfig: SanitizedRequestConfig;
|
|
143
|
-
responseData: unknown;
|
|
144
|
-
}
|
|
145
|
-
/**
|
|
146
|
-
* Structured response for list_pica_integrations tool
|
|
147
|
-
*/
|
|
148
|
-
export interface ListIntegrationsResponse {
|
|
149
|
-
[x: string]: unknown;
|
|
150
|
-
connections: Array<{
|
|
151
|
-
platform: string;
|
|
152
|
-
key: string;
|
|
153
|
-
tags: string[];
|
|
154
|
-
}>;
|
|
155
|
-
availablePlatforms: Array<{
|
|
156
|
-
platform: string;
|
|
157
|
-
name: string;
|
|
158
|
-
category: string;
|
|
159
|
-
}>;
|
|
160
|
-
summary: {
|
|
161
|
-
connectedCount: number;
|
|
162
|
-
availableCount: number;
|
|
163
|
-
};
|
|
164
|
-
}
|
|
165
|
-
/**
|
|
166
|
-
* Structured response for search_pica_platform_actions tool
|
|
167
|
-
*/
|
|
168
|
-
export interface SearchActionsResponse {
|
|
169
|
-
[x: string]: unknown;
|
|
170
|
-
actions: Array<{
|
|
171
|
-
actionId: string;
|
|
172
|
-
title: string;
|
|
173
|
-
method: string;
|
|
174
|
-
path: string;
|
|
175
|
-
}>;
|
|
176
|
-
metadata: {
|
|
177
|
-
platform: string;
|
|
178
|
-
query: string;
|
|
179
|
-
count: number;
|
|
180
|
-
};
|
|
181
|
-
}
|
|
182
|
-
export type PermissionLevel = "read" | "write" | "admin";
|