@withone/mcp 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- <img src="https://assets.withone.ai/banners/mcp.png?v=1" alt="One MCP — Connect your agents to every app through a single MCP." style="border-radius: 5px;">
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 250+ 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.
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
- - **250+ platforms.** Gmail, Slack, Shopify, HubSpot, Stripe, Linear, QuickBooks, and [more](https://app.withone.ai/tools).
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,36 @@ 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
+ ### Clients with native remote support
73
+
74
+ Add `https://mcp.withone.ai/mcp` as a remote (custom) MCP server and complete the OAuth prompt.
75
+
76
+ ### Clients without native remote support (Claude Desktop, etc.)
77
+
78
+ Bridge to the remote server with [`mcp-remote`](https://www.npmjs.com/package/mcp-remote):
79
+
80
+ ```json
81
+ {
82
+ "mcpServers": {
83
+ "one": {
84
+ "command": "npx",
85
+ "args": ["mcp-remote", "https://mcp.withone.ai/mcp"]
86
+ }
87
+ }
88
+ }
89
+ ```
90
+
91
+ The first run opens a browser to authenticate and authorize. After that, the same four tools are available.
92
+
68
93
  ## Manual Installation
69
94
 
70
95
  If you prefer to configure the server manually instead of using `one init`, install the package directly:
@@ -115,6 +140,14 @@ ONE_KNOWLEDGE_AGENT=true
115
140
 
116
141
  All defaults preserve current behavior. If no access control env vars are set, the server starts with full access and all tools available.
117
142
 
143
+ 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:
144
+
145
+ | `access` | When |
146
+ |---|---|
147
+ | `{ "policy": "full" }` | No action allowlist and `ONE_PERMISSIONS=admin` — every action is runnable. |
148
+ | `{ "policy": "methods", "methods": ["GET", ...] }` | No action allowlist, but `ONE_PERMISSIONS` is `read`/`write` — only these HTTP methods are runnable. |
149
+ | `{ "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. |
150
+
118
151
  ## Manual Configuration
119
152
 
120
153
  If you used `one init`, the configuration below is already done for you. These examples are for reference or manual setups.
@@ -146,10 +179,6 @@ Add the following to your MCP config:
146
179
  }
147
180
  ```
148
181
 
149
- ### Remote MCP Server
150
-
151
- The remote MCP server is available at [https://mcp.withone.ai](https://mcp.withone.ai).
152
-
153
182
  ### Docker
154
183
 
155
184
  ```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
- })).describe("Array of user's active connections"),
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@withone/mcp",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "A Model Context Protocol Server for One",
5
5
  "type": "module",
6
6
  "bin": {
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
- }
@@ -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';
@@ -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";