This is page 1 of 2. Use http://codebase.md/maton-ai/agent-toolkit?lines=false&page={x} to view the full context. # Directory Structure ``` ├── .github │ └── workflows │ ├── main.yml │ └── release.yml ├── .gitignore ├── .vscode │ ├── extensions.json │ └── settings.json ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Dockerfile ├── glama.json ├── LICENSE ├── modelcontextprotocol │ ├── .gitignore │ ├── .prettierrc │ ├── Dockerfile │ ├── eslint.config.mjs │ ├── jest.config.ts │ ├── package.json │ ├── pnpm-lock.yaml │ ├── README.md │ ├── scripts │ │ └── publish │ ├── smithery.yaml │ ├── src │ │ └── index.ts │ └── tsconfig.json ├── README.md ├── SECURITY.md └── typescript ├── .gitignore ├── .prettierrc ├── eslint.config.mjs ├── examples │ ├── ai-sdk │ │ ├── .env.template │ │ ├── index.ts │ │ ├── package.json │ │ ├── README.md │ │ └── tsconfig.json │ ├── langchain │ │ ├── .env.template │ │ ├── index.ts │ │ ├── package.json │ │ ├── README.md │ │ └── tsconfig.json │ └── openai │ ├── .env.template │ ├── index.ts │ ├── package.json │ ├── README.md │ └── tsconfig.json ├── jest.config.ts ├── package.json ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── README.md ├── scripts │ └── publish ├── src │ ├── ai-sdk │ │ ├── index.ts │ │ ├── tool.ts │ │ └── toolkit.ts │ ├── langchain │ │ ├── index.ts │ │ ├── tool.ts │ │ └── toolkit.ts │ ├── modelcontextprotocol │ │ ├── index.ts │ │ └── toolkit.ts │ ├── openai │ │ ├── index.ts │ │ └── toolkit.ts │ └── shared │ ├── api.ts │ ├── configuration.ts │ ├── parameters │ │ ├── airtable.ts │ │ ├── asana.ts │ │ ├── aws.ts │ │ ├── calendly.ts │ │ ├── clickup.ts │ │ ├── google-calendar.ts │ │ ├── google-docs.ts │ │ ├── google-drive.ts │ │ ├── google-mail.ts │ │ ├── google-sheet.ts │ │ ├── hubspot.ts │ │ ├── jira.ts │ │ ├── jotform.ts │ │ ├── klaviyo.ts │ │ ├── mailchimp.ts │ │ ├── notion.ts │ │ ├── outlook.ts │ │ ├── pipedrive.ts │ │ ├── salesforce.ts │ │ ├── shopify.ts │ │ ├── slack.ts │ │ ├── stripe.ts │ │ ├── typeform.ts │ │ └── youtube.ts │ ├── prompts │ │ ├── airtable.ts │ │ ├── asana.ts │ │ ├── aws.ts │ │ ├── calendly.ts │ │ ├── clickup.ts │ │ ├── google-calendar.ts │ │ ├── google-docs.ts │ │ ├── google-drive.ts │ │ ├── google-mail.ts │ │ ├── google-sheet.ts │ │ ├── hubspot.ts │ │ ├── jira.ts │ │ ├── jotform.ts │ │ ├── klaviyo.ts │ │ ├── mailchimp.ts │ │ ├── notion.ts │ │ ├── outlook.ts │ │ ├── pipedrive.ts │ │ ├── salesforce.ts │ │ ├── shopify.ts │ │ ├── slack.ts │ │ ├── stripe.ts │ │ ├── typeform.ts │ │ └── youtube.ts │ └── tools.ts ├── tsconfig.json └── tsup.config.ts ``` # Files -------------------------------------------------------------------------------- /modelcontextprotocol/.gitignore: -------------------------------------------------------------------------------- ``` dist/ node_modules/ ``` -------------------------------------------------------------------------------- /typescript/examples/openai/.env.template: -------------------------------------------------------------------------------- ``` OPENAI_API_KEY="" MATON_API_KEY="" ``` -------------------------------------------------------------------------------- /typescript/examples/ai-sdk/.env.template: -------------------------------------------------------------------------------- ``` MATON_API_KEY="" OPENAI_API_KEY="" ``` -------------------------------------------------------------------------------- /typescript/examples/langchain/.env.template: -------------------------------------------------------------------------------- ``` MATON_API_KEY="" OPENAI_API_KEY="" ``` -------------------------------------------------------------------------------- /modelcontextprotocol/.prettierrc: -------------------------------------------------------------------------------- ``` { "singleQuote": true, "trailingComma": "es5", "bracketSpacing": false } ``` -------------------------------------------------------------------------------- /typescript/.prettierrc: -------------------------------------------------------------------------------- ``` { "singleQuote": true, "trailingComma": "es5", "bracketSpacing": false } ``` -------------------------------------------------------------------------------- /typescript/.gitignore: -------------------------------------------------------------------------------- ``` # Logs logs *.log npm-debug.log* yarn-debug.log* yarn-error.log* lerna-debug.log* .pnpm-debug.log* # Diagnostic reports (https://nodejs.org/api/report.html) report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json # Runtime data pids *.pid *.seed *.pid.lock # Directory for instrumented libs generated by jscoverage/JSCover lib-cov # Coverage directory used by tools like istanbul coverage *.lcov # nyc test coverage .nyc_output # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) .grunt # Bower dependency directory (https://bower.io/) bower_components # node-waf configuration .lock-wscript # Compiled binary addons (https://nodejs.org/api/addons.html) build/Release # Dependency directories node_modules/ jspm_packages/ # Snowpack dependency directory (https://snowpack.dev/) web_modules/ # TypeScript cache *.tsbuildinfo # Optional npm cache directory .npm # Optional eslint cache .eslintcache # Optional stylelint cache .stylelintcache # Microbundle cache .rpt2_cache/ .rts2_cache_cjs/ .rts2_cache_es/ .rts2_cache_umd/ # Optional REPL history .node_repl_history # Output of 'npm pack' *.tgz # Yarn Integrity file .yarn-integrity # dotenv environment variable files .env .env.development.local .env.test.local .env.production.local .env.local # parcel-bundler cache (https://parceljs.org/) .cache .parcel-cache # Next.js build output .next out # Nuxt.js build / generate output .nuxt dist # Gatsby files .cache/ # Comment in the public line in if your project uses Gatsby and not Next.js # https://nextjs.org/blog/next-9-1#public-directory-support # public # vuepress build output .vuepress/dist # vuepress v2.x temp and cache directory .temp .cache # Docusaurus cache and generated files .docusaurus # Serverless directories .serverless/ # FuseBox cache .fusebox/ # DynamoDB Local files .dynamodb/ # TernJS port file .tern-port # Stores VSCode versions used for testing VSCode extensions .vscode-test # yarn v2 .yarn/cache .yarn/unplugged .yarn/build-state.yml .yarn/install-state.gz .pnp.* .turbo ``` -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- ``` # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class # C extensions *.so # Distribution / packaging .Python build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ wheels/ share/python-wheels/ *.egg-info/ .installed.cfg *.egg MANIFEST # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .nox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *.cover *.py,cover .hypothesis/ .pytest_cache/ cover/ # Translations *.mo *.pot # Django stuff: *.log local_settings.py db.sqlite3 db.sqlite3-journal # Flask stuff: instance/ .webassets-cache # Scrapy stuff: .scrapy # Sphinx documentation docs/_build/ # PyBuilder .pybuilder/ target/ # Jupyter Notebook .ipynb_checkpoints # IPython profile_default/ ipython_config.py # pyenv # For a library or package, you might want to ignore these files since the code is # intended to run in multiple environments; otherwise, check them in: # .python-version # pipenv # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. # However, in case of collaboration, if having platform-specific dependencies or dependencies # having no cross-platform support, pipenv may install dependencies that don't work, or not # install all needed dependencies. #Pipfile.lock # poetry # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. # This is especially recommended for binary packages to ensure reproducibility, and is more # commonly ignored for libraries. # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control #poetry.lock # pdm # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. #pdm.lock # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it # in version control. # https://pdm.fming.dev/#use-with-ide .pdm.toml # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm __pypackages__/ # Celery stuff celerybeat-schedule celerybeat.pid # SageMath parsed files *.sage.py # Environments .env .venv env/ venv/ ENV/ env.bak/ venv.bak/ # Spyder project settings .spyderproject .spyproject # Rope project settings .ropeproject # mkdocs documentation /site # mypy .mypy_cache/ .dmypy.json dmypy.json # Pyre type checker .pyre/ # pytype static type analyzer .pytype/ # Cython debug symbols cython_debug/ # PyCharm # JetBrains specific template is maintained in a separate JetBrains.gitignore that can # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore # and can be added to the global gitignore or merged into this file. For a more nuclear # option (not recommended) you can uncomment the following to ignore the entire idea folder. #.idea/ ``` -------------------------------------------------------------------------------- /typescript/examples/ai-sdk/README.md: -------------------------------------------------------------------------------- ```markdown # AI SDK Example ## Setup Copy the `.env.template` and populate with your values. ``` cp .env.template .env ``` ## Usage ``` npx ts-node index.ts --env ``` ``` -------------------------------------------------------------------------------- /typescript/examples/openai/README.md: -------------------------------------------------------------------------------- ```markdown # OpenAI Example ## Setup Copy the `.env.template` and populate with your values. ``` cp .env.template .env ``` ## Usage ``` npx ts-node index.ts --env ``` ``` -------------------------------------------------------------------------------- /typescript/examples/langchain/README.md: -------------------------------------------------------------------------------- ```markdown # LangChain Example ## Setup Copy the `.env.template` and populate with your values. ``` cp .env.template .env ``` ## Usage ``` npx ts-node index.ts --env ``` ``` -------------------------------------------------------------------------------- /typescript/README.md: -------------------------------------------------------------------------------- ```markdown # Maton Agent Toolkit - TypeScript The Maton Agent Toolkit enables popular agent frameworks including LangChain and Vercel's AI SDK to integrate with Maton APIs through function calling. It also provides tooling to quickly integrate metered billing for prompt and completion token usage. To get started, get your API key in your [Maton Dashboard][api-keys] and check out [documentation][docs]. ## Installation You don't need this source code unless you want to modify the package. If you just want to use the package run: ``` npm install @maton/agent-toolkit ``` ### Requirements - Node 18+ ### Usage ## Model Context Protocol The Maton Agent Toolkit also supports the [Model Context Protocol (MCP)](https://modelcontextprotocol.com/). To run the Maton MCP server using npx, use the following command: ### API Agent (Beta) ```bash # To use API agent npx -y @maton/mcp hubspot --agent --api-key=YOUR_MATON_API_KEY ``` ### API Action ```bash # To set up all available API actions npx -y @maton/mcp hubspot --actions=all --api-key=YOUR_MATON_API_KEY # To set up all available API actions npx -y @maton/mcp hubspot --actions=create-contact,list-contacts --api-key=YOUR_MATON_API_KEY ``` Replace `YOUR_MATON_API_KEY` with your actual Maton API key. Or, you could set the MATON_API_KEY in your environment variables. You can get your API key in your [Maton Dashboard][api-keys]. ### Usage with Claude Desktop Add the following to your `claude_desktop_config.json`. See [here](https://modelcontextprotocol.io/quickstart/user) for more details. ``` { "mcpServers": { "maton": { "command": "npx", "args": [ "-y", "@maton/mcp@latest", "hubspot", "--actions=all", "--api-key=YOUR_MATON_API_KEY" ] } } } ``` Make sure to replace `YOUR_MATON_API_KEY` with your actual Maton API key. Alternatively, you could set the MATON_API_KEY in `env` variables. You can get your API key in your [Maton Dashboard][api-keys]. ## Available API actions | App | Action | | ----------------- | ------------------------------------- | | `airtable` | `list-bases` | | `airtable` | `list-records` | | `airtable` | `list-tables` | | `asana` | `create-task` | | `asana` | `get-task` | | `asana` | `list-projects` | | `asana` | `list-tasks` | | `asana` | `list-workspaces` | | `aws` | `get-s3-object` | | `aws` | `list-s3-buckets` | | `aws` | `list-s3-objects` | | `calendly` | `get-event` | | `calendly` | `list-event-invitees` | | `calendly` | `list-event-types` | | `calendly` | `list-events` | | `clickup` | `create-task` | | `clickup` | `delete-task` | | `clickup` | `get-task` | | `clickup` | `list-folders` | | `clickup` | `list-lists` | | `clickup` | `list-spaces` | | `clickup` | `list-tasks` | | `clickup` | `list-workspaces` | | `google-calendar` | `create-event` | | `google-calendar` | `delete-event` | | `google-calendar` | `get-calendar` | | `google-calendar` | `get-event` | | `google-calendar` | `list-calendars` | | `google-calendar` | `list-events` | | `google-calendar` | `update-event` | | `google-docs` | `append-text` | | `google-docs` | `create-document` | | `google-docs` | `find-document` | | `google-docs` | `get-document` | | `google-drive` | `create-file` | | `google-drive` | `create-folder` | | `google-drive` | `delete-file` | | `google-drive` | `find-file` | | `google-drive` | `find-folder` | | `google-drive` | `get-file` | | `google-drive` | `list-files` | | `google-mail` | `add-label-to-email` | | `google-mail` | `create-draft` | | `google-mail` | `find-email` | | `google-mail` | `list-labels` | | `google-mail` | `send-email` | | `google-mail` | `remove-label-from-email` | | `google-sheet` | `add-column` | | `google-sheet` | `add-multiple-rows` | | `google-sheet` | `clear-cell` | | `google-sheet` | `clear-rows` | | `google-sheet` | `create-spreadsheet` | | `google-sheet` | `create-worksheet` | | `google-sheet` | `delete-rows` | | `google-sheet` | `delete-worksheet` | | `google-sheet` | `find-row` | | `google-sheet` | `get-cell` | | `google-sheet` | `get-spreadsheet` | | `google-sheet` | `get-values-in-range` | | `google-sheet` | `list-worksheets` | | `google-sheet` | `update-cell` | | `google-sheet` | `update-multiple-rows` | | `google-sheet` | `update-row` | | `hubspot` | `create-contact` | | `hubspot` | `get-contact` | | `hubspot` | `list-contacts` | | `hubspot` | `search-contacts` | | `hubspot` | `merge-contacts` | | `hubspot` | `update-contact` | | `hubspot` | `delete-contact` | | `hubspot` | `create-deal` | | `hubspot` | `get-deal` | | `hubspot` | `list-deals` | | `hubspot` | `search-deals` | | `hubspot` | `merge-deals` | | `hubspot` | `update-deal` | | `hubspot` | `delete-deal` | | `jira` | `list-clouds` | | `jira` | `get-issue` | | `jira` | `list-issues` | | `jira` | `add-comment-to-issue` | | `jira` | `list-comments` | | `jira` | `update-comment` | | `jira` | `list-projects` | | `jira` | `get-user` | | `jira` | `list-users` | | `jotform` | `list-forms` | | `jotform` | `list-submissions` | | `klaviyo` | `add-profiles-to-list` | | `klaviyo` | `assign-template-to-campaign-message` | | `klaviyo` | `create-campaign` | | `klaviyo` | `create-list` | | `klaviyo` | `create-profile` | | `klaviyo` | `create-template` | | `klaviyo` | `get-campaign-messages` | | `klaviyo` | `get-campaign-send-job` | | `klaviyo` | `get-campaigns` | | `klaviyo` | `get-lists` | | `klaviyo` | `get-profiles-for-list` | | `klaviyo` | `get-profiles` | | `klaviyo` | `get-templates` | | `klaviyo` | `send-campaign` | | `mailchimp` | `get-campaign` | | `mailchimp` | `search-campaign` | | `notion` | `create-page` | | `notion` | `find-page` | | `notion` | `get-page` | | `outlook` | `create-draft` | | `outlook` | `find-email` | | `outlook` | `send-email` | | `pipedrive` | `search-people` | | `salesforce` | `create-contact` | | `salesforce` | `get-contact` | | `salesforce` | `list-contacts` | | `shopify` | `create-order` | | `shopify` | `get-order` | | `shopify` | `list-orders` | | `slack` | `list-channels` | | `slack` | `list-messages` | | `slack` | `list-replies` | | `slack` | `send-message` | | `stripe` | `create-customer` | | `stripe` | `create-invoice-item` | | `stripe` | `create-invoice` | | `stripe` | `delete-customer` | | `stripe` | `get-customer` | | `stripe` | `get-invoice` | | `stripe` | `list-customers` | | `stripe` | `list-invoices` | | `typeform` | `get-form` | | `typeform` | `list-forms` | | `typeform` | `list-responses` | | `youtube` | `list-videos` | | `youtube` | `search-videos` | [api-keys]: https://maton.ai/api-keys [docs]: https://maton.ai/docs/api-reference ``` -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- ```markdown # Maton Agent Toolkit The Maton Agent Toolkit enables popular agent frameworks including Model Context Protocol (MCP) to integrate with Maton APIs through function calling. The library is not exhaustive of the entire Maton API. It includes support for Typescript. The toolkit was inspired by [Stripe Agent Toolkit][stripe-agent-toolkit], and its implementation shares similarities with the Stripe Agent Toolkit codebase. Included below are basic instructions, but refer to the [TypeScript](/typescript) package for more information. To get started, get your API key in your [Maton Dashboard][api-keys] and check out [documentation][docs]. ## TypeScript ### Installation You don't need this source code unless you want to modify the package. If you just want to use the package run: ``` npm install @maton/agent-toolkit ``` #### Requirements - Node 18+ ### Usage ## Model Context Protocol The Maton Agent Toolkit also supports the [Model Context Protocol (MCP)](https://modelcontextprotocol.com/). To run the Maton MCP server using npx, use the following command: ### API Agent (Beta) ```bash # To use API agent npx -y @maton/mcp hubspot --agent --api-key=YOUR_MATON_API_KEY ``` ### API Action ```bash # To set up all available API actions npx -y @maton/mcp hubspot --actions=all --api-key=YOUR_MATON_API_KEY # To set up all available API actions npx -y @maton/mcp hubspot --actions=create-contact,list-contacts --api-key=YOUR_MATON_API_KEY ``` Replace `YOUR_MATON_API_KEY` with your actual Maton API key. Or, you could set the MATON_API_KEY in your environment variables. You can get your API key in your [Maton Dashboard][api-keys]. ### Usage with Claude Desktop Add the following to your `claude_desktop_config.json`. See [here](https://modelcontextprotocol.io/quickstart/user) for more details. ``` { "mcpServers": { "maton": { "command": "npx", "args": [ "-y", "@maton/mcp@latest", "hubspot", "--actions=all", "--api-key=YOUR_MATON_API_KEY" ] } } } ``` Make sure to replace `YOUR_MATON_API_KEY` with your actual Maton API key. Alternatively, you could set the MATON_API_KEY in `env` variables. You can get your API key in your [Maton Dashboard][api-keys]. ## Available API actions | App | Action | | ----------------- | ------------------------------------- | | `airtable` | `list-bases` | | `airtable` | `list-records` | | `airtable` | `list-tables` | | `asana` | `create-task` | | `asana` | `get-task` | | `asana` | `list-projects` | | `asana` | `list-tasks` | | `asana` | `list-workspaces` | | `aws` | `get-s3-object` | | `aws` | `list-s3-buckets` | | `aws` | `list-s3-objects` | | `calendly` | `get-event` | | `calendly` | `list-event-invitees` | | `calendly` | `list-event-types` | | `calendly` | `list-events` | | `clickup` | `create-task` | | `clickup` | `delete-task` | | `clickup` | `get-task` | | `clickup` | `list-folders` | | `clickup` | `list-lists` | | `clickup` | `list-spaces` | | `clickup` | `list-tasks` | | `clickup` | `list-workspaces` | | `google-calendar` | `create-event` | | `google-calendar` | `delete-event` | | `google-calendar` | `get-calendar` | | `google-calendar` | `get-event` | | `google-calendar` | `list-calendars` | | `google-calendar` | `list-events` | | `google-calendar` | `update-event` | | `google-docs` | `append-text` | | `google-docs` | `create-document` | | `google-docs` | `find-document` | | `google-docs` | `get-document` | | `google-drive` | `create-file` | | `google-drive` | `create-folder` | | `google-drive` | `delete-file` | | `google-drive` | `find-file` | | `google-drive` | `find-folder` | | `google-drive` | `get-file` | | `google-drive` | `list-files` | | `google-mail` | `add-label-to-email` | | `google-mail` | `create-draft` | | `google-mail` | `find-email` | | `google-mail` | `list-labels` | | `google-mail` | `send-email` | | `google-mail` | `remove-label-from-email` | | `google-sheet` | `add-column` | | `google-sheet` | `add-multiple-rows` | | `google-sheet` | `clear-cell` | | `google-sheet` | `clear-rows` | | `google-sheet` | `create-spreadsheet` | | `google-sheet` | `create-worksheet` | | `google-sheet` | `delete-rows` | | `google-sheet` | `delete-worksheet` | | `google-sheet` | `find-row` | | `google-sheet` | `get-cell` | | `google-sheet` | `get-spreadsheet` | | `google-sheet` | `get-values-in-range` | | `google-sheet` | `list-worksheets` | | `google-sheet` | `update-cell` | | `google-sheet` | `update-multiple-rows` | | `google-sheet` | `update-row` | | `hubspot` | `create-contact` | | `hubspot` | `get-contact` | | `hubspot` | `list-contacts` | | `hubspot` | `search-contacts` | | `hubspot` | `merge-contacts` | | `hubspot` | `update-contact` | | `hubspot` | `delete-contact` | | `hubspot` | `create-deal` | | `hubspot` | `get-deal` | | `hubspot` | `list-deals` | | `hubspot` | `search-deals` | | `hubspot` | `merge-deals` | | `hubspot` | `update-deal` | | `hubspot` | `delete-deal` | | `jira` | `list-clouds` | | `jira` | `get-issue` | | `jira` | `list-issues` | | `jira` | `add-comment-to-issue` | | `jira` | `list-comments` | | `jira` | `update-comment` | | `jira` | `list-projects` | | `jira` | `get-user` | | `jira` | `list-users` | | `jotform` | `list-forms` | | `jotform` | `list-submissions` | | `klaviyo` | `add-profiles-to-list` | | `klaviyo` | `assign-template-to-campaign-message` | | `klaviyo` | `create-campaign` | | `klaviyo` | `create-list` | | `klaviyo` | `create-profile` | | `klaviyo` | `create-template` | | `klaviyo` | `get-campaign-messages` | | `klaviyo` | `get-campaign-send-job` | | `klaviyo` | `get-campaigns` | | `klaviyo` | `get-lists` | | `klaviyo` | `get-profiles-for-list` | | `klaviyo` | `get-profiles` | | `klaviyo` | `get-templates` | | `klaviyo` | `send-campaign` | | `mailchimp` | `get-campaign` | | `mailchimp` | `search-campaign` | | `notion` | `create-page` | | `notion` | `find-page` | | `notion` | `get-page` | | `outlook` | `create-draft` | | `outlook` | `find-email` | | `outlook` | `send-email` | | `pipedrive` | `search-people` | | `salesforce` | `create-contact` | | `salesforce` | `get-contact` | | `salesforce` | `list-contacts` | | `shopify` | `create-order` | | `shopify` | `get-order` | | `shopify` | `list-orders` | | `slack` | `list-channels` | | `slack` | `list-messages` | | `slack` | `list-replies` | | `slack` | `send-message` | | `stripe` | `create-customer` | | `stripe` | `create-invoice-item` | | `stripe` | `create-invoice` | | `stripe` | `delete-customer` | | `stripe` | `get-customer` | | `stripe` | `get-invoice` | | `stripe` | `list-customers` | | `stripe` | `list-invoices` | | `typeform` | `get-form` | | `typeform` | `list-forms` | | `typeform` | `list-responses` | | `youtube` | `list-videos` | | `youtube` | `search-videos` | [api-keys]: https://maton.ai/api-keys [docs]: https://maton.ai/docs/api-reference [stripe-agent-toolkit]: https://github.com/stripe/agent-toolkit ``` -------------------------------------------------------------------------------- /modelcontextprotocol/README.md: -------------------------------------------------------------------------------- ```markdown # Maton Model Context Protocol The Maton [Model Context Protocol](https://modelcontextprotocol.com/) server allows you to integrate with Maton APIs through function calling. This protocol supports various apps and actions to interact with different Maton services. You can get your API key in your [Maton Dashboard][api-keys] and check out [documentation][docs]. ## Setup To run the Maton MCP server using npx, use the following command: ### API Agent (Beta) ```bash # To use API agent npx -y @maton/mcp hubspot --agent --api-key=YOUR_MATON_API_KEY ``` ### API Action ```bash # To set up all available API actions npx -y @maton/mcp hubspot --actions=all --api-key=YOUR_MATON_API_KEY # To set up all available API actions npx -y @maton/mcp hubspot --actions=create-contact,list-contacts --api-key=YOUR_MATON_API_KEY ``` Make sure to replace `YOUR_MATON_API_KEY` with your actual Maton API key. Alternatively, you could set the MATON_API_KEY in your environment variables. You can get your API key in your [Maton Dashboard][api-keys]. ### Usage with Claude Desktop Add the following to your `claude_desktop_config.json`. See [here](https://modelcontextprotocol.io/quickstart/user) for more details. ``` { "mcpServers": { "maton": { "command": "npx", "args": [ "-y", "@maton/mcp@latest", "hubspot", "--actions=all", "--api-key=YOUR_MATON_API_KEY" ] } } } ``` Make sure to replace `YOUR_MATON_API_KEY` with your actual Maton API key. Alternatively, you could set the MATON_API_KEY in `env` variables. You can get your API key in your [Maton Dashboard][api-keys]. ## Debugging the Server To debug your server, you can use the [MCP Inspector](https://modelcontextprotocol.io/docs/tools/inspector). First build the server ``` npm run build ``` Run the following command in your terminal: ```bash # Start MCP Inspector and server with all tools npx @modelcontextprotocol/inspector node dist/index.js salesforce --actions=all --api-key=YOUR_MATON_API_KEY ``` ### Instructions 1. Replace `YOUR_MATON_API_KEY` with your actual Maton API secret key. 2. Run the command to start the MCP Inspector. 3. Open the MCP Inspector UI in your browser and click Connect to start the MCP server. 4. You can see the list of tools you selected and test each tool individually. ## Available API actions | App | Action | | ----------------- | ------------------------------------- | | `airtable` | `list-bases` | | `airtable` | `list-records` | | `airtable` | `list-tables` | | `asana` | `create-task` | | `asana` | `get-task` | | `asana` | `list-projects` | | `asana` | `list-tasks` | | `asana` | `list-workspaces` | | `aws` | `get-s3-object` | | `aws` | `list-s3-buckets` | | `aws` | `list-s3-objects` | | `calendly` | `get-event` | | `calendly` | `list-event-invitees` | | `calendly` | `list-event-types` | | `calendly` | `list-events` | | `clickup` | `create-task` | | `clickup` | `delete-task` | | `clickup` | `get-task` | | `clickup` | `list-folders` | | `clickup` | `list-lists` | | `clickup` | `list-spaces` | | `clickup` | `list-tasks` | | `clickup` | `list-workspaces` | | `google-calendar` | `create-event` | | `google-calendar` | `delete-event` | | `google-calendar` | `get-calendar` | | `google-calendar` | `get-event` | | `google-calendar` | `list-calendars` | | `google-calendar` | `list-events` | | `google-calendar` | `update-event` | | `google-docs` | `append-text` | | `google-docs` | `create-document` | | `google-docs` | `find-document` | | `google-docs` | `get-document` | | `google-drive` | `create-file` | | `google-drive` | `create-folder` | | `google-drive` | `delete-file` | | `google-drive` | `find-file` | | `google-drive` | `find-folder` | | `google-drive` | `get-file` | | `google-drive` | `list-files` | | `google-mail` | `add-label-to-email` | | `google-mail` | `create-draft` | | `google-mail` | `find-email` | | `google-mail` | `list-labels` | | `google-mail` | `send-email` | | `google-mail` | `remove-label-from-email` | | `google-sheet` | `add-column` | | `google-sheet` | `add-multiple-rows` | | `google-sheet` | `clear-cell` | | `google-sheet` | `clear-rows` | | `google-sheet` | `create-spreadsheet` | | `google-sheet` | `create-worksheet` | | `google-sheet` | `delete-rows` | | `google-sheet` | `delete-worksheet` | | `google-sheet` | `find-row` | | `google-sheet` | `get-cell` | | `google-sheet` | `get-spreadsheet` | | `google-sheet` | `get-values-in-range` | | `google-sheet` | `list-worksheets` | | `google-sheet` | `update-cell` | | `google-sheet` | `update-multiple-rows` | | `google-sheet` | `update-row` | | `hubspot` | `create-contact` | | `hubspot` | `get-contact` | | `hubspot` | `list-contacts` | | `hubspot` | `search-contacts` | | `hubspot` | `merge-contacts` | | `hubspot` | `update-contact` | | `hubspot` | `delete-contact` | | `hubspot` | `create-deal` | | `hubspot` | `get-deal` | | `hubspot` | `list-deals` | | `hubspot` | `search-deals` | | `hubspot` | `merge-deals` | | `hubspot` | `update-deal` | | `hubspot` | `delete-deal` | | `jira` | `list-clouds` | | `jira` | `get-issue` | | `jira` | `list-issues` | | `jira` | `add-comment-to-issue` | | `jira` | `list-comments` | | `jira` | `update-comment` | | `jira` | `list-projects` | | `jira` | `get-user` | | `jira` | `list-users` | | `jotform` | `list-forms` | | `jotform` | `list-submissions` | | `klaviyo` | `add-profiles-to-list` | | `klaviyo` | `assign-template-to-campaign-message` | | `klaviyo` | `create-campaign` | | `klaviyo` | `create-list` | | `klaviyo` | `create-profile` | | `klaviyo` | `create-template` | | `klaviyo` | `get-campaign-messages` | | `klaviyo` | `get-campaign-send-job` | | `klaviyo` | `get-campaigns` | | `klaviyo` | `get-lists` | | `klaviyo` | `get-profiles-for-list` | | `klaviyo` | `get-profiles` | | `klaviyo` | `get-templates` | | `klaviyo` | `send-campaign` | | `mailchimp` | `get-campaign` | | `mailchimp` | `search-campaign` | | `notion` | `create-page` | | `notion` | `find-page` | | `notion` | `get-page` | | `outlook` | `create-draft` | | `outlook` | `find-email` | | `outlook` | `send-email` | | `pipedrive` | `search-people` | | `salesforce` | `create-contact` | | `salesforce` | `get-contact` | | `salesforce` | `list-contacts` | | `shopify` | `create-order` | | `shopify` | `get-order` | | `shopify` | `list-orders` | | `slack` | `list-channels` | | `slack` | `list-messages` | | `slack` | `list-replies` | | `slack` | `send-message` | | `stripe` | `create-customer` | | `stripe` | `create-invoice-item` | | `stripe` | `create-invoice` | | `stripe` | `delete-customer` | | `stripe` | `get-customer` | | `stripe` | `get-invoice` | | `stripe` | `list-customers` | | `stripe` | `list-invoices` | | `typeform` | `get-form` | | `typeform` | `list-forms` | | `typeform` | `list-responses` | | `youtube` | `list-videos` | | `youtube` | `search-videos` | [api-keys]: https://maton.ai/api-keys [docs]: https://maton.ai/docs/api-reference ``` -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- ```markdown # Security Policy ### Reporting a vulnerability Please do not open GitHub issues or pull requests - this makes the problem immediately visible to everyone, including malicious actors. Security issues in this open-source project can be safely reported to Maton support ([email protected]). ``` -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- ```markdown # Contributing Contributions of any kind are welcome! If you've found a bug or have a feature request, please feel free to [open an issue](/issues). <!-- We will try and respond to your issue or pull request within a week. --> To make changes yourself, follow these steps: 1. [Fork](https://help.github.com/articles/fork-a-repo/) this repository and [clone](https://help.github.com/articles/cloning-a-repository/) it locally. <!-- 1. TODO add install step(s), e.g. "Run `npm install`" --> <!-- 1. TODO add build step(s), e.g. "Build the library using `npm run build`" --> 2. Make your changes <!-- 1. TODO add test step(s), e.g. "Test your changes with `npm test`" --> 3. Submit a [pull request](https://help.github.com/articles/creating-a-pull-request-from-a-fork/) ## Contributor License Agreement ([CLA](https://en.wikipedia.org/wiki/Contributor_License_Agreement)) Once you have submitted a pull request, sign the CLA by clicking on the badge in the comment from [@CLAassistant](https://github.com/CLAassistant). <img width="910" alt="image" src="https://user-images.githubusercontent.com/62121649/198740836-70aeb322-5755-49fc-af55-93c8e8a39058.png"> <br /> Thanks for contributing to Stripe! :sparkles: ``` -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- ```markdown # Contributor Covenant Code of Conduct ## Our Pledge In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to make participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. ## Our Standards Examples of behavior that contributes to creating a positive environment include: * Using welcoming and inclusive language * Being respectful of differing viewpoints and experiences * Gracefully accepting constructive criticism * Focusing on what is best for the community * Showing empathy towards other community members Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery and unwelcome sexual attention or advances * Trolling, insulting/derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or electronic address, without explicit permission * Other conduct which could reasonably be considered inappropriate in a professional setting ## Our Responsibilities Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. ## Scope This Code of Conduct applies within all project spaces, and it also applies when an individual is representing the project or its community in public spaces. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at [email protected]. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html [homepage]: https://www.contributor-covenant.org For answers to common questions about this code of conduct, see https://www.contributor-covenant.org/faq ``` -------------------------------------------------------------------------------- /typescript/pnpm-workspace.yaml: -------------------------------------------------------------------------------- ```yaml packages: - '.' - 'examples/*' ``` -------------------------------------------------------------------------------- /typescript/src/ai-sdk/index.ts: -------------------------------------------------------------------------------- ```typescript import MatonAgentToolkit from './toolkit'; export {MatonAgentToolkit}; ``` -------------------------------------------------------------------------------- /typescript/src/langchain/index.ts: -------------------------------------------------------------------------------- ```typescript import MatonAgentToolkit from './toolkit'; export {MatonAgentToolkit}; ``` -------------------------------------------------------------------------------- /typescript/src/modelcontextprotocol/index.ts: -------------------------------------------------------------------------------- ```typescript import MatonAgentToolkit from './toolkit'; export {MatonAgentToolkit}; ``` -------------------------------------------------------------------------------- /typescript/src/openai/index.ts: -------------------------------------------------------------------------------- ```typescript import MatonAgentToolkit from './toolkit'; export {MatonAgentToolkit}; ``` -------------------------------------------------------------------------------- /glama.json: -------------------------------------------------------------------------------- ```json { "$schema": "https://glama.ai/mcp/schemas/server.json", "maintainers": [ "byungkyu", "rich-song" ] } ``` -------------------------------------------------------------------------------- /typescript/examples/ai-sdk/tsconfig.json: -------------------------------------------------------------------------------- ```json { "extends": "../../tsconfig.json", "compilerOptions": { "outDir": "dist" }, "include": ["index.ts"], "exclude": ["node_modules", "dist"] } ``` -------------------------------------------------------------------------------- /typescript/examples/langchain/tsconfig.json: -------------------------------------------------------------------------------- ```json { "extends": "../../tsconfig.json", "compilerOptions": { "outDir": "dist" }, "include": ["index.ts"], "exclude": ["node_modules", "dist"] } ``` -------------------------------------------------------------------------------- /typescript/examples/openai/tsconfig.json: -------------------------------------------------------------------------------- ```json { "extends": "../../tsconfig.json", "compilerOptions": { "outDir": "dist" }, "include": ["index.ts"], "exclude": ["node_modules", "dist"] } ``` -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- ```json { "recommendations": [ "EditorConfig.editorconfig", // default "ms-python.python", // intellisense "ms-python.flake8", // linting "charliermarsh.ruff" // formatting ] } ``` -------------------------------------------------------------------------------- /modelcontextprotocol/jest.config.ts: -------------------------------------------------------------------------------- ```typescript import type {Config} from 'jest'; const config: Config = { preset: 'ts-jest', testEnvironment: 'node', roots: ['<rootDir>/src'], testMatch: ['**/test/**/*.ts?(x)'], moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'], }; export default config; ``` -------------------------------------------------------------------------------- /typescript/jest.config.ts: -------------------------------------------------------------------------------- ```typescript import type {Config} from 'jest'; const config: Config = { preset: 'ts-jest', testEnvironment: 'node', roots: ['<rootDir>/src'], testMatch: ['**/test/**/*.ts?(x)'], moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'], }; export default config; ``` -------------------------------------------------------------------------------- /modelcontextprotocol/tsconfig.json: -------------------------------------------------------------------------------- ```json { "compilerOptions": { "target": "ES2022", "module": "Node16", "moduleResolution": "Node16", "outDir": "./dist", "rootDir": "./src", "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true }, "include": ["src/**/*"], "exclude": ["node_modules"] } ``` -------------------------------------------------------------------------------- /typescript/tsconfig.json: -------------------------------------------------------------------------------- ```json { "$schema": "https://json.schemastore.org/tsconfig", "display": "Default", "compilerOptions": { "outDir": "./dist", "target": "es2022", "moduleDetection": "force", "esModuleInterop": true, "skipLibCheck": true, "strict": true, "module": "NodeNext" }, "include": ["**/*.ts"], "exclude": ["node_modules", "examples"] } ``` -------------------------------------------------------------------------------- /modelcontextprotocol/smithery.yaml: -------------------------------------------------------------------------------- ```yaml # Smithery.ai configuration startCommand: type: stdio configSchema: # JSON Schema defining the configuration options for the MCP. {} commandFunction: # A function that produces the CLI command to start the MCP on stdio. |- (config) => ({ "command": "node", "args": [ "dist/index.js" ], "env": {} }) ``` -------------------------------------------------------------------------------- /typescript/src/shared/prompts/pipedrive.ts: -------------------------------------------------------------------------------- ```typescript export const checkConnectionPrompt = ` Check if there is any active connection to the Outlook app. `; export const startConnectionPrompt = ` Start a connection to the Outlook app. Active connections are required to perform actions with the app. `; export const transferAgentPrompt = ` Transfer to the Outlook agent. `; export const searchPeoplePrompt = ` Search people in Pipedrive. `; ``` -------------------------------------------------------------------------------- /typescript/examples/openai/package.json: -------------------------------------------------------------------------------- ```json { "name": "maton-agent-toolkit-examples-openai", "version": "0.1.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "MIT", "dependencies": { "dotenv": "^16.4.5", "openai": "^4.86.1", "@maton/agent-toolkit": "^0.0.8" }, "devDependencies": { "@types/node": "^22.7.4" } } ``` -------------------------------------------------------------------------------- /typescript/src/shared/parameters/jotform.ts: -------------------------------------------------------------------------------- ```typescript import {z} from 'zod'; export const checkConnectionParameters = z.object({}); export const startConnectionParameters = z.object({}); export const transferAgentParameters = z.object({ user_prompt: z.string().describe('The user prompt'), }); export const listFormsParameters = z.object({}); export const listSubmissionsParameters = z.object({ form_id: z.string().describe('The ID of form'), }); ``` -------------------------------------------------------------------------------- /typescript/examples/ai-sdk/package.json: -------------------------------------------------------------------------------- ```json { "name": "exfunc-agent-toolkit-examples-ai-sdk", "version": "0.1.0", "description": "", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "MIT", "dependencies": { "@ai-sdk/openai": "^0.0.63", "@maton/agent-toolkit": "^0.0.8", "ai": "^3.4.7", "dotenv": "^16.4.5" }, "devDependencies": { "@types/node": "^22.7.4" } } ``` -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- ```json { "editor.formatOnSave": true, "python.defaultInterpreterPath": "./venv/bin/python", "[python]": { "editor.defaultFormatter": "charliermarsh.ruff", "editor.codeActionsOnSave": { "source.organizeImports": "never" } }, "[typescript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[json]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "ruff.lint.enable": false } ``` -------------------------------------------------------------------------------- /typescript/src/shared/prompts/youtube.ts: -------------------------------------------------------------------------------- ```typescript export const checkConnectionPrompt = ` Check if there is any active connection to the YouTube app. `; export const startConnectionPrompt = ` Start a connection to the YouTube app. Active connections are required to perform actions with the app. `; export const transferAgentPrompt = ` Transfer to the YouTube agent. `; export const listVideosPrompt = ` List videos in YouTube. `; export const searchVideosPrompt = ` Search videos in YouTube. `; ``` -------------------------------------------------------------------------------- /typescript/src/shared/prompts/jotform.ts: -------------------------------------------------------------------------------- ```typescript export const checkConnectionPrompt = ` Check if there is any active connection to the Jotform app. `; export const startConnectionPrompt = ` Start a connection to the Jotform app. Active connections are required to perform actions with the app. `; export const transferAgentPrompt = ` Transfer to the Jotform agent. `; export const listFormsPrompt = ` List forms in Jotform. `; export const listSubmissionsPrompt = ` List form submissions in Jotform. `; ``` -------------------------------------------------------------------------------- /typescript/src/shared/parameters/mailchimp.ts: -------------------------------------------------------------------------------- ```typescript import {z} from 'zod'; export const checkConnectionParameters = z.object({}); export const startConnectionParameters = z.object({}); export const transferAgentParameters = z.object({ user_prompt: z.string().describe('The user prompt'), }); export const getCampaignParameters = z.object({ campaign_id: z.string().describe('The ID of the campaign'), }); export const searchCampaignsParameters = z.object({ q: z.string().describe('The search query'), }); ``` -------------------------------------------------------------------------------- /typescript/src/shared/prompts/mailchimp.ts: -------------------------------------------------------------------------------- ```typescript export const checkConnectionPrompt = ` Check if there is any active connection to the Mailchimp app. `; export const startConnectionPrompt = ` Start a connection to the Mailchimp app. Active connections are required to perform actions with the app. `; export const transferAgentPrompt = ` Transfer to the Mailchimp agent. `; export const getCampaignPrompt = ` Get campaign in Mailchimp. `; export const searchCampaignPrompt = ` Search campaign in Mailchimp. `; ``` -------------------------------------------------------------------------------- /typescript/src/shared/parameters/pipedrive.ts: -------------------------------------------------------------------------------- ```typescript import {z} from 'zod'; export const checkConnectionParameters = z.object({}); export const startConnectionParameters = z.object({}); export const transferAgentParameters = z.object({ user_prompt: z.string().describe('The user prompt'), }); export const searchPeopleParameters = z.object({ q: z.string().describe('The search query'), max_results: z .number() .describe('The maximum number of results to return. Default is 20.') .optional(), }); ``` -------------------------------------------------------------------------------- /typescript/src/ai-sdk/tool.ts: -------------------------------------------------------------------------------- ```typescript import type {CoreTool} from 'ai'; import {tool} from 'ai'; import {z} from 'zod'; import MatonAPI from '../shared/api'; export default function MatonTool( matonAPI: MatonAPI, method: string, description: string, schema: z.ZodObject<any, any, any, any, {[x: string]: any}> ): CoreTool { return tool({ description: description, parameters: schema, execute: (arg: z.output<typeof schema>) => { return matonAPI.run(method, arg); }, }); } ``` -------------------------------------------------------------------------------- /typescript/src/shared/prompts/notion.ts: -------------------------------------------------------------------------------- ```typescript export const checkConnectionPrompt = ` Check if there is any active connection to the Notion app. `; export const startConnectionPrompt = ` Start a connection to the Notion app. Active connections are required to perform actions with the app. `; export const transferAgentPrompt = ` Transfer to the Notion agent. `; export const createPagePrompt = ` Create a page in Notion. `; export const findPagePrompt = ` Find page in Notion. `; export const getPagePrompt = ` Get a page in Notion. `; ``` -------------------------------------------------------------------------------- /typescript/src/shared/prompts/outlook.ts: -------------------------------------------------------------------------------- ```typescript export const checkConnectionPrompt = ` Check if there is any active connection to the Outlook app. `; export const startConnectionPrompt = ` Start a connection to the Outlook app. Active connections are required to perform actions with the app. `; export const transferAgentPrompt = ` Transfer to the Outlook agent. `; export const createDraftPrompt = ` Create draft in Outlook. `; export const findEmailPrompt = ` Find email in Outlook. `; export const sendEmailPrompt = ` Send email in Outlook. `; ``` -------------------------------------------------------------------------------- /typescript/src/shared/prompts/shopify.ts: -------------------------------------------------------------------------------- ```typescript export const checkConnectionPrompt = ` Check if there is any active connection to the Shopify app. `; export const startConnectionPrompt = ` Start a connection to the Shopify app. Active connections are required to perform actions with the app. `; export const transferAgentPrompt = ` Transfer to the Shopify agent. `; export const createOrderPrompt = ` Create order in Shopify. `; export const getOrderPrompt = ` Get order in Shopify. `; export const listOrdersPrompt = ` List orders in Shopify. `; ``` -------------------------------------------------------------------------------- /typescript/examples/langchain/package.json: -------------------------------------------------------------------------------- ```json { "name": "exfunc-agent-toolkit-examples-langchain", "version": "0.1.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "MIT", "dependencies": { "@langchain/core": "^0.3.43", "@langchain/langgraph": "^0.2.62", "@langchain/openai": "^0.3.17", "@maton/agent-toolkit": "^0.0.8", "dotenv": "^16.4.5", "langchain": "^0.3.2" }, "devDependencies": { "@types/node": "^22.7.4" } } ``` -------------------------------------------------------------------------------- /typescript/src/shared/prompts/typeform.ts: -------------------------------------------------------------------------------- ```typescript export const checkConnectionPrompt = ` Check if there is any active connection to the Typeform app. `; export const startConnectionPrompt = ` Start a connection to the Typeform app. Active connections are required to perform actions with the app. `; export const transferAgentPrompt = ` Transfer to the Typeform agent. `; export const getFormPrompt = ` Get form in Typeform. `; export const listFormsPrompt = ` List forms in Typeform. `; export const listResponsesPrompt = ` List responses in a form in Typeform. `; ``` -------------------------------------------------------------------------------- /typescript/examples/ai-sdk/index.ts: -------------------------------------------------------------------------------- ```typescript import {MatonAgentToolkit} from '@maton/agent-toolkit/ai-sdk'; import {openai} from '@ai-sdk/openai'; import {generateText} from 'ai'; require('dotenv').config(); const matonAgentToolkit = new MatonAgentToolkit({ app: 'hubspot', actions: ['create-contact', 'list-contacts'], }); (async () => { const result = await generateText({ model: openai('gpt-4o-mini'), tools: { ...matonAgentToolkit.getTools(), }, maxSteps: 10, prompt: 'create contact for [email protected] and list contacts', }); console.log(result.text); })(); ``` -------------------------------------------------------------------------------- /typescript/src/shared/prompts/airtable.ts: -------------------------------------------------------------------------------- ```typescript export const checkConnectionPrompt = ` Check if there is any active connection to the Airtable app. `; export const startConnectionPrompt = ` Start a connection to the Airtable app. Active connections are required to perform actions with the app. `; export const transferAgentPrompt = ` Transfer to the Airtable agent. `; export const listBasesPrompt = ` This tool will list bases in Airtable. `; export const listRecordsPrompt = ` This tool will list records in a table in Airtable. `; export const listTablesPrompt = ` This tool will list tables in Airtable. `; ``` -------------------------------------------------------------------------------- /typescript/src/shared/prompts/aws.ts: -------------------------------------------------------------------------------- ```typescript export const checkConnectionPrompt = ` Check if there is any active connection to the AWS app. `; export const startConnectionPrompt = ` Start a connection to the AWS app. Active connections are required to perform actions with the app. `; export const transferAgentPrompt = ` Transfer to the AWS agent. `; export const getS3ObjectPrompt = ` This tool will get an S3 object through a presigned URL. `; export const listS3BucketsPrompt = ` This tool will list all S3 buckets in the account. `; export const listS3ObjectsPrompt = ` This tool will list all S3 objects in a bucket. `; ``` -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- ```dockerfile FROM node:22.12-alpine AS builder COPY modelcontextprotocol /app COPY modelcontextprotocol/tsconfig.json /tsconfig.json WORKDIR /app RUN --mount=type=cache,target=/root/.npm npm install RUN --mount=type=cache,target=/root/.npm-production npm ci --ignore-scripts --omit-dev FROM node:22-alpine AS release COPY --from=builder /app/dist /app/dist COPY --from=builder /app/package.json /app/package.json COPY --from=builder /app/package-lock.json /app/package-lock.json ENV NODE_ENV=production WORKDIR /app RUN npm ci --ignore-scripts --omit-dev ENTRYPOINT ["node", "dist/index.js"] ``` -------------------------------------------------------------------------------- /modelcontextprotocol/Dockerfile: -------------------------------------------------------------------------------- ```dockerfile FROM node:22.12-alpine AS builder COPY modelcontextprotocol /app COPY modelcontextprotocol/tsconfig.json /tsconfig.json WORKDIR /app RUN --mount=type=cache,target=/root/.npm npm install RUN --mount=type=cache,target=/root/.npm-production npm ci --ignore-scripts --omit-dev FROM node:22-alpine AS release COPY --from=builder /app/dist /app/dist COPY --from=builder /app/package.json /app/package.json COPY --from=builder /app/package-lock.json /app/package-lock.json ENV NODE_ENV=production WORKDIR /app RUN npm ci --ignore-scripts --omit-dev ENTRYPOINT ["node", "dist/index.js"] ``` -------------------------------------------------------------------------------- /typescript/src/shared/parameters/airtable.ts: -------------------------------------------------------------------------------- ```typescript import {z} from 'zod'; export const checkConnectionParameters = z.object({}); export const startConnectionParameters = z.object({}); export const transferAgentParameters = z.object({ user_prompt: z.string().describe('The user prompt'), }); export const listBasesParameters = z.object({}); export const listRecordsParameters = z.object({ base_id: z.string().describe('The base ID of the Airtable app'), table_id: z.string().describe('The ID of the table'), }); export const listTablesParameters = z.object({ base_id: z.string().describe('The base ID of the Airtable app'), }); ``` -------------------------------------------------------------------------------- /typescript/src/shared/prompts/salesforce.ts: -------------------------------------------------------------------------------- ```typescript export const checkConnectionPrompt = ` Check if there is any active connection to the salesforce app. `; export const startConnectionPrompt = ` Start a connection to the salesforce app. Active connections are required to perform actions with the app. `; export const transferAgentPrompt = ` Transfer to the Salesforce agent. `; export const createContactPrompt = ` This tool will create a contact in Salesforce. `; export const getContactPrompt = ` This tool will get a contact from Salesforce. `; export const listContactsPrompt = ` This tool will list all contacts in Salesforce. `; ``` -------------------------------------------------------------------------------- /typescript/src/shared/parameters/aws.ts: -------------------------------------------------------------------------------- ```typescript import {z} from 'zod'; export const checkConnectionParameters = z.object({}); export const startConnectionParameters = z.object({}); export const transferAgentParameters = z.object({ user_prompt: z.string().describe('The user prompt'), }); export const getS3ObjectParameters = z.object({ bucket_name: z.string().describe('The name of the S3 bucket'), object_key: z.string().describe('The key of the S3 object'), }); export const listS3BucketsParameters = z.object({}); export const listS3ObjectsParameters = z.object({ bucket_name: z.string().describe('The name of the S3 bucket'), }); ``` -------------------------------------------------------------------------------- /typescript/src/shared/prompts/slack.ts: -------------------------------------------------------------------------------- ```typescript export const checkConnectionPrompt = ` Check if there is any active connection to the Slack app. `; export const startConnectionPrompt = ` Start a connection to the Slack app. Active connections are required to perform actions with the app. `; export const transferAgentPrompt = ` Transfer to the Slack agent. `; export const listChannelsPrompt = ` List channels for the workspace in Slack. `; export const listMessagesPrompt = ` List messages in a channel in Slack. `; export const listRepliesPrompt = ` List replies in a channel in Slack. `; export const sendMessagePrompt = ` Send message to a channel in Slack. `; ``` -------------------------------------------------------------------------------- /typescript/tsup.config.ts: -------------------------------------------------------------------------------- ```typescript import {defineConfig} from 'tsup'; export default defineConfig([ { entry: ['src/langchain/index.ts'], outDir: 'langchain', format: ['cjs', 'esm'], dts: true, sourcemap: true, }, { entry: ['src/ai-sdk/index.ts'], outDir: 'ai-sdk', format: ['cjs', 'esm'], dts: true, sourcemap: true, }, { entry: ['src/modelcontextprotocol/index.ts'], outDir: 'modelcontextprotocol', format: ['cjs', 'esm'], dts: true, sourcemap: true, }, { entry: ['src/openai/index.ts'], outDir: 'openai', format: ['cjs', 'esm'], dts: true, sourcemap: true, }, ]); ``` -------------------------------------------------------------------------------- /typescript/src/shared/prompts/calendly.ts: -------------------------------------------------------------------------------- ```typescript export const checkConnectionPrompt = ` Check if there is any active connection to the Calendly app. `; export const startConnectionPrompt = ` Start a connection to the Calendly app. Active connections are required to perform actions with the app. `; export const transferAgentPrompt = ` Transfer to the Calendly agent. `; export const getEventPrompt = ` This tool will get an event in Calendly. `; export const listEventInviteesPrompt = ` This tool will list event invitees in Calendly. `; export const listEventTypesPrompt = ` This tool will list event types in Calendly. `; export const listEventsPrompt = ` This tool will list events in Calendly. `; ``` -------------------------------------------------------------------------------- /typescript/src/shared/prompts/google-docs.ts: -------------------------------------------------------------------------------- ```typescript export const checkConnectionPrompt = ` Check if there is any active connection to the Google Docs app. `; export const startConnectionPrompt = ` Start a connection to the Google Docs app. Active connections are required to perform actions with the app. `; export const transferAgentPrompt = ` Transfer to the Google Docs agent. `; export const appendTextPrompt = ` This tool will append text to a Google document. `; export const createDocumentPrompt = ` This tool will create a Google document. `; export const findDocumentPrompt = ` This tool will find a Google document. `; export const getDocumentPrompt = ` This tool will get a Google document. `; ``` -------------------------------------------------------------------------------- /typescript/src/shared/prompts/asana.ts: -------------------------------------------------------------------------------- ```typescript export const checkConnectionPrompt = ` Check if there is any active connection to the Asana app. `; export const startConnectionPrompt = ` Start a connection to the Asana app. Active connections are required to perform actions with the app. `; export const transferAgentPrompt = ` Transfer to the Asana agent. `; export const createTaskPrompt = ` This tool will create a task in Asana. `; export const getTaskPrompt = ` This tool will get a task in Asana. `; export const listProjectsPrompt = ` This tool will list projects in Asana. `; export const listTasksPrompt = ` This tool will list tasks in Asana. `; export const listWorkspacesPrompt = ` This tool will list workspaces in Asana. `; ``` -------------------------------------------------------------------------------- /typescript/src/shared/parameters/notion.ts: -------------------------------------------------------------------------------- ```typescript import {z} from 'zod'; export const checkConnectionParameters = z.object({}); export const startConnectionParameters = z.object({}); export const transferAgentParameters = z.object({ user_prompt: z.string().describe('The user prompt'), }); export const createPageParameters = z.object({ parent_page_id: z .string() .describe('The identifier for a Notion parent page'), title: z.string().describe('The title of the page'), content: z.string().describe('Content of the page'), }); export const findPageParameters = z.object({ title: z.string().describe('The title of the page to search'), }); export const getPageParameters = z.object({ page_id: z.string().describe('The ID of page'), }); ``` -------------------------------------------------------------------------------- /typescript/src/shared/parameters/slack.ts: -------------------------------------------------------------------------------- ```typescript import {z} from 'zod'; export const checkConnectionParameters = z.object({}); export const startConnectionParameters = z.object({}); export const transferAgentParameters = z.object({ user_prompt: z.string().describe('The user prompt'), }); export const listChannelsParameters = z.object({}); export const listMessagesParameters = z.object({ channel_id: z.string().describe('The ID of channel'), }); export const listRepliesParameters = z.object({ channel_id: z.string().describe('The ID of channel'), ts: z.string().describe('The timestamp of the message'), }); export const sendMessageParameters = z.object({ channel_id: z.string().describe('The ID of channel'), text: z.string().describe('The text of the message'), }); ``` -------------------------------------------------------------------------------- /typescript/src/shared/prompts/google-mail.ts: -------------------------------------------------------------------------------- ```typescript export const checkConnectionPrompt = ` Check if there is any active connection to the Gmail app. `; export const startConnectionPrompt = ` Start a connection to the Gmail app. Active connections are required to perform actions with the app. `; export const transferAgentPrompt = ` Transfer to the Gmail agent. `; export const addLabelToEmailPrompt = ` This tool will add label to an email in Gmail. `; export const createDraftPrompt = ` This tool will create draft in Gmail. `; export const findEmailPrompt = ` This tool will find email in Gmail. `; export const listLabelsPrompt = ` This tool will list labels in Gmail. `; export const sendEmailPrompt = ` This tool will send email in Gmail. `; export const removeLabelFromEmailPrompt = ` This tool will remove label from an email in Gmail. `; ``` -------------------------------------------------------------------------------- /typescript/src/shared/parameters/google-docs.ts: -------------------------------------------------------------------------------- ```typescript import {z} from 'zod'; export const checkConnectionParameters = z.object({}); export const startConnectionParameters = z.object({}); export const transferAgentParameters = z.object({ user_prompt: z.string().describe('The user prompt'), }); export const appendTextParameters = z.object({ doc_id: z.string().describe('The ID of Google document'), text: z.string().describe('The text of Google document'), }); export const createDocumentParameters = z.object({ title: z.string().describe('The title of Google document'), text: z.string().describe('The text of Google document'), }); export const findDocumentParameters = z.object({ q: z.string().describe('The search query'), }); export const getDocumentParameters = z.object({ doc_id: z.string().describe('The ID of Google document'), }); ``` -------------------------------------------------------------------------------- /typescript/src/langchain/toolkit.ts: -------------------------------------------------------------------------------- ```typescript import {BaseToolkit} from '@langchain/core/tools'; import MatonTool from './tool'; import MatonAPI from '../shared/api'; import tools from '../shared/tools'; import {isToolAllowed, type Configuration} from '../shared/configuration'; class MatonAgentToolkit implements BaseToolkit { private _maton: MatonAPI; tools: MatonTool[]; constructor(configuration: Configuration) { this._maton = new MatonAPI(configuration.apiKey); const filteredTools = tools.filter((tool) => isToolAllowed(tool, configuration) ); this.tools = filteredTools.map( (tool) => new MatonTool( this._maton, tool.method, tool.description, tool.parameters ) ); } getTools(): MatonTool[] { return this.tools; } } export default MatonAgentToolkit; ``` -------------------------------------------------------------------------------- /typescript/src/shared/parameters/salesforce.ts: -------------------------------------------------------------------------------- ```typescript import {z} from 'zod'; export const checkConnectionParameters = z.object({}); export const startConnectionParameters = z.object({}); export const transferAgentParameters = z.object({ user_prompt: z.string().describe('The user prompt'), }); export const createContactParameters = z.object({ first_name: z.string().describe('The first name of the contact'), last_name: z.string().describe('The last name of the contact'), description: z.string().optional().describe('The description of the contact'), email: z.string().email().optional().describe('The email of the contact'), phone: z.string().optional().describe('The phone number of the contact'), }); export const getContactParameters = z.object({ contact_id: z.string().describe('The ID of the contact'), }); export const listContactsParameters = z.object({}); ``` -------------------------------------------------------------------------------- /typescript/src/shared/parameters/calendly.ts: -------------------------------------------------------------------------------- ```typescript import {z} from 'zod'; export const checkConnectionParameters = z.object({}); export const startConnectionParameters = z.object({}); export const transferAgentParameters = z.object({ user_prompt: z.string().describe('The user prompt'), }); export const getEventParameters = z.object({ event_id: z.string().describe('The ID of the event'), }); export const listEventInviteesParameters = z.object({ event_id: z.string().describe('The ID of the event'), }); export const listEventTypesParameters = z.object({}); export const listEventsParameters = z.object({ invitee: z.string().describe('The email address of the invitee').optional(), status: z .enum(['active', 'cancelled']) .describe('The status of the event') .optional(), max_results: z .number() .describe('The maximum number of results to return. Default: 20.') .optional(), }); ``` -------------------------------------------------------------------------------- /typescript/src/shared/prompts/stripe.ts: -------------------------------------------------------------------------------- ```typescript export const checkConnectionPrompt = ` Check if there is any active connection to the Stripe app. `; export const startConnectionPrompt = ` Start a connection to the Stripe app. Active connections are required to perform actions with the app. `; export const transferAgentPrompt = ` Transfer to the Stripe agent. `; export const createCustomerPrompt = ` Create a customer in Stripe. `; export const createInvoiceItemPrompt = ` Create an invoice item on an invoice in Stripe. `; export const createInvoicePrompt = ` Create an invoice on a customer in Stripe. `; export const deleteCustomerPrompt = ` Delete customer in Stripe. `; export const getCustomerPrompt = ` Get customer in Stripe. `; export const getInvoicePrompt = ` Get an invoice in Stripe. `; export const listCustomersPrompt = ` List customers in Stripe. `; export const listInvoicesPrompt = ` List invoices in Stripe. `; ``` -------------------------------------------------------------------------------- /typescript/src/shared/prompts/google-drive.ts: -------------------------------------------------------------------------------- ```typescript export const checkConnectionPrompt = ` Check if there is any active connection to the Google Drive app. `; export const startConnectionPrompt = ` Start a connection to the Google Drive app. Active connections are required to perform actions with the app. `; export const transferAgentPrompt = ` Transfer to the Google Drive agent. `; export const createFilePrompt = ` This tool will create a file in Google Drive. `; export const createFolderPrompt = ` This tool will create a folder in Google Drive. `; export const deleteFilePrompt = ` This tool will delete a file from Google Drive. `; export const findFilePrompt = ` This tool will find a file in Google Drive. `; export const findFolderPrompt = ` This tool will find a folder in Google Drive. `; export const getFilePrompt = ` This tool will get a file from Google Drive. `; export const listFilesPrompt = ` This tool will list files in Google Drive. `; ``` -------------------------------------------------------------------------------- /typescript/src/ai-sdk/toolkit.ts: -------------------------------------------------------------------------------- ```typescript import MatonAPI from '../shared/api'; import tools from '../shared/tools'; import { checkConfiguration, isToolAllowed, type Configuration, } from '../shared/configuration'; import type {CoreTool} from 'ai'; import MatonTool from './tool'; class MatonAgentToolkit { private _maton: MatonAPI; tools: {[key: string]: CoreTool}; constructor(configuration: Configuration) { this._maton = new MatonAPI(configuration.apiKey); this.tools = {}; checkConfiguration(configuration); const filteredTools = tools.filter((tool) => isToolAllowed(tool, configuration) ); filteredTools.forEach((tool) => { // @ts-ignore this.tools[tool.method] = MatonTool( this._maton, tool.method, tool.description, tool.parameters ); }); } getTools(): {[key: string]: CoreTool} { return this.tools; } } export default MatonAgentToolkit; ``` -------------------------------------------------------------------------------- /typescript/src/shared/prompts/clickup.ts: -------------------------------------------------------------------------------- ```typescript export const checkConnectionPrompt = ` Check if there is any active connection to the ClickUp app. `; export const startConnectionPrompt = ` Start a connection to the ClickUp app. Active connections are required to perform actions with the app. `; export const transferAgentPrompt = ` Transfer to the ClickUp agent. `; export const createTaskPrompt = ` This tool will create a task in ClickUp. `; export const deleteTaskPrompt = ` This tool will delete a task in ClickUp. `; export const getTaskPrompt = ` This tool will get a task in ClickUp. `; export const listFoldersPrompt = ` This tool will list folders in ClickUp. `; export const listListsPrompt = ` This tool will list lists in ClickUp. `; export const listSpacesPrompt = ` This tool will list spaces in ClickUp. `; export const listTasksPrompt = ` This tool will list tasks in ClickUp. `; export const listWorkspacesPrompt = ` This tool will list workspaces in ClickUp. `; ``` -------------------------------------------------------------------------------- /typescript/src/langchain/tool.ts: -------------------------------------------------------------------------------- ```typescript import {z} from 'zod'; import {StructuredTool} from '@langchain/core/tools'; import {CallbackManagerForToolRun} from '@langchain/core/callbacks/manager'; import {RunnableConfig} from '@langchain/core/runnables'; import MatonAPI from '../shared/api'; class MatonTool extends StructuredTool { matonAPI: MatonAPI; method: string; name: string; description: string; schema: z.ZodObject<any, any, any, any>; constructor( MatonAPI: MatonAPI, method: string, description: string, schema: z.ZodObject<any, any, any, any, {[x: string]: any}> ) { super(); this.matonAPI = MatonAPI; this.method = method; this.name = method; this.description = description; this.schema = schema; } _call( arg: z.output<typeof this.schema>, _runManager?: CallbackManagerForToolRun, _parentConfig?: RunnableConfig ): Promise<any> { return this.matonAPI.run(this.method, arg); } } export default MatonTool; ``` -------------------------------------------------------------------------------- /typescript/src/shared/parameters/shopify.ts: -------------------------------------------------------------------------------- ```typescript import {z} from 'zod'; export const checkConnectionParameters = z.object({}); export const startConnectionParameters = z.object({}); export const transferAgentParameters = z.object({ user_prompt: z.string().describe('The user prompt'), }); export const createOrderParameters = z.object({ line_items: z .array( z.object({ title: z.string().describe('The title of the product'), price: z.number().describe('The price of the product'), quantity: z .number() .optional() .describe('The quantity of the product to add to the order'), }) ) .describe('List of dictionaries containing the following keys'), }); export const getOrderParameters = z.object({ order_id: z.string().describe('The ID of the order'), }); export const listOrdersParameters = z.object({ fulfillment_status: z .enum(['shipped', 'partial', 'unshipped']) .optional() .describe('The fulfillment status of the orders'), }); ``` -------------------------------------------------------------------------------- /typescript/src/shared/prompts/google-calendar.ts: -------------------------------------------------------------------------------- ```typescript export const checkConnectionPrompt = ` Check if there is any active connection to the Google Calendar app. `; export const startConnectionPrompt = ` Start a connection to the Google Calendar app. Active connections are required to perform actions with the app. `; export const transferAgentPrompt = ` Transfer to the Google Calendar agent. `; export const createEventPrompt = ` This tool will create an event in a calendar in Google Calendar. `; export const deleteEventPrompt = ` This tool will delete an event in a calendar in Google Calendar. `; export const getCalendarPrompt = ` This tool will get a calendar in Google Calendar. `; export const getEventPrompt = ` This tool will get an event in a calendar in Google Calendar. `; export const listCalendarsPrompt = ` This tool will list calendars in Google Calendar. `; export const listEventsPrompt = ` This tool will list events in a calendar in Google Calendar. `; export const updateEventPrompt = ` This tool will update an event in a calendar in Google Calendar. `; ``` -------------------------------------------------------------------------------- /typescript/src/shared/prompts/jira.ts: -------------------------------------------------------------------------------- ```typescript export const checkConnectionPrompt = ` Check if there is any active connection to the Jira app. `; export const startConnectionPrompt = ` Start a connection to the Jira app. Active connections are required to perform actions with the app. `; export const transferAgentPrompt = ` Transfer to the Jira agent. `; export const listCloudsPrompt = ` This tool will list all clouds in Jira. `; export const getIssuePrompt = ` This tool will get an issue from Jira. `; export const listIssuesPrompt = ` This tool will list issues in Jira. `; export const addCommentToIssuePrompt = ` This tool will add a comment to an issue in Jira. `; export const listCommentsPrompt = ` This tool will list all comments in an issue in Jira. `; export const updateCommentPrompt = ` This tool will update a comment in an issue in Jira. `; export const listProjectsPrompt = ` This tool will list all projects in Jira. `; export const getUserPrompt = ` This tool will get a user from Jira. `; export const listUsersPrompt = ` This tool will list all users in Jira. `; ``` -------------------------------------------------------------------------------- /typescript/src/shared/prompts/klaviyo.ts: -------------------------------------------------------------------------------- ```typescript export const checkConnectionPrompt = ` Check if there is any active connection to the klaviyo app. `; export const startConnectionPrompt = ` Start a connection to the klaviyo app. Active connections are required to perform actions with the app. `; export const transferAgentPrompt = ` Transfer to the klaviyo agent. `; export const addProfilesToListPrompt = ` Add profiles to a list. `; export const assignTemplateToCampaignMessagePrompt = ` Assign a template to a campaign message. `; export const createCampaignPrompt = ` Create a campaign. `; export const createListPrompt = ` Create a list. `; export const createProfilePrompt = ` Create a profile. `; export const createTemplatePrompt = ` Create a template. `; export const getCampaignMessagesPrompt = ` Get messages for campaign. `; export const getCampaignSendJobPrompt = ` Get send job for campaign. `; export const getCampaignsPrompt = ` Get campaigns. `; export const getListsPrompt = ` Get lists. `; export const getProfilesForListPrompt = ` Get profiles for list. `; export const getProfilesPrompt = ` Get profiles. `; export const getTemplatesPrompt = ` Get templates. `; export const sendCampaignPrompt = ` Send campaign. `; ``` -------------------------------------------------------------------------------- /typescript/src/modelcontextprotocol/toolkit.ts: -------------------------------------------------------------------------------- ```typescript import {McpServer} from '@modelcontextprotocol/sdk/server/mcp.js'; import {RequestHandlerExtra} from '@modelcontextprotocol/sdk/shared/protocol.js'; import { Configuration, checkConfiguration, isToolAllowed, } from '../shared/configuration'; import MatonAPI from '../shared/api'; import tools from '../shared/tools'; class MatonAgentToolkit extends McpServer { private _maton: MatonAPI; constructor(configuration: Configuration) { super({ name: 'Maton', version: '0.0.1', }); this._maton = new MatonAPI(configuration.apiKey); checkConfiguration(configuration); const filteredTools = tools.filter((tool) => isToolAllowed(tool, configuration) ); filteredTools.forEach((tool) => { this.tool( tool.method, tool.description, tool.parameters.shape, async (arg: any, _extra: RequestHandlerExtra) => { const result = await this._maton.run(tool.method, arg); return { content: [ { type: 'text' as const, text: String(result), }, ], }; } ); }); } } export default MatonAgentToolkit; ``` -------------------------------------------------------------------------------- /typescript/src/shared/parameters/typeform.ts: -------------------------------------------------------------------------------- ```typescript import {z} from 'zod'; export const checkConnectionParameters = z.object({}); export const startConnectionParameters = z.object({}); export const transferAgentParameters = z.object({ user_prompt: z.string().describe('The user prompt'), }); export const getFormParameters = z.object({ form_id: z.string().describe('The ID of the form'), }); export const listFormsParameters = z.object({ q: z.string().describe('The search query').optional(), page: z.number().describe('The page number').optional(), per_page: z.number().describe('The number of items per page').optional(), }); export const listResponsesParameters = z.object({ form_id: z.string().describe('The ID of the form'), sort: z .string() .describe( 'Responses order in {fieldID},{asc|desc} format. You can use built-in submitted_at/staged_at/landed_at field IDs or any field ID from your typeform, possible directions are asc/desc. Default value is submitted_at,desc for completed responses, staged_at,desc for partial responses and landed_at,desc for started responses.' ) .optional(), q: z.string().describe('The search query').optional(), per_page: z.number().describe('The number of items per page').optional(), }); ``` -------------------------------------------------------------------------------- /typescript/examples/openai/index.ts: -------------------------------------------------------------------------------- ```typescript import {MatonAgentToolkit} from '@maton/agent-toolkit/openai'; import OpenAI from 'openai'; import type {ChatCompletionMessageParam} from 'openai/resources'; require('dotenv').config(); const openai = new OpenAI(); const matonAgentToolkit = new MatonAgentToolkit({ app: 'hubspot', actions: ['create-contact', 'list-contacts'], }); (async (): Promise<void> => { let messages: ChatCompletionMessageParam[] = [ { role: 'user', content: `create contact for [email protected] and list contacts`, }, ]; while (true) { // eslint-disable-next-line no-await-in-loop const completion = await openai.chat.completions.create({ model: 'gpt-4o-mini', messages, tools: matonAgentToolkit.getTools(), }); const message = completion.choices[0].message; messages.push(message); if (message.tool_calls) { console.log(JSON.stringify(message.tool_calls, null, 2)); // eslint-disable-next-line no-await-in-loop const toolMessages = await Promise.all( message.tool_calls.map((tc) => matonAgentToolkit.handleToolCall(tc)) ); messages = [...messages, ...toolMessages]; } else { console.log(completion.choices[0].message); break; } } })(); ``` -------------------------------------------------------------------------------- /typescript/examples/langchain/index.ts: -------------------------------------------------------------------------------- ```typescript import {MatonAgentToolkit} from '@maton/agent-toolkit/langchain'; import {createReactAgent} from '@langchain/langgraph/prebuilt'; import {ChatOpenAI} from '@langchain/openai'; require('dotenv').config(); const llm = new ChatOpenAI({ model: 'o3-mini', }); const matonAgentToolkit = new MatonAgentToolkit({ app: 'hubspot', actions: ['create-contact', 'list-contacts'], }); const agent = createReactAgent({ llm, tools: matonAgentToolkit.getTools(), }); (async (): Promise<void> => { const stream = await agent.stream({ messages: [ ['human', 'create contact for [email protected] and list hubspot contacts'], ], }); for await (const chunk of stream) { if (chunk.agent) { console.log( `================================= AI Message =================================` ); const message = chunk.agent.messages[0]; if (message.tool_calls && message.tool_calls.length > 0) { console.log(JSON.stringify(message.tool_calls, undefined, 2)); } else { console.log(message.content); } } else if (chunk.tools) { console.log( `================================= Tool Message =================================` ); console.log(chunk.tools.messages[0].content); } } })(); ``` -------------------------------------------------------------------------------- /typescript/src/shared/parameters/asana.ts: -------------------------------------------------------------------------------- ```typescript import {z} from 'zod'; export const checkConnectionParameters = z.object({}); export const startConnectionParameters = z.object({}); export const transferAgentParameters = z.object({ user_prompt: z.string().describe('The user prompt'), }); export const createTaskParameters = z.object({ project_id: z.string().describe('The project ID'), name: z.string().describe('Name of the task'), assignee: z.string().describe('The email of the user').optional(), completed: z .boolean() .describe('True if the task is currently marked complete, false if not') .optional(), due_at: z .string() .describe( 'The UTC date and time on which this task is due, or null if the task has no due time. This takes an ISO 8601 date string in UTC and should not be used together with due_on.' ) .optional(), notes: z .string() .describe('Free-form textual information associated with the task'), }); export const getTaskParameters = z.object({ task_id: z.string().describe('The task ID'), }); export const listProjectsParameters = z.object({ workspace_id: z.string().describe('The workspace ID'), }); export const listTasksParameters = z.object({ project_id: z.string().describe('The project ID'), }); export const listWorkspacesParameters = z.object({}); ``` -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- ```yaml name: Release on: workflow_dispatch: {} jobs: python-build: name: Build for PyPi runs-on: ubuntu-latest environment: pypi defaults: run: working-directory: ./python steps: - name: Checkout uses: actions/checkout@v4 - name: Python uses: actions/setup-python@v4 with: python-version: "3.11" - name: Install run: make venv - name: Build run: | set -x source venv/bin/activate rm -rf build dist *.egg-info make build python -m twine check dist/* - name: Test run: | make venv make test - name: Upload artifact uses: actions/upload-artifact@v4 with: name: release-dists path: ./python/dist/ python-release: name: Publish to PyPi runs-on: ubuntu-latest environment: pypi needs: - python-build defaults: run: working-directory: ./python permissions: id-token: write steps: - name: Retrieve distribution uses: actions/download-artifact@v4 with: name: release-dists path: dist/ - name: Publish package distributions to PyPI uses: pypa/gh-action-pypi-publish@release/v1 ``` -------------------------------------------------------------------------------- /typescript/src/shared/parameters/clickup.ts: -------------------------------------------------------------------------------- ```typescript import {z} from 'zod'; export const checkConnectionParameters = z.object({}); export const startConnectionParameters = z.object({}); export const transferAgentParameters = z.object({ user_prompt: z.string().describe('The user prompt'), }); export const createTaskParameters = z.object({ list_id: z.string().describe('The ID of the list'), name: z.string().describe('Name of the task'), description: z.string().describe('Description of the task'), priority: z .enum(['Low', 'Medium', 'High', 'Urgent']) .describe('Priority of the task'), assignees: z.array(z.string()).describe('List of assignees'), due_date: z.string().describe('Due date of the task').optional(), }); export const deleteTaskParameters = z.object({ task_id: z.string().describe('The ID of the task'), }); export const getTaskParameters = z.object({ task_id: z.string().describe('The ID of the task'), }); export const listFoldersParameters = z.object({ space_id: z.string().describe('The ID of the space'), }); export const listListsParameters = z.object({ folder_id: z.string().describe('The ID of the folder'), }); export const listSpacesParameters = z.object({ workspace_id: z.string().describe('The ID of the workspace'), }); export const listTasksParameters = z.object({ list_id: z.string().describe('The ID of the list'), }); export const listWorkspacesParameters = z.object({}); ``` -------------------------------------------------------------------------------- /typescript/src/shared/parameters/google-drive.ts: -------------------------------------------------------------------------------- ```typescript import {z} from 'zod'; export const checkConnectionParameters = z.object({}); export const startConnectionParameters = z.object({}); export const transferAgentParameters = z.object({ user_prompt: z.string().describe('The user prompt'), }); export const createFileParameters = z.object({ content: z.string().describe('The text content of the file to create'), mime_type: z.string().describe('The MIME type of the file to create'), name: z.string().optional().describe('The name of the file to create'), parent_id: z .string() .optional() .describe('The ID of the parent folder to create the file in'), }); export const createFolderParameters = z.object({ parent_id: z .string() .describe('The ID of the parent folder to create the folder in'), }); export const deleteFileParameters = z.object({ file_id: z.string().describe('The ID of the file to delete'), }); export const findFileParameters = z.object({ q: z.string().describe('The search query'), }); export const findFolderParameters = z.object({ q: z.string().describe('The search query'), include_trashed: z .boolean() .optional() .describe('Whether to include trashed folders'), }); export const getFileParameters = z.object({ file_id: z.string().describe('The ID of the file to retrieve'), }); export const listFilesParameters = z.object({ folder_id: z.string().optional().describe('The ID of folder'), }); ``` -------------------------------------------------------------------------------- /modelcontextprotocol/package.json: -------------------------------------------------------------------------------- ```json { "name": "@maton/mcp", "version": "0.0.10", "homepage": "https://github.com/maton-ai/agent-toolkit/tree/main/modelcontextprotocol", "description": "A command line tool for setting up Maton MCP server", "bin": "dist/index.js", "files": [ "dist/index.js", "LICENSE", "README.md", "VERSION", "package.json" ], "scripts": { "build": "tsc && node -e \"require('fs').chmodSync('dist/index.js', '755')\"", "clean": "rm -rf dist", "lint": "eslint \"./**/*.ts*\"", "prettier": "prettier './**/*.{js,ts,md,html,css}' --write", "prettier-check": "prettier './**/*.{js,ts,md,html,css}' --check" }, "packageManager": "[email protected]", "engines": { "node": ">=18" }, "dependencies": { "@modelcontextprotocol/sdk": "^1.4.1", "@maton/agent-toolkit": "latest", "colors": "^1.4.0" }, "keywords": [ "mcp", "modelcontextprotocol", "maton" ], "author": "Maton <[email protected]> (https://maton.ai)", "license": "MIT", "devDependencies": { "@eslint/compat": "^1.2.6", "@types/jest": "^29.5.14", "@types/node": "^22.13.4", "@typescript-eslint/eslint-plugin": "^8.24.1", "eslint-config-prettier": "^10.0.1", "eslint-plugin-import": "^2.31.0", "eslint-plugin-jest": "^28.11.0", "eslint-plugin-prettier": "^5.2.3", "globals": "^15.15.0", "jest": "^29.7.0", "prettier": "^3.5.1", "ts-jest": "^29.2.5", "ts-node": "^10.9.2" } } ``` -------------------------------------------------------------------------------- /typescript/src/shared/parameters/outlook.ts: -------------------------------------------------------------------------------- ```typescript import {z} from 'zod'; export const checkConnectionParameters = z.object({}); export const startConnectionParameters = z.object({}); export const transferAgentParameters = z.object({ user_prompt: z.string().describe('The user prompt'), }); export const createDraftParameters = z.object({ to: z.array(z.string()).describe('List of recipient emails'), subject: z.string().describe('The subject of the email'), body: z.string().describe('The body of the email'), cc: z.array(z.string()).describe('List of emails to CC').optional(), bcc: z.array(z.string()).describe('List of emails to BCC').optional(), body_type: z .enum(['plaintext', 'html']) .describe( 'The type of the email body. Default: plaintext. Possible values are: plaintext, html' ) .optional(), }); export const findEmailParameters = z.object({ q: z.string().describe('The search query'), max_results: z .number() .describe('The maximum number of results to return. Default is 10.') .optional(), }); export const sendEmailParameters = z.object({ to: z.array(z.string()).describe('List of recipient emails'), subject: z.string().describe('The subject of the email'), body: z.string().describe('The body of the email'), cc: z.array(z.string()).describe('List of emails to CC').optional(), bcc: z.array(z.string()).describe('List of emails to BCC').optional(), body_type: z .enum(['plaintext', 'html']) .describe( 'The type of the email body. Default: plaintext. Possible values are: plaintext, html' ) .optional(), }); ``` -------------------------------------------------------------------------------- /typescript/src/shared/parameters/jira.ts: -------------------------------------------------------------------------------- ```typescript import {z} from 'zod'; export const checkConnectionParameters = z.object({}); export const startConnectionParameters = z.object({}); export const transferAgentParameters = z.object({ user_prompt: z.string().describe('The user prompt'), }); export const listCloudsParameters = z.object({}); export const getIssueParameters = z.object({ cloud_id: z.string().describe('The ID of the cloud'), issue_id: z.string().describe('The ID of the issue'), }); export const listIssuesParameters = z.object({ cloud_id: z.string().describe('The ID of the cloud'), }); export const addCommentToIssueParameters = z.object({ cloud_id: z.string().describe('The ID of the cloud'), issue_id: z.string().describe('The ID of the issue'), comment: z.string().describe('The comment to add to the issue'), }); export const listCommentsParameters = z.object({ cloud_id: z.string().describe('The ID of the cloud'), issue_id: z.string().describe('The ID of the issue'), }); export const updateCommentParameters = z.object({ cloud_id: z.string().describe('The ID of the cloud'), issue_id: z.string().describe('The ID of the issue'), comment_id: z.string().describe('The ID of the comment'), comment: z.string().describe('The new comment'), }); export const listProjectsParameters = z.object({ cloud_id: z.string().describe('The ID of the cloud'), }); export const getUserParameters = z.object({ account_id: z.string().describe('The ID of the user account'), }); export const listUsersParameters = z.object({ cloud_id: z.string().describe('The ID of the cloud'), }); ``` -------------------------------------------------------------------------------- /typescript/src/openai/toolkit.ts: -------------------------------------------------------------------------------- ```typescript import MatonAPI from '../shared/api'; import tools from '../shared/tools'; import {isToolAllowed, type Configuration} from '../shared/configuration'; import {zodToJsonSchema} from 'zod-to-json-schema'; import type { ChatCompletionTool, ChatCompletionMessageToolCall, ChatCompletionToolMessageParam, } from 'openai/resources'; class MatonAgentToolkit { private _maton: MatonAPI; tools: ChatCompletionTool[]; constructor(configuration: Configuration) { this._maton = new MatonAPI(configuration.apiKey); const filteredTools = tools.filter((tool) => isToolAllowed(tool, configuration) ); this.tools = filteredTools.map((tool) => ({ type: 'function', function: { name: tool.method, description: tool.description, parameters: zodToJsonSchema(tool.parameters), }, })); } getTools(): ChatCompletionTool[] { return this.tools; } /** * Processes a single OpenAI tool call by executing the requested function. * * @param {ChatCompletionMessageToolCall} toolCall - The tool call object from OpenAI containing * function name, arguments, and ID. * @returns {Promise<ChatCompletionToolMessageParam>} A promise that resolves to a tool message * object containing the result of the tool execution with the proper format for the OpenAI API. */ async handleToolCall(toolCall: ChatCompletionMessageToolCall) { const args = JSON.parse(toolCall.function.arguments); const response = await this._maton.run(toolCall.function.name, args); return { role: 'tool', tool_call_id: toolCall.id, content: response, } as ChatCompletionToolMessageParam; } } export default MatonAgentToolkit; ``` -------------------------------------------------------------------------------- /typescript/src/shared/prompts/google-sheet.ts: -------------------------------------------------------------------------------- ```typescript export const checkConnectionPrompt = ` Check if there is any active connection to the Google Sheets app. `; export const startConnectionPrompt = ` Start a connection to the Google Sheets app. Active connections are required to perform actions with the app. `; export const transferAgentPrompt = ` Transfer to the Google Sheets agent. `; export const addColumnPrompt = ` This tool will add a column to a Google spreadsheet. `; export const addMultipleRowsPrompt = ` This tool will add multiple rows to a Google spreadsheet. `; export const clearCellPrompt = ` This tool will clear a cell in a Google spreadsheet. `; export const clearRowsPrompt = ` This tool will clear multiple rows in a Google spreadsheet. `; export const createSpreadsheetPrompt = ` This tool will create a Google spreadsheet. `; export const createWorksheetPrompt = ` This tool will create a worksheet in a Google spreadsheet. `; export const deleteRowsPrompt = ` This tool will delete multiple rows in a Google spreadsheet. `; export const deleteWorksheetPrompt = ` This tool will delete a worksheet in a Google spreadsheet. `; export const findRowPrompt = ` This tool will find one or more rows by a column and value. `; export const getCellPrompt = ` This tool will get a cell from a Google spreadsheet. `; export const getSpreadsheetPrompt = ` This tool will get a Google spreadsheet. `; export const getValuesInRangePrompt = ` This tool will get values in a range in a Google spreadsheet. `; export const listWorksheetsPrompt = ` This tool will list worksheets in a Google spreadsheet. `; export const updateCellPrompt = ` This tool will update a cell in a Google spreadsheet. `; export const updateMultipleRowsPrompt = ` This tool will update multiple rows in a Google spreadsheet. `; export const updateRowPrompt = ` This tool will update a row in a Google spreadsheet. `; ``` -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- ```yaml name: CI on: workflow_dispatch: {} push: branches: - main pull_request: branches: - main jobs: typescript-build: name: Build - TypeScript runs-on: ubuntu-latest defaults: run: working-directory: ./typescript steps: - name: Checkout uses: actions/checkout@v3 - name: pnpm uses: pnpm/action-setup@v4 with: version: 9.11.0 - name: Node uses: actions/setup-node@v4 with: node-version: "18" - name: Install run: pnpm install --frozen-lockfile - name: Build run: pnpm run build - name: Clean run: pnpm run clean - name: Lint run: pnpm run lint - name: Prettier run: pnpm run prettier-check modelcontextprotocol-build: name: Build - Model Context Protocol runs-on: ubuntu-latest defaults: run: working-directory: ./modelcontextprotocol steps: - name: Checkout uses: actions/checkout@v3 - name: pnpm uses: pnpm/action-setup@v4 with: version: 9.11.0 - name: Node uses: actions/setup-node@v4 with: node-version: "18" - name: Install run: pnpm install --frozen-lockfile - name: Build run: pnpm run build - name: Clean run: pnpm run clean - name: Lint run: pnpm run lint - name: Prettier run: pnpm run prettier-check python-build: name: Build - Python runs-on: ubuntu-latest defaults: run: working-directory: ./python steps: - name: Checkout uses: actions/checkout@v3 - name: Python uses: actions/setup-python@v4 with: python-version: "3.11" - name: Install run: make venv - name: Build run: | set -x source venv/bin/activate rm -rf build dist *.egg-info make build python -m twine check dist/* - name: Test run: | make venv make test ``` -------------------------------------------------------------------------------- /modelcontextprotocol/src/index.ts: -------------------------------------------------------------------------------- ```typescript #!/usr/bin/env node import {MatonAgentToolkit} from '@maton/agent-toolkit/modelcontextprotocol'; import {StdioServerTransport} from '@modelcontextprotocol/sdk/server/stdio.js'; import {green, red, yellow} from 'colors'; type Options = { app?: string; agent?: boolean; actions?: string[]; apiKey?: string; }; const ACCEPTED_ARGS: string[] = ['agent', 'actions', 'api-key']; export function parseArgs(args: string[]): Options { const options: Options = {app: args[0]}; args.slice(1).forEach((arg) => { if (arg.startsWith('--')) { const [key, value] = arg.slice(2).split('='); if (key == 'agent') { options.agent = true; } else if (key == 'actions') { options.actions = value.split(','); } else if (key == 'api-key') { options.apiKey = value; } else { throw new Error( `Invalid argument: ${key}. Accepted arguments are: ${ACCEPTED_ARGS.join( ', ' )}` ); } } }); // Check if API key is either provided in args or set in environment variables const apiKey = options.apiKey || process.env.MATON_API_KEY; if (!apiKey) { throw new Error( 'Maton API key not provided. Please either pass it as an argument --api-key=$KEY or set the MATON_API_KEY environment variable.' ); } options.apiKey = apiKey; return options; } function handleError(error: any) { console.error(red('\n🚨 Error initializing Maton MCP server:\n')); console.error(yellow(` ${error.message}\n`)); } export async function main() { const options = parseArgs(process.argv.slice(2)); const server = new MatonAgentToolkit({ apiKey: options.apiKey, app: options.app, agent: options.agent, actions: options.actions, }); const transport = new StdioServerTransport(); await server.connect(transport); // We use console.error instead of console.log since console.log will output to stdio, which will confuse the MCP server console.error(green('✅ Maton MCP Server running on stdio')); } if (require.main === module) { main().catch((error) => { handleError(error); }); } ``` -------------------------------------------------------------------------------- /typescript/src/shared/parameters/youtube.ts: -------------------------------------------------------------------------------- ```typescript import {z} from 'zod'; export const checkConnectionParameters = z.object({}); export const startConnectionParameters = z.object({}); export const transferAgentParameters = z.object({ user_prompt: z.string().describe('The user prompt'), }); export const listVideosParameters = z.object({ part: z .array( z.enum([ 'auditDetails', 'brandingSettings', 'contentDetails', 'contentOwnerDetails', 'id', 'localizations', 'snippet', 'statistics', 'status', 'topicDetails', ]) ) .describe( 'The part parameter specifies a comma-separated list of one or more resource properties that the API response will include. Possible values are: auditDetails, brandingSettings, contentDetails, contentOwnerDetails, id, localizations, snippet, statistics, status, topicDetails' ), use_case: z .enum(['id', 'myRating', 'chart']) .describe( 'The useCase parameter specifies the type of resource to be returned. Possible values are: id, myRating, chart' ), video_ids: z .array(z.enum(['id', 'myRating', 'chart'])) .optional() .describe( 'The id parameter specifies a comma-separated list of the YouTube video ID(s) for the resource(s) that are being retrieved.' ), my_rating: z .enum(['like', 'dislike']) .optional() .describe( 'The myRating parameter specifies the rating of the authenticated user. Possible values are: like, dislike' ), region_code: z .string() .optional() .describe( 'The regionCode parameter instructs the API to return results for the specified country. The parameter value is an ISO 3166-1 alpha-2 country code. For example: US, GB, BR' ), max_results: z .number() .optional() .describe( 'The maxResults parameter specifies the maximum number of items that should be returned in the result set. Default: 20.' ), }); export const searchVideosParameters = z.object({ q: z.string().describe('The search query'), max_results: z .number() .optional() .describe('The maximum number of results to return. Default: 20.'), }); ``` -------------------------------------------------------------------------------- /typescript/package.json: -------------------------------------------------------------------------------- ```json { "name": "@maton/agent-toolkit", "version": "0.0.10", "homepage": "https://github.com/maton-ai/agent-toolkit", "scripts": { "build": "tsup", "clean": "rm -rf langchain ai-sdk modelcontextprotocol openai", "lint": "eslint \"./**/*.ts*\"", "prettier": "prettier './**/*.{js,ts,md,html,css}' --write", "prettier-check": "prettier './**/*.{js,ts,md,html,css}' --check" }, "exports": { "./langchain": { "types": "./langchain/index.d.ts", "require": "./langchain/index.js", "import": "./langchain/index.mjs" }, "./ai-sdk": { "types": "./ai-sdk/index.d.ts", "require": "./ai-sdk/index.js", "import": "./ai-sdk/index.mjs" }, "./openai": { "types": "./openai/index.d.ts", "require": "./openai/index.js", "import": "./openai/index.mjs" }, "./modelcontextprotocol": { "types": "./modelcontextprotocol/index.d.ts", "require": "./modelcontextprotocol/index.js", "import": "./modelcontextprotocol/index.mjs" } }, "packageManager": "[email protected]", "engines": { "node": ">=18" }, "author": "Maton <[email protected]> (https://maton.ai/)", "contributors": [ "Richard Song <[email protected]>", "Byungkyu Park <[email protected]>" ], "license": "MIT", "devDependencies": { "@eslint/compat": "^1.2.4", "@types/jest": "^29.5.14", "@types/node": "^22.10.5", "@typescript-eslint/eslint-plugin": "^8.19.1", "eslint": "^9.17.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-import": "^2.31.0", "eslint-plugin-jest": "^28.10.0", "eslint-plugin-prettier": "^5.2.1", "globals": "^15.14.0", "jest": "^29.7.0", "prettier": "^3.4.2", "ts-jest": "^29.2.5", "ts-node": "^10.9.2", "tsup": "^8.3.5", "typescript": "^5.7.2" }, "dependencies": { "zod": "^3.24.1", "zod-to-json-schema": "^3.24.3" }, "peerDependencies": { "openai": "^4.86.1", "@langchain/core": "^0.3.6", "@modelcontextprotocol/sdk": "^1.4.1", "ai": "^3.4.7 || ^4.0.0" }, "workspaces": [ ".", "examples/*" ], "files": [ "ai-sdk/**/*", "langchain/**/*", "modelcontextprotocol/**/*", "openai/**/*", "LICENSE", "README.md", "VERSION", "package.json" ] } ``` -------------------------------------------------------------------------------- /typescript/src/shared/prompts/hubspot.ts: -------------------------------------------------------------------------------- ```typescript export const checkConnectionPrompt = ` Check if there is any active connection to the salesforce app. `; export const startConnectionPrompt = ` Start a connection to the salesforce app. Active connections are required to perform actions with the app. `; export const transferAgentPrompt = ` Transfer to the HubSpot agent. `; export const createContactPrompt = ` Create a contact. Object properties should include at least one of the following properties: email, firstname, or lastname. It is recommended to always include email, because email address is the primary unique identifier to avoid duplicate contacts in HubSpot. `; export const getContactPrompt = ` Get a contact. `; export const listContactsPrompt = ` List all contacts, using query parameters to control the information that gets returned. `; export const searchContactsPrompt = ` Search for contacts by filtering on properties, searching through associations, and sorting results. To apply OR logic for filters, include multiple filters within a filter group. To apply AND logic for filters, include a list of conditions within one set of filters. `; export const mergeContactsPrompt = ` Merge two contacts. `; export const updateContactPrompt = ` Update a contact. Provided property values will be overwritten. Properties values can be cleared by passing an empty string. `; export const deleteContactPrompt = ` Delete a contact. `; export const createDealPrompt = ` Create a deal. Object properties should include the following properties: dealname, dealstage, and if you have multiple pipelines, pipeline. If a pipeline isn't specified, the default pipeline will be used. `; export const getDealPrompt = ` Get a deal. `; export const listDealsPrompt = ` List all deals, using query parameters to control the information that gets returned. `; export const searchDealsPrompt = ` Search for deals by filtering on properties, searching through associations, and sorting results. To apply OR logic for filters, include multiple filters within a filter group. To apply AND logic for filters, include a list of conditions within one set of filters. `; export const mergeDealPrompt = ` Merge two deals. `; export const updateDealPrompt = ` Update a deal. Provided property values will be overwritten. Properties values can be cleared by passing an empty string. `; export const deleteDealPrompt = ` Delete a deal. `; ``` -------------------------------------------------------------------------------- /typescript/src/shared/parameters/google-mail.ts: -------------------------------------------------------------------------------- ```typescript import {z} from 'zod'; export const checkConnectionParameters = z.object({}); export const startConnectionParameters = z.object({}); export const transferAgentParameters = z.object({ user_prompt: z.string().describe('The user prompt'), }); export const addLabelToEmailParameters = z.object({ message_id: z.string().describe('The ID of the message'), label_ids: z .array(z.string()) .describe('List of label IDs to add to the message'), }); export const createDraftParameters = z.object({ to: z.array(z.string()).describe('List of recipient emails'), subject: z.string().describe('The subject of the email'), body: z.string().describe('The body of the email'), cc: z.array(z.string()).describe('List of emails to CC').optional(), bcc: z.array(z.string()).describe('List of emails to BCC').optional(), body_type: z .enum(['plaintext', 'html']) .describe( 'The type of the email body. Default: plaintext. Possible values are: plaintext, html' ) .optional(), }); export const findEmailParameters = z.object({ q: z.string().describe('The search query'), label_ids: z .array(z.string()) .describe( 'List of label IDs. Only messages that match all of the specified labels are returned.' ) .optional(), include_spam_trash: z .boolean() .describe( 'Whether to include messages from `SPAM` and `TRASH` in the results. Default: False.' ) .optional(), max_results: z .number() .describe('The maximum number of results to return. Default: 10. Max: 500.') .optional(), }); export const listLabelsParameters = z.object({}); export const removeLabelFromEmailParameters = z.object({ message_id: z.string().describe('The ID of the message'), label_ids: z .array(z.string()) .describe('List of label IDs to remove from the message'), }); export const sendEmailParameters = z.object({ to: z.array(z.string()).describe('List of recipient emails'), subject: z.string().describe('The subject of the email'), body: z.string().describe('The body of the email'), cc: z.array(z.string()).describe('List of emails to CC').optional(), bcc: z.array(z.string()).describe('List of emails to BCC').optional(), body_type: z .enum(['plaintext', 'html']) .describe( 'The type of the email body. Default: plaintext. Possible values are: plaintext, html' ) .optional(), }); ``` -------------------------------------------------------------------------------- /typescript/src/shared/parameters/stripe.ts: -------------------------------------------------------------------------------- ```typescript import {z} from 'zod'; export const checkConnectionParameters = z.object({}); export const startConnectionParameters = z.object({}); export const transferAgentParameters = z.object({ user_prompt: z.string().describe('The user prompt'), }); export const createCustomerParameters = z.object({ name: z.string().describe('The name of the customer'), email: z.string().describe('The email address of the customer'), phone: z.string().describe('The phone number of the customer'), description: z.string().describe('The description of the customer'), address1: z.string().describe('The first line of the address'), address2: z.string().describe('The second line of the address'), city: z.string().describe('The city of the address'), state: z.string().describe('The state of the address'), postal_code: z.string().describe('The postal code of the address'), country: z.string().describe('The country of the address'), }); export const createInvoiceItemParameters = z.object({ customer_id: z.string().describe('The ID of the customer'), invoice_id: z.string().describe('The ID of the invoice'), subscription_id: z.string().describe('The ID of the subscription'), price_id: z.string().describe('The ID of the price'), quantity: z.number().describe('The quantity of the invoice item'), amount: z.number().describe('The amount of the invoice item'), description: z.string().describe('The description of the invoice item'), currency: z.string().describe('The currency of the invoice item'), }); export const createInvoiceParameters = z.object({ customer_id: z.string().describe('The ID of the customer'), subscription_id: z.string().describe('The ID of the subscription'), description: z.string().describe('The description of the invoice'), collection_method: z .enum(['charge_automatically', 'send_invoice']) .describe('The collection method of the invoice'), days_until_due: z .number() .describe('The number of days until the invoice is due'), }); export const deleteCustomerParameters = z.object({ customer_id: z.string().describe('The ID of the customer'), }); export const getCustomerParameters = z.object({ customer_id: z.string().describe('The ID of the customer'), }); export const getInvoiceParameters = z.object({ invoice_id: z.string().describe('The ID of the invoice'), }); export const listCustomersParameters = z.object({ email: z.string().describe('The email address of the customer').optional(), limit: z.number().describe('The number of results to return').optional(), }); export const listInvoicesParameters = z.object({ email: z.string().describe('The email address of the customer').optional(), limit: z.number().describe('The number of results to return').optional(), }); ``` -------------------------------------------------------------------------------- /typescript/src/shared/api.ts: -------------------------------------------------------------------------------- ```typescript class MatonClient { private headers: {'x-api-key': string}; constructor(apiKey: string) { this.headers = {'x-api-key': apiKey}; } async createConnection(app: string): Promise<any> { const body = {app}; const response = await fetch('https://api.maton.ai/create-connection', { method: 'POST', headers: this.headers, body: JSON.stringify(body), }); return response.json(); } async getConnection(connectionId: string): Promise<any> { const body = {connection_id: connectionId}; const response = await fetch('https://api.maton.ai/get-connection', { method: 'POST', headers: this.headers, body: JSON.stringify(body), }); return response.json(); } async listConnections(app?: string, status?: string): Promise<any> { const body = {app, status}; const response = await fetch('https://api.maton.ai/list-connections', { method: 'POST', headers: this.headers, body: JSON.stringify(body), }); return response.json(); } async deleteConnection(connectionId: string): Promise<any> { const body = {connection_id: connectionId}; const response = await fetch('https://api.maton.ai/delete-connection', { method: 'POST', headers: this.headers, body: JSON.stringify(body), }); return response.json(); } async invokeAction( app: string, action: string, args: {[key: string]: any} ): Promise<any> { const body = { app: app, action: action, args: args, }; const response = await fetch('https://api.maton.ai/invoke-action', { method: 'POST', headers: this.headers, body: JSON.stringify(body), }); return response.json(); } async invokeAgent(app: string, userPrompt: string): Promise<any> { const body = { app: app, user_prompt: userPrompt, }; const response = await fetch('https://api.maton.ai/invoke-agent', { method: 'POST', headers: this.headers, body: JSON.stringify(body), }); return response.json(); } } class MatonAPI { maton: MatonClient; constructor(apiKey?: string) { const envApiKey = process.env.MATON_API_KEY ?? ''; if (!apiKey && !envApiKey) { throw new Error( 'Did not find MATON_API_KEY, please add an environment variable or pass it as a parameter' ); } this.maton = new MatonClient(apiKey || envApiKey); } async run(method: string, arg: any) { const [app, ...rest] = method.split('_'); const action = rest.join('-'); let output = {}; if (method.endsWith('check_connection')) { const listConnectionsResp = await this.maton.listConnections( app, 'ACTIVE' ); const connections = listConnectionsResp.connections; return connections && connections.length > 0; } else if (method.endsWith('start_connection')) { const createConnectionResp = await this.maton.createConnection(app); const getConnectionResp = await this.maton.getConnection( createConnectionResp.connection_id ); const connection = getConnectionResp.connection; if (connection) { output = { connection_id: connection.connection_id, redirect_url: connection.url, instruction: 'Ask user to open the redirect URL and complete the Oauth process. \n Once user completes the process and gets back, check again by calling check_connection', }; } } else if (method.endsWith('transfer_agent')) { output = await this.maton.invokeAgent(app, arg.user_prompt); } else { output = await this.maton.invokeAction(app, action, arg); } return JSON.stringify(output); } } export default MatonAPI; ``` -------------------------------------------------------------------------------- /typescript/src/shared/parameters/google-sheet.ts: -------------------------------------------------------------------------------- ```typescript import {z} from 'zod'; export const checkConnectionParameters = z.object({}); export const startConnectionParameters = z.object({}); export const transferAgentParameters = z.object({ user_prompt: z.string().describe('The user prompt'), }); export const addColumnParameters = z.object({ spreadsheet_id: z.string().describe('The ID of Google spreadsheet'), worksheet_id: z.string().describe('The ID of worksheet'), column: z.string().describe('The column letter'), }); export const addMultipleRowsParameters = z.object({ spreadsheet_id: z.string().describe('The ID of Google spreadsheet'), worksheet_id: z.string().describe('The ID of worksheet'), values: z.array(z.array(z.string())).describe('The values of the rows'), }); export const clearCellParameters = z.object({ spreadsheet_id: z.string().describe('The ID of Google spreadsheet'), worksheet_id: z.string().describe('The ID of worksheet'), cell: z.string().describe('The A1 notation of the cell. E.g., `A1`'), }); export const clearRowsParameters = z.object({ spreadsheet_id: z.string().describe('The ID of Google spreadsheet'), worksheet_id: z.string().describe('The ID of worksheet'), start_row: z.number().describe('The starting row number'), end_row: z.number().describe('The ending row number (inclusive)'), }); export const createSpreadsheetParameters = z.object({ title: z.string().describe('The title of Google spreadsheet'), }); export const createWorksheetParameters = z.object({ spreadsheet_id: z.string().describe('The ID of Google spreadsheet'), title: z.string().describe('The title of Google spreadsheet'), }); export const deleteRowsParameters = z.object({ spreadsheet_id: z.string().describe('The ID of Google spreadsheet'), worksheet_id: z.string().describe('The ID of worksheet'), start_row: z.number().describe('The starting row number'), end_row: z.number().describe('The ending row number (inclusive)'), }); export const deleteWorksheetParameters = z.object({ spreadsheet_id: z.string().describe('The ID of Google spreadsheet'), worksheet_id: z.string().describe('The ID of worksheet'), }); export const findRowParameters = z.object({ spreadsheet_id: z.string().describe('The ID of Google spreadsheet'), worksheet_id: z.string().describe('The ID of worksheet'), column: z.string().describe('The column letter'), value: z.string().describe('The value to search for'), }); export const getCellParameters = z.object({ spreadsheet_id: z.string().describe('The ID of Google spreadsheet'), worksheet_id: z.string().describe('The ID of worksheet'), cell: z.string().describe('The A1 notation of the cell. E.g., `A1`'), }); export const getSpreadsheetParameters = z.object({ spreadsheet_id: z.string().describe('The ID of Google spreadsheet'), }); export const getValuesInRangeParameters = z.object({ spreadsheet_id: z.string().describe('The ID of Google spreadsheet'), worksheet_id: z.string().describe('The ID of worksheet'), range: z .string() .describe('The A1 notation of the values to retrieve. E.g., `A1:E5`'), }); export const listWorksheetsParameters = z.object({ spreadsheet_id: z.string().describe('The ID of Google spreadsheet'), }); export const updateCellParameters = z.object({ spreadsheet_id: z.string().describe('The ID of Google spreadsheet'), worksheet_id: z.string().describe('The ID of worksheet'), cell: z.string().describe('The A1 notation of the cell. E.g., `A1`'), value: z.string().describe('The value to update'), }); export const updateMultipleRowsParameters = z.object({ spreadsheet_id: z.string().describe('The ID of Google spreadsheet'), worksheet_id: z.string().describe('The ID of worksheet'), range: z .string() .describe('The A1 notation of the values to retrieve. E.g., `A1:E5`'), values: z.array(z.array(z.string())).describe('The values to update'), }); export const updateRowParameters = z.object({ spreadsheet_id: z.string().describe('The ID of Google spreadsheet'), worksheet_id: z.string().describe('The ID of worksheet'), row: z.number().describe('The row number'), values: z.array(z.string()).describe('The values to update'), }); ``` -------------------------------------------------------------------------------- /typescript/src/shared/configuration.ts: -------------------------------------------------------------------------------- ```typescript import type {Tool} from './tools'; const ACCEPTED_APPS: string[] = [ 'airtable', 'asana', 'aws', 'calendly', 'clickup', 'google-calendar', 'google-docs', 'google-drive', 'google-mail', 'google-sheet', 'hubspot', 'jira', 'jotform', 'klaviyo', 'mailchimp', 'notion', 'outlook', 'pipedrive', 'salesforce', 'shopify', 'slack', 'stripe', 'typeform', 'youtube', ]; const ACCEPTED_ACTIONS: {[key: string]: string[]} = { airtable: ['list-bases', 'list-records', 'list-tables'], asana: [ 'create-task', 'get-task', 'list-projects', 'list-tasks', 'list-workspaces', ], aws: ['get-s3-object', 'list-s3-buckets', 'list-s3-objects'], calendly: [ 'get-event', 'list-event-invitees', 'list-event-types', 'list-events', ], clickup: [ 'create-task', 'delete-task', 'get-task', 'list-folders', 'list-lists', 'list-spaces', 'list-tasks', 'list-workspaces', ], 'google-calendar': [ 'create-event', 'delete-event', 'get-calendar', 'get-event', 'list-calendars', 'list-events', 'update-event', ], 'google-docs': [ 'append-text', 'create-document', 'find-document', 'get-document', ], 'google-drive': [ 'create-file', 'create-folder', 'delete-file', 'find-file', 'find-folder', 'get-file', 'list-files', ], 'google-mail': [ 'add-label-to-email', 'create-draft', 'find-email', 'list-labels', 'send-email', 'remove-label-from-email', ], 'google-sheet': [ 'add-column', 'add-multiple-rows', 'clear-cell', 'clear-rows', 'create-spreadsheet', 'create-worksheet', 'delete-rows', 'delete-worksheet', 'find-row', 'get-cell', 'get-spreadsheet', 'get-values-in-range', 'list-worksheets', 'update-cell', 'update-multiple-rows', 'update-row', ], hubspot: [ 'create-contact', 'get-contact', 'list-contacts', 'search-contacts', 'merge-contacts', 'update-contact', 'delete-contact', 'create-deal', 'get-deal', 'list-deals', 'search-deals', 'merge-deals', 'update-deal', 'delete-deal', ], jira: [ 'list-clouds', 'get-issue', 'list-issues', 'add-comment-to-issue', 'list-comments', 'update-comment', 'list-projects', 'get-user', 'list-users', ], jotform: ['list-forms', 'list-submissions'], klaviyo: [ 'add-profiles-to-list', 'assign-template-to-campaign-message', 'create-campaign', 'create-list', 'create-profile', 'create-template', 'get-campaign-messages', 'get-campaign-send-job', 'get-campaigns', 'get-lists', 'get-profiles-for-list', 'get-profiles', 'get-templates', 'send-campaign', ], mailchimp: ['get-campaign', 'search-campaign'], notion: ['create-page', 'find-page', 'get-page'], outlook: ['create-draft', 'find-email', 'send-email'], pipedrive: ['search-people'], salesforce: ['create-contact', 'get-contact', 'list-contacts'], shopify: ['create-order', 'get-order', 'list-orders'], slack: ['list-channels', 'list-messages', 'list-replies', 'send-message'], stripe: [ 'create-customer', 'create-invoice-item', 'create-invoice', 'delete-customer', 'get-customer', 'get-invoice', 'list-customers', 'list-invoices', ], typeform: ['get-form', 'list-forms', 'list-responses'], youtube: ['list-videos', 'search-videos'], }; const AGENT_ACTIONS = ['transfer-agent']; const BUILTIN_ACTIONS = ['check-connection', 'start-connection']; export type Actions = { [key: string]: boolean; }; export type Configuration = { apiKey?: string; app?: string; agent?: boolean; actions?: string[]; }; function getMethod(app: string, action: string) { return `${app}_${action.replaceAll('-', '_')}`; } export const checkConfiguration = (configuration: Configuration) => { if (!configuration.app) { throw new Error('The app argument must be provided.'); } if (configuration.agent && configuration.actions) { throw new Error('Both --agent and --actions arguments cannot be provided.'); } else if (!configuration.agent && !configuration.actions) { throw new Error('Either --agent or --actions arguments must be provided.'); } if (!ACCEPTED_APPS.includes(configuration.app)) { throw new Error( `Invalid app: ${configuration.app}. Accepted apps are: ${ACCEPTED_APPS.join( ', ' )}` ); } if (configuration.actions) { configuration.actions.forEach((action: string) => { if (action == 'all') { return; } if (!ACCEPTED_ACTIONS[configuration.app!].includes(action.trim())) { throw new Error( `Invalid action: ${action}. Accepted actions are: ${ACCEPTED_ACTIONS[ configuration.app! ].join(', ')}` ); } }); } }; export const isToolAllowed = ( tool: Tool, configuration: Configuration ): boolean => { if (!configuration.app || !tool.method.startsWith(configuration.app)) { return false; } if ( BUILTIN_ACTIONS.map((action) => getMethod(configuration.app!, action) ).includes(tool.method) ) { return true; } if (configuration.agent) { return AGENT_ACTIONS.map((action) => getMethod(configuration.app!, action) ).includes(tool.method); } else if (configuration.actions) { if (configuration.actions.includes('all')) { return !AGENT_ACTIONS.map((action) => getMethod(configuration.app!, action) ).includes(tool.method); } return configuration.actions .map((action) => getMethod(configuration.app!, action)) .includes(tool.method); } else { return false; } }; ``` -------------------------------------------------------------------------------- /typescript/src/shared/parameters/google-calendar.ts: -------------------------------------------------------------------------------- ```typescript import {z} from 'zod'; export const checkConnectionParameters = z.object({}); export const startConnectionParameters = z.object({}); export const transferAgentParameters = z.object({ user_prompt: z.string().describe('The user prompt'), }); export const createEventParameters = z.object({ calendar_id: z.string().describe('The ID of Google Calendar'), event_start_date: z .string() .describe( 'The start date of the event in the format `yyyy-mm-dd`. For all-day events, enter the Event day in the format `yyyy-mm-dd`. For events with time, format according to RFC3339: `yyyy-mm-ddThh:mm:ss+01:00`.' ), event_end_date: z .string() .describe( 'The start date of the event in the format `yyyy-mm-dd`. For all-day events, enter the Event day in the format `yyyy-mm-dd`. For events with time, format according to RFC3339: `yyyy-mm-ddThh:mm:ss+01:00`.' ), summary: z.string().describe('The title of the event.').optional(), location: z.string().describe('The location of the event.').optional(), description: z.string().describe('The description of the event.').optional(), attendees: z .array(z.string()) .describe('The email addresses of the attendees.') .optional(), repeat_frequency: z .enum(['DAILY', 'WEEKLY', 'MONTHLY', 'YEARLY']) .describe('The frequency of the event repetition.') .optional(), repeat_times: z .number() .describe('The number of times the event repeats.') .optional(), repeat_interval: z .number() .describe( 'The interval between event repetitions. To repeat every day, enter 1. To repeat every other day, enter 2.' ) .optional(), send_updates: z .enum(['all', 'externalOnly', 'none']) .describe('Whether to send updates.') .optional(), create_meet_room: z .boolean() .describe('Whether to create a Google Meet room for this event.') .optional(), visibility: z .enum(['default', 'public', 'private', 'confidential']) .describe( 'The visibility of the event. Defaults to default if not specified.' ) .optional(), }); export const deleteEventParameters = z.object({ calendar_id: z.string().describe('The ID of calendar'), event_id: z.string().describe('The ID of event'), }); export const getCalendarParameters = z.object({ calendar_id: z.string().describe('The ID of Google Calendar'), }); export const getEventParameters = z.object({ calendar_id: z.string().describe('The ID of calendar'), event_id: z.string().describe('The ID of event'), }); export const listCalendarsParameters = z.object({}); export const listEventsParameters = z.object({ calendar_id: z.string().describe('The ID of calendar'), order_by: z .enum(['startTime', 'updated']) .describe('The order of the events returned in the result.') .optional(), q: z.string().describe('The search query.').optional(), show_deleted: z .boolean() .describe( 'Whether to include deleted events (with status equals "cancelled") in the result.' ) .optional(), show_hidden_invitations: z .boolean() .describe('Whether to include hidden invitations in the result.') .optional(), show_single_events: z .boolean() .describe( 'Whether to expand recurring events into instances and only return single one-off events and instances of recurring events, but not the underlying recurring events themselves.' ) .optional(), time_max: z .string() .describe("Upper bound (exclusive) for an event's time to filter by.") .optional(), time_min: z .string() .describe("Lower bound (exclusive) for an event's time to filter by.") .optional(), updated_min: z .string() .describe("Lower bound for an event's last modification time to filter by.") .optional(), event_types: z .array(z.enum(['default', 'focusTime', 'outOfOffice', 'workingLocation'])) .describe('Filter events by event type.') .optional(), }); export const updateEventParameters = z.object({ calendar_id: z.string().describe('The ID of calendar'), event_id: z.string().describe('The ID of event'), summary: z.string().describe('The title of the event.').optional(), event_start_date: z .string() .describe( 'The start date of the event in the format `yyyy-mm-dd`. For all-day events, enter the Event day in the format `yyyy-mm-dd`. For events with time, format according to RFC3339: `yyyy-mm-ddThh:mm:ss+01:00`.' ) .optional(), event_end_date: z .string() .describe( 'The start date of the event in the format `yyyy-mm-dd`. For all-day events, enter the Event day in the format `yyyy-mm-dd`. For events with time, format according to RFC3339: `yyyy-mm-ddThh:mm:ss+01:00`.' ) .optional(), location: z.string().describe('The location of the event.').optional(), description: z.string().describe('The description of the event.').optional(), attendees: z .array(z.string()) .describe('The email addresses of the attendees.') .optional(), repeat_frequency: z .enum(['DAILY', 'WEEKLY', 'MONTHLY', 'YEARLY']) .describe('The frequency of the event repetition.') .optional(), repeat_times: z .number() .describe('The number of times the event repeats.') .optional(), repeat_interval: z .number() .describe( 'The interval between event repetitions. To repeat every day, enter 1. To repeat every other day, enter 2.' ) .optional(), send_updates: z .enum(['all', 'externalOnly', 'none']) .describe('Whether to send updates.') .optional(), create_meet_room: z .boolean() .describe('Whether to create a Google Meet room for this event.') .optional(), visibility: z .enum(['default', 'public', 'private', 'confidential']) .describe('The visibility of the event.') .optional(), }); ``` -------------------------------------------------------------------------------- /typescript/src/shared/parameters/klaviyo.ts: -------------------------------------------------------------------------------- ```typescript import {z} from 'zod'; export const checkConnectionParameters = z.object({}); export const startConnectionParameters = z.object({}); export const transferAgentParameters = z.object({ user_prompt: z.string().describe('The user prompt'), }); export const addProfilesToListParameters = z.object({ list_id: z.string().describe('The list ID'), profile_ids: z.array(z.string()).describe('A list of profile IDs'), }); export const assignTemplateToCampaignMessageParameters = z.object({ campaign_message_id: z.string().describe('The ID of the campaign message'), template_id: z.string().describe('The ID of the template'), }); export const createCampaignParameters = z.object({ name: z.string().describe('The name of the campaign'), audiences: z.object({ included: z.array(z.string()).describe('The IDs of included lists'), excluded: z.array(z.string()).describe('The IDs of excluded lists'), }), campaign_messages: z.array( z .object({ type: z.enum(['campaign-message']), attributes: z .object({ definition: z .object({ channel: z .enum(['email', 'sms', 'mobile_push']) .describe('The channel of the campaign message.'), label: z .string() .optional() .describe('The label of the campaign message.'), content: z .object({ subject: z .string() .optional() .describe('The subject of the campaign message.'), previewText: z .string() .optional() .describe('The preview text of the campaign message.'), fromEmail: z .string() .optional() .describe('The from email of the campaign message.'), fromLabel: z .string() .optional() .describe('The from label of the campaign message.'), replyToEmail: z .string() .optional() .describe('The reply to email of the campaign message.'), ccEmail: z .string() .optional() .describe('The cc email of the campaign message.'), bccEmail: z .string() .optional() .describe('The bcc email of the campaign message.'), }) .optional(), renderOptions: z .object({ shortenLinks: z .boolean() .optional() .describe('Whether to shorten links.'), addOrgPrefix: z .boolean() .optional() .describe('Whether to add org prefix.'), addInfoLinks: z .boolean() .optional() .describe('Whether to add info links.'), addOptOutLanguage: z .boolean() .optional() .describe('Whether to add opt out language.'), }) .optional(), kvPairs: z .object({}) .optional() .describe('The kv pairs of the campaign message.'), options: z .object({ type: z .enum(['open_app', 'deep_link']) .describe('The type of the options.'), iosDeepLink: z .string() .optional() .describe('The ios deep link of the campaign message.'), androidDeepLink: z .string() .optional() .describe( 'The android deep link of the campaign message.' ), display: z .boolean() .optional() .describe( 'Whether to display the campaign message. Required if type is "open_app".' ), }) .optional() .describe('The options of the campaign message.'), }) .describe('The definition of the campaign message.'), }) .describe('THe attributes of the campaign message.'), }) .describe('The data of the campaign message.') ), send_strategy: z .object({ method: z .enum(['static', 'throttled', 'immediate', 'smart_send_time']) .describe('The method of the send strategy.'), datetime: z .string() .optional() .describe( 'The ISO 8601 date and time of the send time. Requred if method is "static".' ), options: z .object({ isLocalTime: z.boolean().describe('Whether to use local time'), sendPastRecipientsImmediately: z .boolean() .optional() .describe('Whether to send past recipients immediately.'), }) .optional() .describe('The options of the send strategy.'), throttlePercentage: z .number() .optional() .describe( 'The throttle percentage of the send strategy. Required if method is "throttled"' ), date: z .string() .optional() .describe( 'The ISO 8601 date of the send time. Required if method is "smart_send_time"' ), }) .optional() .describe('The send strategy of the campaign.'), send_options: z .object({ useSmartSending: z .boolean() .optional() .describe('Whether to use smart sending.'), }) .optional() .describe('The send options of the campaign.'), tracking_options: z .object({ addTrackingParams: z .boolean() .optional() .describe('Whether to add tracking params.'), customTrackingParams: z .array( z.object({ type: z .enum(['static', 'dynamic']) .describe('The type of the custom tracking param.'), value: z .string() .describe('The value of the custom tracking param.'), name: z.string().describe('The name of the custom tracking param.'), }) ) .optional() .describe('The custom tracking params of the campaign.'), isTrackingClicks: z .boolean() .optional() .describe('Whether to track clicks.'), isTrackingOpens: z .boolean() .optional() .describe('Whether to track opens.'), }) .optional() .describe('The tracking options of the campaign.'), }); export const createListParameters = z.object({ name: z.string().describe('The name of the list.'), }); export const createProfileParameters = z.object({ email: z.string().optional().describe('The email of the user.'), phone_number: z.string().optional().describe('The phone number of the user.'), external_id: z.string().optional().describe('The external ID of the user.'), first_name: z.string().optional().describe('The first name of the user.'), last_name: z.string().optional().describe('The last name of the user.'), organization: z.string().optional().describe('The organization of the user.'), locale: z.string().optional().describe('The locale of the user.'), title: z.string().optional().describe('The title of the user.'), image: z.string().optional().describe('The image of the user.'), location: z.string().optional().describe('The location of the user.'), properties: z.object({}).optional().describe('The properties of the user.'), }); export const createTemplateParameters = z.object({ name: z.string().describe('The name of the template.'), html: z.string().optional().describe('The HTML content of the template.'), text: z.string().optional().describe('The text content of the template.'), }); export const getCampaignMessagesParameters = z.object({ campaign_id: z.string().describe('The ID of the campaign.'), }); export const getCampaignSendJobParameters = z.object({ campaign_id: z.string().describe('The ID of the campaign.'), }); export const getCampaignsParameters = z.object({ filter: z .string() .describe( "The filter of the campaigns. A channel filter is required to list campaigns. Please provide either:\n`equals(messages.channel,'email')` to list email campaigns, `equals(messages.channel,'sms')` to list SMS campaigns, `equals(messages.channel,'mobile_push')` to list mobile push campaigns." ), }); export const getListsParameters = z.object({}); export const getProfilesForListParameters = z.object({ list_id: z.string().describe('The list ID.'), }); export const getProfilesParameters = z.object({}); export const getTemplatesParameters = z.object({}); export const sendCampaignParameters = z.object({ campaign_id: z.string().describe('The ID of the campaign.'), }); ``` -------------------------------------------------------------------------------- /modelcontextprotocol/eslint.config.mjs: -------------------------------------------------------------------------------- ``` import prettier from "eslint-plugin-prettier"; import _import from "eslint-plugin-import"; import { fixupPluginRules } from "@eslint/compat"; import globals from "globals"; import typescriptEslint from "@typescript-eslint/eslint-plugin"; import path from "node:path"; import { fileURLToPath } from "node:url"; import js from "@eslint/js"; import { FlatCompat } from "@eslint/eslintrc"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const compat = new FlatCompat({ baseDirectory: __dirname, recommendedConfig: js.configs.recommended, allConfig: js.configs.all }); export default [...compat.extends("plugin:prettier/recommended"), { plugins: { prettier, import: fixupPluginRules(_import), }, languageOptions: { globals: { ...globals.node, }, ecmaVersion: 2018, sourceType: "commonjs", }, rules: { "accessor-pairs": "error", "array-bracket-spacing": ["error", "never"], "array-callback-return": "off", "arrow-parens": "error", "arrow-spacing": "error", "block-scoped-var": "off", "block-spacing": "off", "brace-style": ["error", "1tbs", { allowSingleLine: true, }], "capitalized-comments": "off", "class-methods-use-this": "off", "comma-dangle": "off", "comma-spacing": "off", "comma-style": ["error", "last"], complexity: "error", "computed-property-spacing": ["error", "never"], "consistent-return": "off", "consistent-this": "off", curly: "error", "default-case": "off", "dot-location": ["error", "property"], "dot-notation": "error", "eol-last": "error", eqeqeq: "off", "func-call-spacing": "error", "func-name-matching": "error", "func-names": "off", "func-style": ["error", "declaration", { allowArrowFunctions: true, }], "generator-star-spacing": "error", "global-require": "off", "guard-for-in": "error", "handle-callback-err": "off", "id-blacklist": "error", "id-length": "off", "id-match": "error", "import/extensions": "off", "init-declarations": "off", "jsx-quotes": "error", "key-spacing": "error", "keyword-spacing": ["error", { after: true, before: true, }], "line-comment-position": "off", "linebreak-style": ["error", "unix"], "lines-around-directive": "error", "max-depth": "error", "max-len": "off", "max-lines": "off", "max-nested-callbacks": "error", "max-params": "off", "max-statements": "off", "max-statements-per-line": "off", "multiline-ternary": "off", "new-cap": "off", "new-parens": "error", "newline-after-var": "off", "newline-before-return": "off", "newline-per-chained-call": "off", "no-alert": "error", "no-array-constructor": "error", "no-await-in-loop": "error", "no-bitwise": "off", "no-caller": "error", "no-catch-shadow": "off", "no-compare-neg-zero": "error", "no-confusing-arrow": "error", "no-continue": "off", "no-div-regex": "error", "no-duplicate-imports": "off", "no-else-return": "off", "no-empty-function": "off", "no-eq-null": "off", "no-eval": "error", "no-extend-native": "error", "no-extra-bind": "error", "no-extra-label": "error", "no-extra-parens": "off", "no-floating-decimal": "error", "no-implicit-globals": "error", "no-implied-eval": "error", "no-inline-comments": "off", "no-inner-declarations": ["error", "functions"], "no-invalid-this": "off", "no-iterator": "error", "no-label-var": "error", "no-labels": "error", "no-lone-blocks": "error", "no-lonely-if": "error", "no-loop-func": "error", "no-magic-numbers": "off", "no-mixed-requires": "error", "no-multi-assign": "off", "no-multi-spaces": "error", "no-multi-str": "error", "no-multiple-empty-lines": "error", "no-native-reassign": "error", "no-negated-condition": "off", "no-negated-in-lhs": "error", "no-nested-ternary": "error", "no-new": "error", "no-new-func": "error", "no-new-object": "error", "no-new-require": "error", "no-new-wrappers": "error", "no-octal-escape": "error", "no-param-reassign": "off", "no-path-concat": "error", "no-plusplus": ["error", { allowForLoopAfterthoughts: true, }], "no-process-env": "off", "no-process-exit": "error", "no-proto": "error", "no-prototype-builtins": "off", "no-restricted-globals": "error", "no-restricted-imports": "error", "no-restricted-modules": "error", "no-restricted-properties": "error", "no-restricted-syntax": "error", "no-return-assign": "error", "no-return-await": "error", "no-script-url": "error", "no-self-compare": "error", "no-sequences": "error", "no-shadow": "off", "no-shadow-restricted-names": "error", "no-spaced-func": "error", "no-sync": "error", "no-tabs": "error", "no-template-curly-in-string": "error", "no-ternary": "off", "no-throw-literal": "error", "no-trailing-spaces": "error", "no-undef-init": "error", "no-undefined": "off", "no-underscore-dangle": "off", "no-unmodified-loop-condition": "error", "no-unneeded-ternary": "error", "no-unused-expressions": "error", "no-unused-vars": ["error", { args: "none", }], "no-use-before-define": "off", "no-useless-call": "error", "no-useless-computed-key": "error", "no-useless-concat": "error", "no-useless-constructor": "error", "no-useless-escape": "off", "no-useless-rename": "error", "no-useless-return": "error", "no-var": "off", "no-void": "error", "no-warning-comments": "error", "no-whitespace-before-property": "error", "no-with": "error", "nonblock-statement-body-position": "error", "object-curly-newline": "off", "object-curly-spacing": ["error", "never"], "object-property-newline": "off", "object-shorthand": "off", "one-var": "off", "one-var-declaration-per-line": "error", "operator-assignment": ["error", "always"], "operator-linebreak": "off", "padded-blocks": "off", "prefer-arrow-callback": "off", "prefer-const": "error", "prefer-destructuring": ["error", { array: false, object: false, }], "prefer-numeric-literals": "error", "prefer-promise-reject-errors": "error", "prefer-reflect": "off", "prefer-rest-params": "off", "prefer-spread": "off", "prefer-template": "off", "quote-props": "off", quotes: ["error", "single", { avoidEscape: true, }], radix: "error", "require-await": "error", "require-jsdoc": "off", "rest-spread-spacing": "error", semi: "off", "semi-spacing": ["error", { after: true, before: false, }], "sort-imports": "off", "sort-keys": "off", "sort-vars": "error", "space-before-blocks": "error", "space-before-function-paren": "off", "space-in-parens": ["error", "never"], "space-infix-ops": "error", "space-unary-ops": "error", "spaced-comment": ["error", "always"], strict: "off", "symbol-description": "error", "template-curly-spacing": "error", "template-tag-spacing": "error", "unicode-bom": ["error", "never"], "valid-jsdoc": "off", "vars-on-top": "off", "wrap-regex": "off", "yield-star-spacing": "error", yoda: ["error", "never"], }, }, ...compat.extends( "eslint:recommended", "plugin:@typescript-eslint/eslint-recommended", "plugin:@typescript-eslint/recommended", "plugin:prettier/recommended", ).map(config => ({ ...config, files: ["**/*.ts"], })), { files: ["**/*.ts"], plugins: { "@typescript-eslint": typescriptEslint, prettier, }, rules: { "@typescript-eslint/no-use-before-define": 0, "@typescript-eslint/no-empty-interface": 0, "@typescript-eslint/no-unused-vars": 0, "@typescript-eslint/triple-slash-reference": 0, "@typescript-eslint/ban-ts-comment": "off", "@typescript-eslint/no-empty-function": 0, "@typescript-eslint/no-require-imports": 0, "@typescript-eslint/naming-convention": ["error", { selector: "default", format: ["camelCase", "UPPER_CASE", "PascalCase"], leadingUnderscore: "allow", }, { selector: "property", format: null, }], "@typescript-eslint/no-explicit-any": 0, "@typescript-eslint/explicit-function-return-type": "off", "@typescript-eslint/no-this-alias": "off", "@typescript-eslint/no-var-requires": 0, "prefer-rest-params": "off", }, }, { files: ["test/**/*.ts"], rules: { "@typescript-eslint/explicit-function-return-type": "off", }, }]; ``` -------------------------------------------------------------------------------- /typescript/eslint.config.mjs: -------------------------------------------------------------------------------- ``` import prettier from "eslint-plugin-prettier"; import _import from "eslint-plugin-import"; import { fixupPluginRules } from "@eslint/compat"; import globals from "globals"; import typescriptEslint from "@typescript-eslint/eslint-plugin"; import path from "node:path"; import { fileURLToPath } from "node:url"; import js from "@eslint/js"; import { FlatCompat } from "@eslint/eslintrc"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const compat = new FlatCompat({ baseDirectory: __dirname, recommendedConfig: js.configs.recommended, allConfig: js.configs.all }); export default [...compat.extends("plugin:prettier/recommended"), { plugins: { prettier, import: fixupPluginRules(_import), }, languageOptions: { globals: { ...globals.node, }, ecmaVersion: 2018, sourceType: "commonjs", }, rules: { "accessor-pairs": "error", "array-bracket-spacing": ["error", "never"], "array-callback-return": "off", "arrow-parens": "error", "arrow-spacing": "error", "block-scoped-var": "off", "block-spacing": "off", "brace-style": ["error", "1tbs", { allowSingleLine: true, }], "capitalized-comments": "off", "class-methods-use-this": "off", "comma-dangle": "off", "comma-spacing": "off", "comma-style": ["error", "last"], complexity: "error", "computed-property-spacing": ["error", "never"], "consistent-return": "off", "consistent-this": "off", curly: "error", "default-case": "off", "dot-location": ["error", "property"], "dot-notation": "error", "eol-last": "error", eqeqeq: "off", "func-call-spacing": "error", "func-name-matching": "error", "func-names": "off", "func-style": ["error", "declaration", { allowArrowFunctions: true, }], "generator-star-spacing": "error", "global-require": "off", "guard-for-in": "error", "handle-callback-err": "off", "id-blacklist": "error", "id-length": "off", "id-match": "error", "import/extensions": "off", "init-declarations": "off", "jsx-quotes": "error", "key-spacing": "error", "keyword-spacing": ["error", { after: true, before: true, }], "line-comment-position": "off", "linebreak-style": ["error", "unix"], "lines-around-directive": "error", "max-depth": "error", "max-len": "off", "max-lines": "off", "max-nested-callbacks": "error", "max-params": "off", "max-statements": "off", "max-statements-per-line": "off", "multiline-ternary": "off", "new-cap": "off", "new-parens": "error", "newline-after-var": "off", "newline-before-return": "off", "newline-per-chained-call": "off", "no-alert": "error", "no-array-constructor": "error", "no-await-in-loop": "error", "no-bitwise": "off", "no-caller": "error", "no-catch-shadow": "off", "no-compare-neg-zero": "error", "no-confusing-arrow": "error", "no-continue": "off", "no-div-regex": "error", "no-duplicate-imports": "off", "no-else-return": "off", "no-empty-function": "off", "no-eq-null": "off", "no-eval": "error", "no-extend-native": "error", "no-extra-bind": "error", "no-extra-label": "error", "no-extra-parens": "off", "no-floating-decimal": "error", "no-implicit-globals": "error", "no-implied-eval": "error", "no-inline-comments": "off", "no-inner-declarations": ["error", "functions"], "no-invalid-this": "off", "no-iterator": "error", "no-label-var": "error", "no-labels": "error", "no-lone-blocks": "error", "no-lonely-if": "error", "no-loop-func": "error", "no-magic-numbers": "off", "no-mixed-requires": "error", "no-multi-assign": "off", "no-multi-spaces": "error", "no-multi-str": "error", "no-multiple-empty-lines": "error", "no-native-reassign": "error", "no-negated-condition": "off", "no-negated-in-lhs": "error", "no-nested-ternary": "error", "no-new": "error", "no-new-func": "error", "no-new-object": "error", "no-new-require": "error", "no-new-wrappers": "error", "no-octal-escape": "error", "no-param-reassign": "off", "no-path-concat": "error", "no-plusplus": ["error", { allowForLoopAfterthoughts: true, }], "no-process-env": "off", "no-process-exit": "error", "no-proto": "error", "no-prototype-builtins": "off", "no-restricted-globals": "error", "no-restricted-imports": "error", "no-restricted-modules": "error", "no-restricted-properties": "error", "no-restricted-syntax": "error", "no-return-assign": "error", "no-return-await": "error", "no-script-url": "error", "no-self-compare": "error", "no-sequences": "error", "no-shadow": "off", "no-shadow-restricted-names": "error", "no-spaced-func": "error", "no-sync": "error", "no-tabs": "error", "no-template-curly-in-string": "error", "no-ternary": "off", "no-throw-literal": "error", "no-trailing-spaces": "error", "no-undef-init": "error", "no-undefined": "off", "no-underscore-dangle": "off", "no-unmodified-loop-condition": "error", "no-unneeded-ternary": "error", "no-unused-expressions": "error", "no-unused-vars": ["error", { args: "none", }], "no-use-before-define": "off", "no-useless-call": "error", "no-useless-computed-key": "error", "no-useless-concat": "error", "no-useless-constructor": "error", "no-useless-escape": "off", "no-useless-rename": "error", "no-useless-return": "error", "no-var": "off", "no-void": "error", "no-warning-comments": "error", "no-whitespace-before-property": "error", "no-with": "error", "nonblock-statement-body-position": "error", "object-curly-newline": "off", "object-curly-spacing": ["error", "never"], "object-property-newline": "off", "object-shorthand": "off", "one-var": "off", "one-var-declaration-per-line": "error", "operator-assignment": ["error", "always"], "operator-linebreak": "off", "padded-blocks": "off", "prefer-arrow-callback": "off", "prefer-const": "error", "prefer-destructuring": ["error", { array: false, object: false, }], "prefer-numeric-literals": "error", "prefer-promise-reject-errors": "error", "prefer-reflect": "off", "prefer-rest-params": "off", "prefer-spread": "off", "prefer-template": "off", "quote-props": "off", quotes: ["error", "single", { avoidEscape: true, }], radix: "error", "require-await": "error", "require-jsdoc": "off", "rest-spread-spacing": "error", semi: "off", "semi-spacing": ["error", { after: true, before: false, }], "sort-imports": "off", "sort-keys": "off", "sort-vars": "error", "space-before-blocks": "error", "space-before-function-paren": "off", "space-in-parens": ["error", "never"], "space-infix-ops": "error", "space-unary-ops": "error", "spaced-comment": ["error", "always"], strict: "off", "symbol-description": "error", "template-curly-spacing": "error", "template-tag-spacing": "error", "unicode-bom": ["error", "never"], "valid-jsdoc": "off", "vars-on-top": "off", "wrap-regex": "off", "yield-star-spacing": "error", yoda: ["error", "never"], }, }, ...compat.extends( "eslint:recommended", "plugin:@typescript-eslint/eslint-recommended", "plugin:@typescript-eslint/recommended", "plugin:prettier/recommended", ).map(config => ({ ...config, files: ["**/*.ts"], })), { files: ["**/*.ts"], plugins: { "@typescript-eslint": typescriptEslint, prettier, }, rules: { "@typescript-eslint/no-use-before-define": 0, "@typescript-eslint/no-empty-interface": 0, "@typescript-eslint/no-unused-vars": 0, "@typescript-eslint/triple-slash-reference": 0, "@typescript-eslint/ban-ts-comment": "off", "@typescript-eslint/no-empty-function": 0, "@typescript-eslint/no-require-imports": 0, "@typescript-eslint/naming-convention": ["error", { selector: "default", format: ["camelCase", "UPPER_CASE", "PascalCase"], leadingUnderscore: "allow", }, { selector: "property", format: null, }], "@typescript-eslint/no-explicit-any": 0, "@typescript-eslint/explicit-function-return-type": "off", "@typescript-eslint/no-this-alias": "off", "@typescript-eslint/no-var-requires": 0, "prefer-rest-params": "off", }, }, { files: ["test/**/*.ts"], rules: { "@typescript-eslint/explicit-function-return-type": "off", }, }]; ``` -------------------------------------------------------------------------------- /typescript/src/shared/parameters/hubspot.ts: -------------------------------------------------------------------------------- ```typescript import {z} from 'zod'; export const checkConnectionParameters = z.object({}); export const startConnectionParameters = z.object({}); export const transferAgentParameters = z.object({ user_prompt: z.string().describe('The user prompt'), }); const associationTypesSchema = z.object({ association_category: z.literal('HUBSPOT_DEFINED'), association_type_id: z.union([ z.literal(279), // Contact to Company z.literal(449), // Contact to Contact z.literal(4), // Contact to Deal z.literal(15), // Contact to Ticket z.literal(341), // Deal to Company z.literal(3), // Deal to Contact z.literal(451), // Deal to Deal z.literal(27), // Deal to Ticket ]), }); const associationSchema = z.object({ types: z.array(associationTypesSchema).optional(), to: z.string().optional(), }); const contactPropertiesSchema = z.object({ firstname: z.string().optional(), lastname: z.string().optional(), email: z.string().optional(), company: z.string().optional(), website: z.string().optional(), mobilephone: z.string().optional(), phone: z.string().optional(), fax: z.string().optional(), address: z.string().optional(), city: z.string().optional(), state: z.string().optional(), zip: z.string().optional(), country: z.string().optional(), jobtitle: z.string().optional(), industry: z.string().optional(), lifecyclestage: z .union([ z.literal('subscriber'), z.literal('lead'), z.literal('marketingqualifiedlead'), z.literal('salesqualifiedlead'), z.literal('opportunity'), z.literal('customer'), z.literal('evangelist'), z.literal('other'), ]) .optional(), }); export const createContactParameters = z.object({ associations: z.array(associationSchema).optional(), properties: contactPropertiesSchema.optional(), }); export const getContactParameters = z.object({ contact_id: z.string().describe('The ID of the contact'), }); export const listContactsParameters = z.object({ limit: z .number() .optional() .default(100) .describe( 'The maximum number of results to display per page. Default: 100. Maximum: 100.' ), after: z .string() .optional() .describe( 'The paging cursor token of the last successfully read resource will be returned as the paging.next.after JSON property of a paged response containing more results.' ), properties: z .array(z.string()) .optional() .describe( 'List of the properties to be returned in the response. If any of the specified properties are not present on the requested object(s), they will be ignored.' ), associations: z .array(z.string()) .optional() .describe( 'List of object types to retrieve associated IDs for. If any of the specified associations do not exist, they will be ignored.' ), archived: z .boolean() .optional() .describe('Whether to return only results that have been archived.'), }); export const searchContactsParameters = z.object({ query: z.string().optional().describe('The query of the search.'), limit: z .number() .int() .min(1) .max(200) .default(200) .describe( 'The maximum number of results to display per page. Default: 200. Maximum: 200.' ), after: z .string() .optional() .describe( 'The paging cursor token of the last successfully read resource will be returned as the paging.next.after JSON property of a paged response containing more results.' ), sorts: z .array( z.object({ propertyName: z.string().describe('The name of the property.'), direction: z .enum(['ASCENDING', 'DESCENDING']) .describe('The direction of the sort.'), }) ) .optional() .describe('List of sorts containing the following keys:'), properties: z .array(z.string()) .optional() .describe( 'List of the properties to be returned in the response. If any of the specified properties are not present on the requested object(s), they will be ignored.' ), filter_groups: z .array( z.object({ filters: z .array( z.object({ high_value: z .string() .optional() .describe('The maximum value of a range.'), property_name: z .string() .optional() .describe('The name of the property.'), values: z .array(z.string()) .optional() .describe('List of values to compare.'), value: z.string().optional().describe('The value to compare.'), operator: z .enum([ 'IN', 'NOT_HAS_PROPERTY', 'LT', 'EQ', 'GT', 'NOT_IN', 'GTE', 'CONTAINS_TOKEN', 'HAS_PROPERTY', 'LTE', 'NOT_CONTAINS_TOKEN', 'BETWEEN', 'NEQ', ]) .optional() .describe('The operator of the filter. Possible values are:'), }) ) .optional() .describe('List of filters containing the following keys'), }) ) .optional() .describe('List of filter groups containing the following keys.'), }); export const mergeContactsParameters = z.object({ object_id_to_merge: z.string({ description: 'The ID of the object to merge.', }), primary_object_id: z.string({ description: 'The ID of the primary object of the merge.', }), }); export const updateContactParameters = z.object({ contact_id: z.string(), properties: z.optional( z.object({ firstname: z.optional(z.string()), lastname: z.optional(z.string()), email: z.optional(z.string()), company: z.optional(z.string()), website: z.optional(z.string()), mobilephone: z.optional(z.string()), phone: z.optional(z.string()), fax: z.optional(z.string()), address: z.optional(z.string()), city: z.optional(z.string()), state: z.optional(z.string()), zip: z.optional(z.string()), country: z.optional(z.string()), jobtitle: z.optional(z.string()), industry: z.optional(z.string()), lifecyclestage: z.optional( z.enum([ 'subscriber', 'lead', 'marketingqualifiedlead', 'salesqualifiedlead', 'opportunity', 'customer', 'evangelist', 'other', ]) ), }) ), }); export const deleteContactParameters = z.object({ contact_id: z.string().describe('The ID of the contact'), }); const dealPropertiesSchema = z.object({ dealname: z.string(), dealstage: z.enum([ 'appointmentscheduled', 'qualifiedtobuy', 'presentationscheduled', 'decisionmakerboughtin', 'contractsent', 'closedwon', 'closedlost', ]), amount: z.number().optional(), closed_lost_reason: z.string().optional(), closed_won_reason: z.string().optional(), closedate: z.date().optional(), createdate: z.date().optional(), dealtype: z.enum(['newbusiness', 'existingbusiness']).optional(), description: z.string().optional(), hs_priority: z.enum(['low', 'medium', 'high']).optional(), pipeline: z.enum(['default']).optional(), }); export const createDealParameters = z.object({ associations: z.array(associationSchema).optional(), properties: dealPropertiesSchema.optional(), }); export const getDealParameters = z.object({ deal_id: z.string().describe('The ID of the deal'), }); export const listDealsParameters = z.object({ limit: z .number() .optional() .describe( 'The maximum number of results to display per page. Default: 100. Maximum: 100.' ), after: z .string() .optional() .describe( 'The paging cursor token of the last successfully read resource will be returned as the paging.next.after JSON property of a paged response containing more results.' ), properties: z .array(z.string()) .optional() .describe( 'List of the properties to be returned in the response. If any of the specified properties are not present on the requested object(s), they will be ignored.' ), associations: z .array(z.string()) .optional() .describe( 'List of object types to retrieve associated IDs for. If any of the specified associations do not exist, they will be ignored.' ), archived: z .boolean() .optional() .describe('Whether to return only results that have been archived.'), }); export const searchDealsParameters = z.object({ query: z.string().optional(), limit: z.number().optional().default(200), after: z.string().optional(), sorts: z .array( z.object({ propertyName: z.string(), direction: z.union([z.literal('ASCENDING'), z.literal('DESCENDING')]), }) ) .optional(), properties: z.array(z.string()).optional(), filter_groups: z .array( z.object({ filters: z .array( z.object({ high_value: z.string().optional(), property_name: z.string().optional(), values: z.array(z.string()).optional(), value: z.string().optional(), operator: z.union([ z.literal('IN'), z.literal('NOT_HAS_PROPERTY'), z.literal('LT'), z.literal('EQ'), z.literal('GT'), z.literal('NOT_IN'), z.literal('GTE'), z.literal('CONTAINS_TOKEN'), z.literal('HAS_PROPERTY'), z.literal('LTE'), z.literal('NOT_CONTAINS_TOKEN'), z.literal('BETWEEN'), z.literal('NEQ'), ]), }) ) .optional(), }) ) .optional(), }); export const mergeDealParameters = z.object({ object_id_to_merge: z.string().describe('The ID of the object to merge.'), primary_object_id: z .string() .describe('The ID of the primary object of the merge.'), }); export const updateDealParameters = z.object({ deal_id: z.string().describe('The ID of the deal.'), properties: z .object({ firstname: z .string() .optional() .describe('The first name of the contact.'), lastname: z.string().optional().describe('The last name of the contact.'), email: z .string() .optional() .describe('The email address of the contact.'), company: z.string().optional().describe('The company of the contact.'), website: z.string().optional().describe('The website of the contact.'), mobilephone: z .string() .optional() .describe('The mobile phone number of the contact.'), phone: z.string().optional().describe('The phone number of the contact.'), fax: z.string().optional().describe('The fax number of the contact.'), address: z.string().optional().describe('The address of the contact.'), city: z.string().optional().describe('The city of the contact.'), state: z.string().optional().describe('The state of the contact.'), zip: z.string().optional().describe('The zip code of the contact.'), country: z.string().optional().describe('The country of the contact.'), jobtitle: z.string().optional().describe('The job title of the contact.'), industry: z.string().optional().describe('The industry of the contact.'), lifecyclestage: z .enum([ 'subscriber', 'lead', 'marketingqualifiedlead', 'salesqualifiedlead', 'opportunity', 'customer', 'evangelist', 'other', ]) .optional() .describe('The lifecycle stage of the contact.'), }) .optional(), }); export const deleteDealParameters = z.object({ deal_id: z.string().describe('The ID of the deal'), }); ```