πŸš€ DAY 5 OF LAUNCH WEEK: Introducing Socket Firewall Enterprise.Learn more β†’
Socket
Book a DemoInstallSign in
Socket

@zapier/mcp-integration

Package Overview
Dependencies
Maintainers
292
Versions
20
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@zapier/mcp-integration

SDK for using remote Model Context Protocol (MCP) servers in/as Zapier integrations

Source
npmnpm
Version
0.0.0-STAFF-2098-20250826095649
Version published
Weekly downloads
63
-40%
Maintainers
292
Weekly downloads
Β 
Created
Source

@zapier/mcp-integration

SDK for integrating with Model Context Protocol (MCP) servers, designed for use in Zapier integrations.

npm version License: MIT

Table of Contents

Installation & Prerequisites

Install the package via npm:

npm install @zapier/mcp-integration

Prerequisites

TypeScript Configuration

Make sure your tsconfig.json includes .json files:

{
  "include": ["src/**/*", "src/*.json"]
}

Make sure your .zapierapprc includes the .json files:

{
  "includeInBuild": ["dist/.*.json"]
}

Quick Start

Here's a minimal working example:

1. Create MCP Proxy

Create src/mcp.ts:

import { Proxy } from '@zapier/mcp-integration';
import packageJson from '../package.json' with { type: 'json' };

export const mcp = new Proxy({
  name: packageJson.name,
  version: packageJson.version,
  serverUrl: process.env.SERVER_URL,
  transport: 'sse', // or 'streamable'
});

2. Initialize Your App

Update src/index.ts:

import { defineApp } from 'zapier-platform-core';
import { mcp } from './mcp.js';

export default defineApp({
  ...mcp.defineApp(),

  triggers: {
    my_trigger: {
      noun: 'Item',
      display: {
        label: 'New Item',
        description: 'Triggers when a new item is available.',
      },
      operation: {
        perform: async (z, bundle) => {
          // Call MCP tool
          return await mcp.callTool({
            name: 'list_items',
            arguments: {},
          });
        },
      },
    },
  },
});

Use the CLI to automatically generate actions from your MCP tools:

npx @zapier/mcp-integration generate

This creates complete Zapier actions from your MCP tools automatically.

Basic Usage

Setup Patterns

You can use @zapier/mcp-integration in two ways:

Use MCP for authentication and all actions:

// src/mcp.ts
export const mcp = new Proxy({
  name: packageJson.name,
  version: packageJson.version,
  serverUrl: process.env.SERVER_URL,
  transport: process.env.TRANSPORT,
});

// src/index.ts
export default defineApp({
  ...mcp.defineApp(), // Includes auth + actions
});

Actions Only

Handle authentication yourself, use MCP for some actions:

// src/mcp.ts
export const mcp = new Proxy({
  name: packageJson.name,
  version: packageJson.version,
  serverUrl: process.env.SERVER_URL,
  transport: process.env.TRANSPORT,
  auth: { type: 'oauth' },
});

// src/index.ts
export default defineApp({
  ...mcp.defineApp({ handleAuth: false }),
  authentication: yourAuthConfig,
});

Calling MCP Tools

const perform = async (z: ZObject, bundle: Bundle) => {
  const result = await mcp.callTool({
    name: 'my_tool',
    arguments: { hello: 'world' },
    parse: true, // Parse JSON responses (default: true)
    error: true, // Throw on MCP errors (default: true)
    filter: 'data.items', // JSONata filter (optional)
  });

  return result;
};

Making API Requests

Use z.request() normally - authentication is handled automatically:

const perform = async (z: ZObject, bundle: Bundle) => {
  const response = await z.request({
    method: 'GET',
    url: 'https://api.example.com/data',
  });

  return response.json;
};

Code Generation

The package includes a CLI tool that automatically generates Zapier actions from your MCP tools.

CLI Usage

npx @zapier/mcp-integration generate [options]

Options:

  • --mcpModule <path> - Path to your MCP module (default: dist/mcp.js)
  • --writeToDir <path> - Output directory (default: .)
  • --tool <name> - Generate only specific tool (preserves existing files)

Basic Generation

# Generate all actions
npx @zapier/mcp-integration generate

# Custom paths
npx @zapier/mcp-integration generate --mcpModule dist/my-mcp.js --writeToDir ./src

Selective Generation (Development)

Generate only specific tools during development:

# Generate only one tool - faster and preserves other files
npx @zapier/mcp-integration generate --tool notion-create-comment

Benefits:

  • βœ… Faster - processes one tool vs all tools
  • βœ… Safe - preserves existing imports and files
  • βœ… Perfect for iteration - test single tool changes

Generated Structure

src/
β”œβ”€β”€ tools.json                    # Complete tool definitions
β”œβ”€β”€ creates/
β”‚   β”œβ”€β”€ index.generated.ts        # Export index
β”‚   └── create_tool_name.generated.ts
β”œβ”€β”€ searches/
β”‚   β”œβ”€β”€ index.generated.ts
β”‚   └── search_tool_name.generated.ts
└── triggers/
    β”œβ”€β”€ index.generated.ts
    └── trigger_tool_name.generated.ts

Important: All .generated.ts files are auto-created and shouldn't be manually edited.

Customizing Actions

Use transformers to customize how MCP tools become Zapier actions:

Basic Transformer

import {
  defineTransform,
  extendAction,
  withNamedImport,
} from '@zapier/mcp-integration';

export const transformer = defineTransform({
  transformCreate: (action, tool) => {
    if (tool.name === 'notion-create-page') {
      return extendAction(action)
        .prependFields({
          key: 'workspace_id',
          dynamic: 'list_workspaces.id.name',
        })
        .replacePerform(withNamedImport('../utils/customPerform.js', 'perform'))
        .build();
    }
    return action;
  },
});

// Use in your proxy
export const mcp = new Proxy({
  // ... config
  transformer,
});

Field Manipulation

// Add fields
extendAction(action)
  .prependFields({ key: 'token', type: 'string', required: true })
  .appendFields({ key: 'debug', type: 'boolean', default: false })
  .build();

// Modify fields
extendAction(action)
  .modifyField('page_id', (field) => ({
    ...field,
    dynamic: 'list_pages.id.name',
  }))
  .build();

// Replace all fields
extendAction(action)
  .replaceInputFields(
    { key: 'url', type: 'string', required: true },
    { key: 'method', type: 'string', choices: ['GET', 'POST', 'PUT'] },
  )
  .build();

Input Field Groups

Organize fields in the UI with groups:

// Define groups and fields
export const inputFieldGroups = [
  { key: 'content', label: 'Content', emphasize: true },
  { key: 'formatting', label: 'Formatting', emphasize: false },
];

export const inputFields = [
  { key: 'title', type: 'string', required: true, group: 'content' },
  { key: 'text', type: 'text', required: true, group: 'content' },
  {
    key: 'formatting',
    type: 'string',
    list: true,
    choices: { bold: 'Bold', italic: 'Italic' },
    group: 'formatting',
  },
];

// Use in transformer
extendAction(action)
  .replaceInputFields(withNamedImport('../utils/myAction.js', 'inputFields'))
  .replaceInputFieldGroups(
    withNamedImport('../utils/myAction.js', 'inputFieldGroups'),
  )
  .build();

Dynamic Dropdowns

// Add common dropdowns
const addDropdowns = addCommonDynamicDropdowns({
  page_id: 'list_pages.id.name',
  user_id: 'list_users.id.name',
});

extendAction(action).transformAllFields(addDropdowns).build();

Control Action Types

transformTool: (tool) => {
  // Make read-only tools generate search/trigger instead of create
  if (tool.name === 'get-user') {
    return {
      ...tool,
      annotations: { ...tool.annotations, readOnlyHint: true },
    };
  }
  return undefined; // unchanged
},

Advanced Configuration

Authentication

OAuth 2.0

const mcp = new Proxy({
  // ... basic config
  auth: { type: 'oauth' }, // Auto-configured
});

Bearer Token

const mcp = new Proxy({
  // ... basic config
  auth: { type: 'bearer', token: 'your-token' },
});

Transport Options

  • sse - Server-Sent Events (recommended)
  • streamable - HTTP streaming
const mcp = new Proxy({
  // ... config
  transport: 'sse', // or 'streamable'
  debug: true, // Enable debug logging (streamable only)
});

Tool Call Options

await mcp.callTool({
  name: 'my_tool',
  arguments: { param: 'value' },
  parse: true, // Parse JSON (default: true)
  error: true, // Throw on errors (default: true)
  filter: 'data.items', // JSONata filter
});

API Reference

Proxy Class

Main class for MCP integration.

Constructor

new Proxy(config: Config)

Config:

  • name: string - Integration name
  • version: string - Integration version
  • serverUrl: string - MCP server URL
  • transport: 'sse' | 'streamable' - Transport protocol
  • auth?: AuthConfig - Authentication (optional)
  • transformer?: Transformer - Action customization (optional)
  • delegateAuth?: boolean - Delegate auth handling (default: false)
  • debug?: boolean - Enable debug logging (optional)

Key Methods

defineApp(options?: AppOptions): App

Returns Zapier app configuration.

Options:

  • handleAuth?: boolean - Handle authentication (default: true)
callTool(options: CallToolOptions): Promise<any>

Call an MCP tool.

Options:

  • name: string - Tool name
  • arguments: object - Tool arguments
  • parse?: boolean - Parse JSON (default: true)
  • error?: boolean - Throw on errors (default: true)
  • filter?: string - JSONata filter
Tool Management
  • listTools(params?) - List tools with pagination
  • listAllTools() - List all tools (auto-pagination)
  • getTool(name) - Get specific tool
  • getServerVersion() - Get server version
OAuth Methods
  • authorizeUrl(z, bundle) - Get authorization URL
  • getAccessToken(z, bundle) - Exchange code for tokens
  • refreshAccessToken(z, bundle) - Refresh expired tokens
Utilities
  • defineTest() - Connection test function
  • defineConnectionLabel() - Connection label generator
  • close() - Close MCP client
  • configure(config) - Update configuration

Transformation Functions

defineTransform(transformer: Transformer): Transformer

Create action transformer.

Transformer:

  • transformTool?: (tool) => Tool | undefined - Transform tool before generation
  • transformCreate?: (action, tool) => Create | undefined - Customize creates
  • transformSearch?: (action, tool) => Search | undefined - Customize searches
  • transformTrigger?: (action, tool) => Trigger | undefined - Customize triggers

extendAction<T>(action: T): ActionExtender<T>

Fluent API for modifying actions.

Methods:

  • prependFields(...fields) - Add fields at start
  • appendFields(...fields) - Add fields at end
  • insertFieldsAfter(key, ...fields) - Insert fields after key
  • replaceInputFields(...fields) - Replace all fields
  • replaceInputFieldGroups(groups) - Replace field groups
  • modifyField(key, modifier) - Modify specific field
  • transformAllFields(transformer) - Transform all fields
  • replacePerform(namedImport) - Replace perform function
  • replaceDescription(description) - Change description
  • build() - Return modified action

Helper Functions

  • addCommonDynamicDropdowns(mappings) - Add dropdowns to fields
  • withNamedImport(path, name) - Create named import reference
  • convertInputSchemaToFields(schema) - Convert MCP schema to Zapier fields

Examples

Complete Integration

// src/mcp.ts
import { Proxy, defineTransform, extendAction } from '@zapier/mcp-integration';
import packageJson from '../package.json' with { type: 'json' };

const transformer = defineTransform({
  transformCreate: (action, tool) => {
    // Add workspace selection to all creates
    return extendAction(action)
      .prependFields({
        key: 'workspace_id',
        dynamic: 'list_workspaces.id.name',
        required: true,
      })
      .build();
  },
});

export const mcp = new Proxy({
  name: packageJson.name,
  version: packageJson.version,
  serverUrl: process.env.SERVER_URL,
  transport: 'sse',
  transformer,
});

// src/index.ts
import { defineApp } from 'zapier-platform-core';
import { mcp } from './mcp.js';

export default defineApp({
  ...mcp.defineApp(),

  // Generated actions will be automatically included
  // Custom triggers for dropdowns
  triggers: {
    list_workspaces: {
      noun: 'Workspace',
      display: { label: 'New Workspace', description: 'For dropdowns' },
      operation: {
        perform: async (z, bundle) => {
          const workspaces = await mcp.callTool({
            name: 'list-workspaces',
            arguments: {},
            filter: 'content[0].json.data',
          });

          return workspaces.map((w) => ({ id: w.id, name: w.name }));
        },
      },
    },
  },
});

Custom Perform Function

// src/utils/createPagePerform.ts
export const perform = async (z: ZObject, bundle: Bundle) => {
  const { workspace_id, title, content, template } = bundle.inputData;

  try {
    if (!workspace_id) throw new Error('Workspace required');
    if (!title?.trim()) throw new Error('Title cannot be empty');

    const result = await mcp.callTool({
      name: 'notion-create-page',
      arguments: {
        workspace_id,
        title: title.trim(),
        content,
        metadata: {
          template_used: template || 'blank',
          created_by: 'zapier',
        },
      },
      filter: 'content[0].json',
    });

    return {
      id: result.id,
      title: result.properties?.title || title,
      url: result.url,
      created_at: new Date().toISOString(),
    };
  } catch (error) {
    z.console.error('Page creation failed:', error);
    throw new Error(`Failed to create page: ${error.message}`);
  }
};

Field Groups Example

// src/utils/commentAction.ts
export const inputFieldGroups = [
  { key: 'content', label: 'Content', emphasize: true },
  { key: 'formatting', label: 'Text Formatting', emphasize: false },
];

export const inputFields = [
  {
    key: 'page_id',
    label: 'Page',
    dynamic: 'list_pages.id.name',
    required: true,
    group: 'content',
  },
  {
    key: 'text_content',
    label: 'Comment Text',
    type: 'text',
    required: true,
    group: 'content',
  },
  {
    key: 'formatting',
    label: 'Text Formatting',
    type: 'string',
    list: true,
    choices: {
      bold: 'Bold',
      italic: 'Italic',
      underline: 'Underline',
    },
    group: 'formatting',
  },
];

export const perform = async (z: ZObject, bundle: Bundle) => {
  const formattingOptions = bundle.inputData.formatting || [];

  const richTextObject = {
    type: 'text',
    text: { content: bundle.inputData.text_content },
    annotations: {
      bold: formattingOptions.includes('bold'),
      italic: formattingOptions.includes('italic'),
      underline: formattingOptions.includes('underline'),
    },
  };

  return await mcp.callTool({
    name: 'notion-create-comment',
    arguments: {
      parent: bundle.inputData.page_id,
      rich_text: [richTextObject],
    },
  });
};

TypeScript Support

This package includes comprehensive TypeScript support:

import { Proxy, defineTransform, extendAction } from '@zapier/mcp-integration';

// All types are automatically inferred
const mcp = new Proxy({
  name: 'my-integration',
  version: '1.0.0',
  serverUrl: process.env.SERVER_URL!,
  transport: 'sse',
});

// Tool calls are properly typed
const result = await mcp.callTool({
  name: 'my_tool',
  arguments: { param: 'value' },
});

The package provides full TypeScript definitions for all exported functions and classes.

Contributing

This package is part of the Zapier MCP integration project. For issues and contributions, please visit the GitLab repository.

License

MIT Β© Zapier

Keywords

zapier

FAQs

Package last updated on 26 Aug 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts