universal-mcp-applications 0.1.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- universal_mcp/applications/ahrefs/README.md +51 -0
- universal_mcp/applications/ahrefs/__init__.py +1 -0
- universal_mcp/applications/ahrefs/app.py +2291 -0
- universal_mcp/applications/airtable/README.md +22 -0
- universal_mcp/applications/airtable/__init__.py +1 -0
- universal_mcp/applications/airtable/app.py +479 -0
- universal_mcp/applications/apollo/README.md +44 -0
- universal_mcp/applications/apollo/__init__.py +1 -0
- universal_mcp/applications/apollo/app.py +1847 -0
- universal_mcp/applications/asana/README.md +199 -0
- universal_mcp/applications/asana/__init__.py +1 -0
- universal_mcp/applications/asana/app.py +9509 -0
- universal_mcp/applications/aws-s3/README.md +0 -0
- universal_mcp/applications/aws-s3/__init__.py +1 -0
- universal_mcp/applications/aws-s3/app.py +552 -0
- universal_mcp/applications/bill/README.md +0 -0
- universal_mcp/applications/bill/__init__.py +1 -0
- universal_mcp/applications/bill/app.py +8705 -0
- universal_mcp/applications/box/README.md +307 -0
- universal_mcp/applications/box/__init__.py +1 -0
- universal_mcp/applications/box/app.py +15987 -0
- universal_mcp/applications/braze/README.md +106 -0
- universal_mcp/applications/braze/__init__.py +1 -0
- universal_mcp/applications/braze/app.py +4754 -0
- universal_mcp/applications/cal-com-v2/README.md +150 -0
- universal_mcp/applications/cal-com-v2/__init__.py +1 -0
- universal_mcp/applications/cal-com-v2/app.py +5541 -0
- universal_mcp/applications/calendly/README.md +53 -0
- universal_mcp/applications/calendly/__init__.py +1 -0
- universal_mcp/applications/calendly/app.py +1436 -0
- universal_mcp/applications/canva/README.md +43 -0
- universal_mcp/applications/canva/__init__.py +1 -0
- universal_mcp/applications/canva/app.py +941 -0
- universal_mcp/applications/clickup/README.md +135 -0
- universal_mcp/applications/clickup/__init__.py +1 -0
- universal_mcp/applications/clickup/app.py +5009 -0
- universal_mcp/applications/coda/README.md +108 -0
- universal_mcp/applications/coda/__init__.py +1 -0
- universal_mcp/applications/coda/app.py +3671 -0
- universal_mcp/applications/confluence/README.md +198 -0
- universal_mcp/applications/confluence/__init__.py +1 -0
- universal_mcp/applications/confluence/app.py +6273 -0
- universal_mcp/applications/contentful/README.md +17 -0
- universal_mcp/applications/contentful/__init__.py +1 -0
- universal_mcp/applications/contentful/app.py +364 -0
- universal_mcp/applications/crustdata/README.md +25 -0
- universal_mcp/applications/crustdata/__init__.py +1 -0
- universal_mcp/applications/crustdata/app.py +586 -0
- universal_mcp/applications/dialpad/README.md +202 -0
- universal_mcp/applications/dialpad/__init__.py +1 -0
- universal_mcp/applications/dialpad/app.py +5949 -0
- universal_mcp/applications/digitalocean/README.md +463 -0
- universal_mcp/applications/digitalocean/__init__.py +1 -0
- universal_mcp/applications/digitalocean/app.py +20835 -0
- universal_mcp/applications/domain-checker/README.md +13 -0
- universal_mcp/applications/domain-checker/__init__.py +1 -0
- universal_mcp/applications/domain-checker/app.py +265 -0
- universal_mcp/applications/e2b/README.md +12 -0
- universal_mcp/applications/e2b/__init__.py +1 -0
- universal_mcp/applications/e2b/app.py +187 -0
- universal_mcp/applications/elevenlabs/README.md +88 -0
- universal_mcp/applications/elevenlabs/__init__.py +1 -0
- universal_mcp/applications/elevenlabs/app.py +3235 -0
- universal_mcp/applications/exa/README.md +15 -0
- universal_mcp/applications/exa/__init__.py +1 -0
- universal_mcp/applications/exa/app.py +221 -0
- universal_mcp/applications/falai/README.md +17 -0
- universal_mcp/applications/falai/__init__.py +1 -0
- universal_mcp/applications/falai/app.py +331 -0
- universal_mcp/applications/figma/README.md +49 -0
- universal_mcp/applications/figma/__init__.py +1 -0
- universal_mcp/applications/figma/app.py +1090 -0
- universal_mcp/applications/firecrawl/README.md +20 -0
- universal_mcp/applications/firecrawl/__init__.py +1 -0
- universal_mcp/applications/firecrawl/app.py +514 -0
- universal_mcp/applications/fireflies/README.md +25 -0
- universal_mcp/applications/fireflies/__init__.py +1 -0
- universal_mcp/applications/fireflies/app.py +506 -0
- universal_mcp/applications/fpl/README.md +23 -0
- universal_mcp/applications/fpl/__init__.py +1 -0
- universal_mcp/applications/fpl/app.py +1327 -0
- universal_mcp/applications/fpl/utils/api.py +142 -0
- universal_mcp/applications/fpl/utils/fixtures.py +629 -0
- universal_mcp/applications/fpl/utils/helper.py +982 -0
- universal_mcp/applications/fpl/utils/league_utils.py +546 -0
- universal_mcp/applications/fpl/utils/position_utils.py +68 -0
- universal_mcp/applications/ghost-content/README.md +25 -0
- universal_mcp/applications/ghost-content/__init__.py +1 -0
- universal_mcp/applications/ghost-content/app.py +654 -0
- universal_mcp/applications/github/README.md +1049 -0
- universal_mcp/applications/github/__init__.py +1 -0
- universal_mcp/applications/github/app.py +50600 -0
- universal_mcp/applications/gong/README.md +63 -0
- universal_mcp/applications/gong/__init__.py +1 -0
- universal_mcp/applications/gong/app.py +2297 -0
- universal_mcp/applications/google-ads/README.md +0 -0
- universal_mcp/applications/google-ads/__init__.py +1 -0
- universal_mcp/applications/google-ads/app.py +23 -0
- universal_mcp/applications/google-calendar/README.md +21 -0
- universal_mcp/applications/google-calendar/__init__.py +1 -0
- universal_mcp/applications/google-calendar/app.py +574 -0
- universal_mcp/applications/google-docs/README.md +25 -0
- universal_mcp/applications/google-docs/__init__.py +1 -0
- universal_mcp/applications/google-docs/app.py +760 -0
- universal_mcp/applications/google-drive/README.md +68 -0
- universal_mcp/applications/google-drive/__init__.py +1 -0
- universal_mcp/applications/google-drive/app.py +4936 -0
- universal_mcp/applications/google-gemini/README.md +25 -0
- universal_mcp/applications/google-gemini/__init__.py +1 -0
- universal_mcp/applications/google-gemini/app.py +663 -0
- universal_mcp/applications/google-mail/README.md +31 -0
- universal_mcp/applications/google-mail/__init__.py +1 -0
- universal_mcp/applications/google-mail/app.py +1354 -0
- universal_mcp/applications/google-searchconsole/README.md +21 -0
- universal_mcp/applications/google-searchconsole/__init__.py +1 -0
- universal_mcp/applications/google-searchconsole/app.py +320 -0
- universal_mcp/applications/google-sheet/README.md +36 -0
- universal_mcp/applications/google-sheet/__init__.py +1 -0
- universal_mcp/applications/google-sheet/app.py +1941 -0
- universal_mcp/applications/hashnode/README.md +20 -0
- universal_mcp/applications/hashnode/__init__.py +1 -0
- universal_mcp/applications/hashnode/app.py +455 -0
- universal_mcp/applications/heygen/README.md +44 -0
- universal_mcp/applications/heygen/__init__.py +1 -0
- universal_mcp/applications/heygen/app.py +961 -0
- universal_mcp/applications/http-tools/README.md +16 -0
- universal_mcp/applications/http-tools/__init__.py +1 -0
- universal_mcp/applications/http-tools/app.py +153 -0
- universal_mcp/applications/hubspot/README.md +239 -0
- universal_mcp/applications/hubspot/__init__.py +1 -0
- universal_mcp/applications/hubspot/app.py +416 -0
- universal_mcp/applications/jira/README.md +600 -0
- universal_mcp/applications/jira/__init__.py +1 -0
- universal_mcp/applications/jira/app.py +28804 -0
- universal_mcp/applications/klaviyo/README.md +313 -0
- universal_mcp/applications/klaviyo/__init__.py +1 -0
- universal_mcp/applications/klaviyo/app.py +11236 -0
- universal_mcp/applications/linkedin/README.md +15 -0
- universal_mcp/applications/linkedin/__init__.py +1 -0
- universal_mcp/applications/linkedin/app.py +243 -0
- universal_mcp/applications/mailchimp/README.md +281 -0
- universal_mcp/applications/mailchimp/__init__.py +1 -0
- universal_mcp/applications/mailchimp/app.py +10937 -0
- universal_mcp/applications/markitdown/README.md +12 -0
- universal_mcp/applications/markitdown/__init__.py +1 -0
- universal_mcp/applications/markitdown/app.py +63 -0
- universal_mcp/applications/miro/README.md +151 -0
- universal_mcp/applications/miro/__init__.py +1 -0
- universal_mcp/applications/miro/app.py +5429 -0
- universal_mcp/applications/ms-teams/README.md +42 -0
- universal_mcp/applications/ms-teams/__init__.py +1 -0
- universal_mcp/applications/ms-teams/app.py +1823 -0
- universal_mcp/applications/neon/README.md +74 -0
- universal_mcp/applications/neon/__init__.py +1 -0
- universal_mcp/applications/neon/app.py +2018 -0
- universal_mcp/applications/notion/README.md +30 -0
- universal_mcp/applications/notion/__init__.py +1 -0
- universal_mcp/applications/notion/app.py +527 -0
- universal_mcp/applications/openai/README.md +22 -0
- universal_mcp/applications/openai/__init__.py +1 -0
- universal_mcp/applications/openai/app.py +759 -0
- universal_mcp/applications/outlook/README.md +20 -0
- universal_mcp/applications/outlook/__init__.py +1 -0
- universal_mcp/applications/outlook/app.py +444 -0
- universal_mcp/applications/perplexity/README.md +12 -0
- universal_mcp/applications/perplexity/__init__.py +1 -0
- universal_mcp/applications/perplexity/app.py +65 -0
- universal_mcp/applications/pipedrive/README.md +284 -0
- universal_mcp/applications/pipedrive/__init__.py +1 -0
- universal_mcp/applications/pipedrive/app.py +12924 -0
- universal_mcp/applications/posthog/README.md +132 -0
- universal_mcp/applications/posthog/__init__.py +1 -0
- universal_mcp/applications/posthog/app.py +7125 -0
- universal_mcp/applications/reddit/README.md +135 -0
- universal_mcp/applications/reddit/__init__.py +1 -0
- universal_mcp/applications/reddit/app.py +4652 -0
- universal_mcp/applications/replicate/README.md +18 -0
- universal_mcp/applications/replicate/__init__.py +1 -0
- universal_mcp/applications/replicate/app.py +495 -0
- universal_mcp/applications/resend/README.md +40 -0
- universal_mcp/applications/resend/__init__.py +1 -0
- universal_mcp/applications/resend/app.py +881 -0
- universal_mcp/applications/retell/README.md +21 -0
- universal_mcp/applications/retell/__init__.py +1 -0
- universal_mcp/applications/retell/app.py +333 -0
- universal_mcp/applications/rocketlane/README.md +70 -0
- universal_mcp/applications/rocketlane/__init__.py +1 -0
- universal_mcp/applications/rocketlane/app.py +4346 -0
- universal_mcp/applications/semanticscholar/README.md +25 -0
- universal_mcp/applications/semanticscholar/__init__.py +1 -0
- universal_mcp/applications/semanticscholar/app.py +482 -0
- universal_mcp/applications/semrush/README.md +44 -0
- universal_mcp/applications/semrush/__init__.py +1 -0
- universal_mcp/applications/semrush/app.py +2081 -0
- universal_mcp/applications/sendgrid/README.md +362 -0
- universal_mcp/applications/sendgrid/__init__.py +1 -0
- universal_mcp/applications/sendgrid/app.py +9752 -0
- universal_mcp/applications/sentry/README.md +186 -0
- universal_mcp/applications/sentry/__init__.py +1 -0
- universal_mcp/applications/sentry/app.py +7471 -0
- universal_mcp/applications/serpapi/README.md +14 -0
- universal_mcp/applications/serpapi/__init__.py +1 -0
- universal_mcp/applications/serpapi/app.py +293 -0
- universal_mcp/applications/sharepoint/README.md +0 -0
- universal_mcp/applications/sharepoint/__init__.py +1 -0
- universal_mcp/applications/sharepoint/app.py +215 -0
- universal_mcp/applications/shopify/README.md +321 -0
- universal_mcp/applications/shopify/__init__.py +1 -0
- universal_mcp/applications/shopify/app.py +15392 -0
- universal_mcp/applications/shortcut/README.md +128 -0
- universal_mcp/applications/shortcut/__init__.py +1 -0
- universal_mcp/applications/shortcut/app.py +4478 -0
- universal_mcp/applications/slack/README.md +0 -0
- universal_mcp/applications/slack/__init__.py +1 -0
- universal_mcp/applications/slack/app.py +570 -0
- universal_mcp/applications/spotify/README.md +91 -0
- universal_mcp/applications/spotify/__init__.py +1 -0
- universal_mcp/applications/spotify/app.py +2526 -0
- universal_mcp/applications/supabase/README.md +87 -0
- universal_mcp/applications/supabase/__init__.py +1 -0
- universal_mcp/applications/supabase/app.py +2970 -0
- universal_mcp/applications/tavily/README.md +12 -0
- universal_mcp/applications/tavily/__init__.py +1 -0
- universal_mcp/applications/tavily/app.py +51 -0
- universal_mcp/applications/trello/README.md +266 -0
- universal_mcp/applications/trello/__init__.py +1 -0
- universal_mcp/applications/trello/app.py +10875 -0
- universal_mcp/applications/twillo/README.md +0 -0
- universal_mcp/applications/twillo/__init__.py +1 -0
- universal_mcp/applications/twillo/app.py +269 -0
- universal_mcp/applications/twitter/README.md +100 -0
- universal_mcp/applications/twitter/__init__.py +1 -0
- universal_mcp/applications/twitter/api_segments/__init__.py +0 -0
- universal_mcp/applications/twitter/api_segments/api_segment_base.py +51 -0
- universal_mcp/applications/twitter/api_segments/compliance_api.py +122 -0
- universal_mcp/applications/twitter/api_segments/dm_conversations_api.py +255 -0
- universal_mcp/applications/twitter/api_segments/dm_events_api.py +140 -0
- universal_mcp/applications/twitter/api_segments/likes_api.py +159 -0
- universal_mcp/applications/twitter/api_segments/lists_api.py +395 -0
- universal_mcp/applications/twitter/api_segments/openapi_json_api.py +34 -0
- universal_mcp/applications/twitter/api_segments/spaces_api.py +309 -0
- universal_mcp/applications/twitter/api_segments/trends_api.py +40 -0
- universal_mcp/applications/twitter/api_segments/tweets_api.py +1403 -0
- universal_mcp/applications/twitter/api_segments/usage_api.py +40 -0
- universal_mcp/applications/twitter/api_segments/users_api.py +1498 -0
- universal_mcp/applications/twitter/app.py +46 -0
- universal_mcp/applications/unipile/README.md +28 -0
- universal_mcp/applications/unipile/__init__.py +1 -0
- universal_mcp/applications/unipile/app.py +829 -0
- universal_mcp/applications/whatsapp/README.md +23 -0
- universal_mcp/applications/whatsapp/__init__.py +1 -0
- universal_mcp/applications/whatsapp/app.py +595 -0
- universal_mcp/applications/whatsapp-business/README.md +34 -0
- universal_mcp/applications/whatsapp-business/__init__.py +1 -0
- universal_mcp/applications/whatsapp-business/app.py +1065 -0
- universal_mcp/applications/wrike/README.md +46 -0
- universal_mcp/applications/wrike/__init__.py +1 -0
- universal_mcp/applications/wrike/app.py +1583 -0
- universal_mcp/applications/youtube/README.md +57 -0
- universal_mcp/applications/youtube/__init__.py +1 -0
- universal_mcp/applications/youtube/app.py +1696 -0
- universal_mcp/applications/zenquotes/README.md +12 -0
- universal_mcp/applications/zenquotes/__init__.py +1 -0
- universal_mcp/applications/zenquotes/app.py +31 -0
- universal_mcp_applications-0.1.1.dist-info/METADATA +172 -0
- universal_mcp_applications-0.1.1.dist-info/RECORD +268 -0
- universal_mcp_applications-0.1.1.dist-info/WHEEL +4 -0
- universal_mcp_applications-0.1.1.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Airtable MCP Server
|
|
2
|
+
|
|
3
|
+
An MCP Server for the Airtable API.
|
|
4
|
+
|
|
5
|
+
## 🛠️ Tool List
|
|
6
|
+
|
|
7
|
+
This is automatically generated from OpenAPI schema for the Airtable API.
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
| Tool | Description |
|
|
11
|
+
|------|-------------|
|
|
12
|
+
| `list_bases` | Lists all bases accessible with the current API key. |
|
|
13
|
+
| `list_tables` | Lists all tables within a specified base. |
|
|
14
|
+
| `get_record` | Retrieves a single record by its ID from a specified table within a base. |
|
|
15
|
+
| `list_records` | Lists records from a specified table within a base. |
|
|
16
|
+
| `create_record` | Creates a new record in a specified table within a base. |
|
|
17
|
+
| `update_record` | Updates an existing record in a specified table within a base. |
|
|
18
|
+
| `delete_record` | Deletes a record from a specified table within a base. |
|
|
19
|
+
| `batch_create_records` | Creates multiple records in batches in a specified table. |
|
|
20
|
+
| `batch_update_records` | Updates multiple records in batches in a specified table. |
|
|
21
|
+
| `batch_delete_records` | Deletes multiple records in batches from a specified table. |
|
|
22
|
+
| `batch_upsert_records` | Updates or creates records in batches in a specified table. |
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .app import AirtableApp
|
|
@@ -0,0 +1,479 @@
|
|
|
1
|
+
from collections.abc import Iterable
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
# Import necessary components from pyairtable
|
|
5
|
+
from pyairtable import Api
|
|
6
|
+
from pyairtable.api.base import Base
|
|
7
|
+
from pyairtable.api.table import Table
|
|
8
|
+
from pyairtable.api.types import (
|
|
9
|
+
RecordDeletedDict,
|
|
10
|
+
RecordDict,
|
|
11
|
+
RecordId,
|
|
12
|
+
UpdateRecordDict,
|
|
13
|
+
UpsertResultDict,
|
|
14
|
+
WritableFields,
|
|
15
|
+
)
|
|
16
|
+
from pyairtable.formulas import Formula, to_formula_str
|
|
17
|
+
from universal_mcp.applications.application import APIApplication
|
|
18
|
+
from universal_mcp.integrations import Integration
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class AirtableApp(APIApplication):
|
|
22
|
+
"""
|
|
23
|
+
Application for interacting with the Airtable API to manage bases, tables,
|
|
24
|
+
and records. Requires an Airtable API key configured via integration.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
def __init__(self, integration: Integration | None = None) -> None:
|
|
28
|
+
super().__init__(name="airtable", integration=integration)
|
|
29
|
+
|
|
30
|
+
def _get_client(self) -> Api:
|
|
31
|
+
"""Initializes and returns the pyairtable client after ensuring API key is set."""
|
|
32
|
+
if not self.integration:
|
|
33
|
+
raise ValueError("Integration is not set for AirtableApp.")
|
|
34
|
+
credentials = self.integration.get_credentials()
|
|
35
|
+
api_key = (
|
|
36
|
+
credentials.get("api_key")
|
|
37
|
+
or credentials.get("apiKey")
|
|
38
|
+
or credentials.get("API_KEY")
|
|
39
|
+
)
|
|
40
|
+
if not api_key:
|
|
41
|
+
raise ValueError("Airtable API key is not configured in the integration.")
|
|
42
|
+
return Api(api_key)
|
|
43
|
+
|
|
44
|
+
def _prepare_pyairtable_params(
|
|
45
|
+
self, collected_options: dict[str, Any]
|
|
46
|
+
) -> dict[str, Any]:
|
|
47
|
+
"""
|
|
48
|
+
Extracts the actual parameters for pyairtable from the collected options.
|
|
49
|
+
If `collected_options` contains a key "options" whose value is a dictionary
|
|
50
|
+
(as might come from a JSON tool call), that nested dictionary is used.
|
|
51
|
+
Otherwise, `collected_options` itself is assumed to contain the direct parameters.
|
|
52
|
+
"""
|
|
53
|
+
nested_options = collected_options.get("options")
|
|
54
|
+
if isinstance(nested_options, dict):
|
|
55
|
+
return nested_options
|
|
56
|
+
|
|
57
|
+
return collected_options
|
|
58
|
+
|
|
59
|
+
def list_bases(self) -> list[Base] | str:
|
|
60
|
+
"""
|
|
61
|
+
Lists all bases accessible with the current API key.
|
|
62
|
+
|
|
63
|
+
Returns:
|
|
64
|
+
A list of pyairtable.api.base.Base objects on success,
|
|
65
|
+
or a string containing an error message on failure.
|
|
66
|
+
|
|
67
|
+
Tags:
|
|
68
|
+
list, base, important
|
|
69
|
+
"""
|
|
70
|
+
try:
|
|
71
|
+
client = self._get_client()
|
|
72
|
+
return client.bases()
|
|
73
|
+
except Exception as e:
|
|
74
|
+
return f"Error listing bases: {type(e).__name__} - {e}"
|
|
75
|
+
|
|
76
|
+
def list_tables(self, base_id: str) -> list[Table] | str:
|
|
77
|
+
"""
|
|
78
|
+
Lists all tables within a specified base.
|
|
79
|
+
|
|
80
|
+
Args:
|
|
81
|
+
base_id: The ID of the base.
|
|
82
|
+
|
|
83
|
+
Returns:
|
|
84
|
+
A list of pyairtable.api.table.Table objects on success,
|
|
85
|
+
or a string containing an error message on failure.
|
|
86
|
+
|
|
87
|
+
Tags:
|
|
88
|
+
list, table, important
|
|
89
|
+
"""
|
|
90
|
+
try:
|
|
91
|
+
client = self._get_client()
|
|
92
|
+
base = client.base(base_id)
|
|
93
|
+
return base.tables()
|
|
94
|
+
except Exception as e:
|
|
95
|
+
return (
|
|
96
|
+
f"Error listing tables for base '{base_id}': {type(e).__name__} - {e}"
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
def get_record(
|
|
100
|
+
self, base_id: str, table_id_or_name: str, record_id: RecordId, **options: Any
|
|
101
|
+
) -> RecordDict | str:
|
|
102
|
+
"""
|
|
103
|
+
Retrieves a single record by its ID from a specified table within a base.
|
|
104
|
+
|
|
105
|
+
Args:
|
|
106
|
+
base_id: The ID of the base.
|
|
107
|
+
table_id_or_name: The ID or name of the table.
|
|
108
|
+
record_id: The ID of the record to retrieve.
|
|
109
|
+
**options: Additional options for retrieving the record (e.g., cell_format, user_locale).
|
|
110
|
+
If these are passed within a nested "options" dict from a tool call,
|
|
111
|
+
they will be extracted.
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
A dictionary representing the record on success,
|
|
115
|
+
or a string containing an error message on failure.
|
|
116
|
+
|
|
117
|
+
Tags:
|
|
118
|
+
get, record, important
|
|
119
|
+
"""
|
|
120
|
+
try:
|
|
121
|
+
client = self._get_client()
|
|
122
|
+
table = client.table(base_id, table_id_or_name)
|
|
123
|
+
pyairtable_params = self._prepare_pyairtable_params(options)
|
|
124
|
+
return table.get(record_id, **pyairtable_params)
|
|
125
|
+
except Exception as e:
|
|
126
|
+
return f"Error getting record '{record_id}' from '{table_id_or_name}' in '{base_id}': {type(e).__name__} - {e}"
|
|
127
|
+
|
|
128
|
+
def list_records(
|
|
129
|
+
self, base_id: str, table_id_or_name: str, **options: Any
|
|
130
|
+
) -> list[RecordDict] | str:
|
|
131
|
+
"""
|
|
132
|
+
Lists records from a specified table within a base.
|
|
133
|
+
|
|
134
|
+
Args:
|
|
135
|
+
base_id: The ID of the base.
|
|
136
|
+
table_id_or_name: The ID or name of the table.
|
|
137
|
+
**options: Additional options for listing records (e.g., view, max_records, formula, sort).
|
|
138
|
+
Formula can be a string or a pyairtable.formulas.Formula object.
|
|
139
|
+
If these are passed within a nested "options" dict from a tool call,
|
|
140
|
+
they will be extracted.
|
|
141
|
+
|
|
142
|
+
Returns:
|
|
143
|
+
A list of dictionaries, where each dictionary represents a record, on success,
|
|
144
|
+
or a string containing an error message on failure.
|
|
145
|
+
|
|
146
|
+
Tags:
|
|
147
|
+
list, record, important
|
|
148
|
+
"""
|
|
149
|
+
try:
|
|
150
|
+
client = self._get_client()
|
|
151
|
+
table = client.table(base_id, table_id_or_name)
|
|
152
|
+
pyairtable_params = self._prepare_pyairtable_params(options)
|
|
153
|
+
|
|
154
|
+
# Convert Formula object to string if provided, after preparing params
|
|
155
|
+
if "formula" in pyairtable_params and isinstance(
|
|
156
|
+
pyairtable_params["formula"], Formula
|
|
157
|
+
):
|
|
158
|
+
pyairtable_params["formula"] = to_formula_str(
|
|
159
|
+
pyairtable_params["formula"]
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
return table.all(**pyairtable_params)
|
|
163
|
+
except Exception as e:
|
|
164
|
+
return f"Error listing records from '{table_id_or_name}' in '{base_id}': {type(e).__name__} - {e}"
|
|
165
|
+
|
|
166
|
+
def create_record(
|
|
167
|
+
self,
|
|
168
|
+
base_id: str,
|
|
169
|
+
table_id_or_name: str,
|
|
170
|
+
fields: WritableFields,
|
|
171
|
+
**options: Any, # Captures typecast, use_field_ids etc.
|
|
172
|
+
) -> RecordDict | str:
|
|
173
|
+
"""
|
|
174
|
+
Creates a new record in a specified table within a base.
|
|
175
|
+
|
|
176
|
+
Args:
|
|
177
|
+
base_id: The ID of the base.
|
|
178
|
+
table_id_or_name: The ID or name of the table.
|
|
179
|
+
fields: A dictionary where keys are field names/IDs and values are the field data.
|
|
180
|
+
**options: Additional options for creating the record (e.g., typecast, use_field_ids).
|
|
181
|
+
If these are passed within a nested "options" dict from a tool call,
|
|
182
|
+
they will be extracted.
|
|
183
|
+
|
|
184
|
+
Returns:
|
|
185
|
+
A dictionary representing the newly created record on success,
|
|
186
|
+
or a string containing an error message on failure.
|
|
187
|
+
|
|
188
|
+
Tags:
|
|
189
|
+
create, record, important
|
|
190
|
+
"""
|
|
191
|
+
try:
|
|
192
|
+
client = self._get_client()
|
|
193
|
+
table = client.table(base_id, table_id_or_name)
|
|
194
|
+
# pyairtable's Table.create() takes typecast and use_field_ids as named args,
|
|
195
|
+
# not as **kwargs. We need to extract them or use defaults.
|
|
196
|
+
|
|
197
|
+
prepared_options = self._prepare_pyairtable_params(options)
|
|
198
|
+
prepared_options.get("typecast", False)
|
|
199
|
+
prepared_options.get(
|
|
200
|
+
"use_field_ids"
|
|
201
|
+
) # Let pyairtable handle default if None
|
|
202
|
+
|
|
203
|
+
# Ensure only valid kwargs for pyairtable's `create` are passed if it doesn't use **kwargs for these
|
|
204
|
+
# For pyairtable.Table.create, it only takes `typecast` and `use_field_ids` as specific keyword args.
|
|
205
|
+
# The `**options` in `AirtableApp` could collect other things if the tool call sends them.
|
|
206
|
+
# The `pyairtable.Table.create` signature is:
|
|
207
|
+
# create(self, fields: WritableFields, typecast: bool = False, use_field_ids: Optional[bool] = None)
|
|
208
|
+
# It does NOT take a general **kwargs.
|
|
209
|
+
|
|
210
|
+
# So, we must call it with the specific parameters.
|
|
211
|
+
# `_prepare_pyairtable_params` helps if "options" is nested, but we still need to map.
|
|
212
|
+
|
|
213
|
+
call_kwargs = {}
|
|
214
|
+
if "typecast" in prepared_options:
|
|
215
|
+
call_kwargs["typecast"] = prepared_options["typecast"]
|
|
216
|
+
if (
|
|
217
|
+
"use_field_ids" in prepared_options
|
|
218
|
+
): # Pass it only if explicitly provided
|
|
219
|
+
call_kwargs["use_field_ids"] = prepared_options["use_field_ids"]
|
|
220
|
+
|
|
221
|
+
return table.create(fields=fields, **call_kwargs)
|
|
222
|
+
except Exception as e:
|
|
223
|
+
return f"Error creating record in '{table_id_or_name}' in '{base_id}': {type(e).__name__} - {e}"
|
|
224
|
+
|
|
225
|
+
def update_record(
|
|
226
|
+
self,
|
|
227
|
+
base_id: str,
|
|
228
|
+
table_id_or_name: str,
|
|
229
|
+
record_id: RecordId,
|
|
230
|
+
fields: WritableFields,
|
|
231
|
+
**options: Any, # Captures replace, typecast, use_field_ids etc.
|
|
232
|
+
) -> RecordDict | str:
|
|
233
|
+
"""
|
|
234
|
+
Updates an existing record in a specified table within a base.
|
|
235
|
+
|
|
236
|
+
Args:
|
|
237
|
+
base_id: The ID of the base.
|
|
238
|
+
table_id_or_name: The ID or name of the table.
|
|
239
|
+
record_id: The ID of the record to update.
|
|
240
|
+
fields: A dictionary where keys are field names/IDs and values are the field data to update.
|
|
241
|
+
**options: Additional options for updating the record (e.g., replace, typecast, use_field_ids).
|
|
242
|
+
If these are passed within a nested "options" dict from a tool call,
|
|
243
|
+
they will be extracted.
|
|
244
|
+
|
|
245
|
+
Returns:
|
|
246
|
+
A dictionary representing the updated record on success,
|
|
247
|
+
or a string containing an error message on failure.
|
|
248
|
+
|
|
249
|
+
Tags:
|
|
250
|
+
update, record
|
|
251
|
+
"""
|
|
252
|
+
try:
|
|
253
|
+
client = self._get_client()
|
|
254
|
+
table = client.table(base_id, table_id_or_name)
|
|
255
|
+
# pyairtable.Table.update() signature:
|
|
256
|
+
# update(self, record_id: RecordId, fields: WritableFields, replace: bool = False,
|
|
257
|
+
# typecast: bool = False, use_field_ids: Optional[bool] = None)
|
|
258
|
+
# It does NOT take a general **kwargs.
|
|
259
|
+
|
|
260
|
+
prepared_options = self._prepare_pyairtable_params(options)
|
|
261
|
+
call_kwargs = {}
|
|
262
|
+
if "replace" in prepared_options:
|
|
263
|
+
call_kwargs["replace"] = prepared_options["replace"]
|
|
264
|
+
if "typecast" in prepared_options:
|
|
265
|
+
call_kwargs["typecast"] = prepared_options["typecast"]
|
|
266
|
+
if "use_field_ids" in prepared_options:
|
|
267
|
+
call_kwargs["use_field_ids"] = prepared_options["use_field_ids"]
|
|
268
|
+
|
|
269
|
+
return table.update(record_id, fields=fields, **call_kwargs)
|
|
270
|
+
except Exception as e:
|
|
271
|
+
return f"Error updating record '{record_id}' in '{table_id_or_name}' in '{base_id}': {type(e).__name__} - {e}"
|
|
272
|
+
|
|
273
|
+
def delete_record(
|
|
274
|
+
self, base_id: str, table_id_or_name: str, record_id: RecordId
|
|
275
|
+
) -> RecordDeletedDict | str:
|
|
276
|
+
"""
|
|
277
|
+
Deletes a record from a specified table within a base.
|
|
278
|
+
|
|
279
|
+
Args:
|
|
280
|
+
base_id: The ID of the base.
|
|
281
|
+
table_id_or_name: The ID or name of the table.
|
|
282
|
+
record_id: The ID of the record to delete.
|
|
283
|
+
|
|
284
|
+
Returns:
|
|
285
|
+
A dictionary confirming the deletion on success,
|
|
286
|
+
or a string containing an error message on failure.
|
|
287
|
+
|
|
288
|
+
Tags:
|
|
289
|
+
delete, record
|
|
290
|
+
"""
|
|
291
|
+
try:
|
|
292
|
+
client = self._get_client()
|
|
293
|
+
table = client.table(base_id, table_id_or_name)
|
|
294
|
+
return table.delete(record_id)
|
|
295
|
+
except Exception as e:
|
|
296
|
+
return f"Error deleting record '{record_id}' from '{table_id_or_name}' in '{base_id}': {type(e).__name__} - {e}"
|
|
297
|
+
|
|
298
|
+
def batch_create_records(
|
|
299
|
+
self,
|
|
300
|
+
base_id: str,
|
|
301
|
+
table_id_or_name: str,
|
|
302
|
+
records: Iterable[WritableFields],
|
|
303
|
+
**options: Any, # Captures typecast, use_field_ids etc.
|
|
304
|
+
) -> list[RecordDict] | str:
|
|
305
|
+
"""
|
|
306
|
+
Creates multiple records in batches in a specified table.
|
|
307
|
+
|
|
308
|
+
Args:
|
|
309
|
+
base_id: The ID of the base.
|
|
310
|
+
table_id_or_name: The ID or name of the table.
|
|
311
|
+
records: An iterable of dictionaries, where each dictionary contains the fields for a new record.
|
|
312
|
+
**options: Additional options for creating records (e.g., typecast, use_field_ids).
|
|
313
|
+
If these are passed within a nested "options" dict from a tool call,
|
|
314
|
+
they will be extracted.
|
|
315
|
+
|
|
316
|
+
Returns:
|
|
317
|
+
A list of dictionaries representing the newly created records on success,
|
|
318
|
+
or a string containing an error message on failure.
|
|
319
|
+
|
|
320
|
+
Tags:
|
|
321
|
+
create, record, batch
|
|
322
|
+
"""
|
|
323
|
+
try:
|
|
324
|
+
client = self._get_client()
|
|
325
|
+
table = client.table(base_id, table_id_or_name)
|
|
326
|
+
# pyairtable.Table.batch_create() signature:
|
|
327
|
+
# batch_create(self, records: Iterable[WritableFields], typecast: bool = False, use_field_ids: Optional[bool] = None)
|
|
328
|
+
# It does NOT take a general **kwargs.
|
|
329
|
+
|
|
330
|
+
prepared_options = self._prepare_pyairtable_params(options)
|
|
331
|
+
call_kwargs = {}
|
|
332
|
+
if "typecast" in prepared_options:
|
|
333
|
+
call_kwargs["typecast"] = prepared_options["typecast"]
|
|
334
|
+
if "use_field_ids" in prepared_options:
|
|
335
|
+
call_kwargs["use_field_ids"] = prepared_options["use_field_ids"]
|
|
336
|
+
|
|
337
|
+
return table.batch_create(records, **call_kwargs)
|
|
338
|
+
except Exception as e:
|
|
339
|
+
return f"Error batch creating records in '{table_id_or_name}' in '{base_id}': {type(e).__name__} - {e}"
|
|
340
|
+
|
|
341
|
+
def batch_update_records(
|
|
342
|
+
self,
|
|
343
|
+
base_id: str,
|
|
344
|
+
table_id_or_name: str,
|
|
345
|
+
records: Iterable[UpdateRecordDict],
|
|
346
|
+
**options: Any, # Captures replace, typecast, use_field_ids etc.
|
|
347
|
+
) -> list[RecordDict] | str:
|
|
348
|
+
"""
|
|
349
|
+
Updates multiple records in batches in a specified table.
|
|
350
|
+
|
|
351
|
+
Args:
|
|
352
|
+
base_id: The ID of the base.
|
|
353
|
+
table_id_or_name: The ID or name of the table.
|
|
354
|
+
records: An iterable of dictionaries, where each dictionary must contain 'id' and 'fields' for the record to update.
|
|
355
|
+
**options: Additional options for updating records (e.g., replace, typecast, use_field_ids).
|
|
356
|
+
If these are passed within a nested "options" dict from a tool call,
|
|
357
|
+
they will be extracted.
|
|
358
|
+
|
|
359
|
+
Returns:
|
|
360
|
+
A list of dictionaries representing the updated records on success,
|
|
361
|
+
or a string containing an error message on failure.
|
|
362
|
+
|
|
363
|
+
Tags:
|
|
364
|
+
update, record, batch
|
|
365
|
+
"""
|
|
366
|
+
try:
|
|
367
|
+
client = self._get_client()
|
|
368
|
+
table = client.table(base_id, table_id_or_name)
|
|
369
|
+
# pyairtable.Table.batch_update() signature:
|
|
370
|
+
# batch_update(self, records: Iterable[UpdateRecordDict], replace: bool = False,
|
|
371
|
+
# typecast: bool = False, use_field_ids: Optional[bool] = None)
|
|
372
|
+
# It does NOT take a general **kwargs.
|
|
373
|
+
|
|
374
|
+
prepared_options = self._prepare_pyairtable_params(options)
|
|
375
|
+
call_kwargs = {}
|
|
376
|
+
if "replace" in prepared_options:
|
|
377
|
+
call_kwargs["replace"] = prepared_options["replace"]
|
|
378
|
+
if "typecast" in prepared_options:
|
|
379
|
+
call_kwargs["typecast"] = prepared_options["typecast"]
|
|
380
|
+
if "use_field_ids" in prepared_options:
|
|
381
|
+
call_kwargs["use_field_ids"] = prepared_options["use_field_ids"]
|
|
382
|
+
|
|
383
|
+
return table.batch_update(records, **call_kwargs)
|
|
384
|
+
except Exception as e:
|
|
385
|
+
return f"Error batch updating records in '{table_id_or_name}' in '{base_id}': {type(e).__name__} - {e}"
|
|
386
|
+
|
|
387
|
+
def batch_delete_records(
|
|
388
|
+
self, base_id: str, table_id_or_name: str, record_ids: Iterable[RecordId]
|
|
389
|
+
) -> list[RecordDeletedDict] | str:
|
|
390
|
+
"""
|
|
391
|
+
Deletes multiple records in batches from a specified table.
|
|
392
|
+
|
|
393
|
+
Args:
|
|
394
|
+
base_id: The ID of the base.
|
|
395
|
+
table_id_or_name: The ID or name of the table.
|
|
396
|
+
record_ids: An iterable of record IDs to delete.
|
|
397
|
+
|
|
398
|
+
Returns:
|
|
399
|
+
A list of dictionaries confirming the deletion status for each record on success,
|
|
400
|
+
or a string containing an error message on failure.
|
|
401
|
+
|
|
402
|
+
Tags:
|
|
403
|
+
delete, record, batch
|
|
404
|
+
"""
|
|
405
|
+
try:
|
|
406
|
+
client = self._get_client()
|
|
407
|
+
table = client.table(base_id, table_id_or_name)
|
|
408
|
+
return table.batch_delete(record_ids)
|
|
409
|
+
except Exception as e:
|
|
410
|
+
return f"Error batch deleting records from '{table_id_or_name}' in '{base_id}': {type(e).__name__} - {e}"
|
|
411
|
+
|
|
412
|
+
def batch_upsert_records(
|
|
413
|
+
self,
|
|
414
|
+
base_id: str,
|
|
415
|
+
table_id_or_name: str,
|
|
416
|
+
records: Iterable[
|
|
417
|
+
dict[str, Any]
|
|
418
|
+
], # pyairtable expects Dict, not UpdateRecordDict here
|
|
419
|
+
key_fields: list[str],
|
|
420
|
+
**options: Any, # Captures replace, typecast, use_field_ids etc.
|
|
421
|
+
) -> UpsertResultDict | str:
|
|
422
|
+
"""
|
|
423
|
+
Updates or creates records in batches in a specified table.
|
|
424
|
+
|
|
425
|
+
Records are matched by 'id' if provided, or by 'key_fields'.
|
|
426
|
+
|
|
427
|
+
Args:
|
|
428
|
+
base_id: The ID of the base.
|
|
429
|
+
table_id_or_name: The ID or name of the table.
|
|
430
|
+
records: An iterable of dictionaries, where each dictionary contains either
|
|
431
|
+
'id' and 'fields' for existing records, or just 'fields' for new records.
|
|
432
|
+
key_fields: A list of field names/IDs used to match records if 'id' is not provided.
|
|
433
|
+
**options: Additional options for upserting records (e.g., replace, typecast, use_field_ids).
|
|
434
|
+
If these are passed within a nested "options" dict from a tool call,
|
|
435
|
+
they will be extracted.
|
|
436
|
+
|
|
437
|
+
Returns:
|
|
438
|
+
A dictionary containing lists of created/updated record IDs and the affected records on success,
|
|
439
|
+
or a string containing an error message on failure.
|
|
440
|
+
|
|
441
|
+
Tags:
|
|
442
|
+
create, update, record, batch, upsert
|
|
443
|
+
"""
|
|
444
|
+
try:
|
|
445
|
+
client = self._get_client()
|
|
446
|
+
table = client.table(base_id, table_id_or_name)
|
|
447
|
+
# pyairtable.Table.batch_upsert() signature:
|
|
448
|
+
# batch_upsert(self, records: Iterable[Dict[str, Any]], key_fields: List[FieldName],
|
|
449
|
+
# replace: bool = False, typecast: bool = False, use_field_ids: Optional[bool] = None)
|
|
450
|
+
# It does NOT take a general **kwargs.
|
|
451
|
+
|
|
452
|
+
prepared_options = self._prepare_pyairtable_params(options)
|
|
453
|
+
call_kwargs = {}
|
|
454
|
+
if "replace" in prepared_options:
|
|
455
|
+
call_kwargs["replace"] = prepared_options["replace"]
|
|
456
|
+
if "typecast" in prepared_options:
|
|
457
|
+
call_kwargs["typecast"] = prepared_options["typecast"]
|
|
458
|
+
if "use_field_ids" in prepared_options:
|
|
459
|
+
call_kwargs["use_field_ids"] = prepared_options["use_field_ids"]
|
|
460
|
+
|
|
461
|
+
return table.batch_upsert(records, key_fields=key_fields, **call_kwargs)
|
|
462
|
+
except Exception as e:
|
|
463
|
+
return f"Error batch upserting records in '{table_id_or_name}' in '{base_id}': {type(e).__name__} - {e}"
|
|
464
|
+
|
|
465
|
+
def list_tools(self):
|
|
466
|
+
"""Returns a list of methods exposed as tools."""
|
|
467
|
+
return [
|
|
468
|
+
self.list_bases,
|
|
469
|
+
self.list_tables,
|
|
470
|
+
self.get_record,
|
|
471
|
+
self.list_records,
|
|
472
|
+
self.create_record,
|
|
473
|
+
self.update_record,
|
|
474
|
+
self.delete_record,
|
|
475
|
+
self.batch_create_records,
|
|
476
|
+
self.batch_update_records,
|
|
477
|
+
self.batch_delete_records,
|
|
478
|
+
self.batch_upsert_records,
|
|
479
|
+
]
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# ApolloApp MCP Server
|
|
2
|
+
|
|
3
|
+
An MCP Server for the ApolloApp API.
|
|
4
|
+
|
|
5
|
+
## 🛠️ Tool List
|
|
6
|
+
|
|
7
|
+
This is automatically generated from OpenAPI schema for the ApolloApp API.
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
| Tool | Description |
|
|
11
|
+
|------|-------------|
|
|
12
|
+
| `people_enrichment` | Matches a person based on provided identifying information such as name, email, organization, or LinkedIn URL, with options to reveal personal emails and phone numbers. |
|
|
13
|
+
| `bulk_people_enrichment` | Performs a bulk match operation on people data using a POST request to the "/people/bulk_match" endpoint, accepting query parameters to control the reveal of personal emails and phone numbers, and optionally specifying a webhook URL, with the request body containing JSON data. |
|
|
14
|
+
| `organization_enrichment` | Retrieves enriched organization data for a company specified by its domain name. |
|
|
15
|
+
| `bulk_organization_enrichment` | Enriches multiple organizations in bulk by submitting an array of domain names and returns detailed company profiles in a single request. |
|
|
16
|
+
| `people_search` | Searches for people matching specified criteria including titles, locations, seniorities, organization details, and keywords, returning paginated results. |
|
|
17
|
+
| `organization_search` | Searches mixed companies based on various criteria such as employee ranges, locations, revenue range, technology usage, keyword tags, organization names, and IDs, supporting pagination. |
|
|
18
|
+
| `organization_jobs_postings` | Retrieves a paginated list of job postings for a specified organization using the "GET" method, allowing optional pagination parameters for page and items per page. |
|
|
19
|
+
| `create_an_account` | Creates a new account resource using the provided query parameters such as name, domain, owner ID, account stage ID, phone, and raw address. |
|
|
20
|
+
| `update_an_account` | Updates an account identified by `{account_id}` with specified parameters such as `name`, `domain`, `owner_id`, `account_stage_id`, `raw_address`, and `phone`, returning a status message upon successful modification. |
|
|
21
|
+
| `search_for_accounts` | Searches for accounts based on organization name, account stage IDs, sorting, and pagination parameters, returning matching results. |
|
|
22
|
+
| `update_account_stage` | Updates multiple account records in bulk by their specified IDs, assigning each to the given account stage ID. |
|
|
23
|
+
| `update_account_ownership` | Updates the owners of multiple accounts by assigning a specified owner ID to the given list of account IDs. |
|
|
24
|
+
| `list_account_stages` | Retrieves a list of account stages. |
|
|
25
|
+
| `create_a_contact` | Creates a new contact with specified details such as name, organization, contact information, and labels. |
|
|
26
|
+
| `update_a_contact` | Updates or replaces the details of a specific contact identified by contact_id using the provided parameters as new values for the contact record. |
|
|
27
|
+
| `search_for_contacts` | Searches contacts based on keywords, contact stage IDs, sorting, and pagination parameters, returning a filtered and sorted list of contacts. |
|
|
28
|
+
| `update_contact_stage` | Updates the stage of multiple contacts by specifying their IDs and the new contact stage ID via a POST request. |
|
|
29
|
+
| `update_contact_ownership` | Updates the owners of specified contacts by assigning a new owner ID to the provided list of contact IDs. |
|
|
30
|
+
| `list_contact_stages` | Retrieves a list of all available contact stage IDs from the Apollo account[2][4]. |
|
|
31
|
+
| `create_deal` | Creates a new opportunity with specified details such as name, owner, account, amount, stage, and closed date. |
|
|
32
|
+
| `list_all_deals` | Searches and retrieves a paginated list of opportunities with optional sorting by a specified field. |
|
|
33
|
+
| `update_deal` | Updates specific fields of an opportunity resource identified by opportunity_id using a PATCH request[2][4][5]. |
|
|
34
|
+
| `list_deal_stages` | Retrieves a list of opportunity stages representing the different phases in the sales pipeline. |
|
|
35
|
+
| `add_contacts_to_sequence` | Adds specified contact IDs to an email campaign sequence, configuring how and when emails are sent to each contact and supporting various filtering options. |
|
|
36
|
+
| `update_contact_status_sequence` | Posts a request to remove or stop specified contact IDs from given emailer campaign IDs based on the selected mode. |
|
|
37
|
+
| `create_task` | Creates multiple tasks in bulk with specified user, contact IDs, priority, due date, type, status, and optional note parameters. |
|
|
38
|
+
| `search_tasks` | Searches for tasks using specified parameters and returns a paginated list of results, allowing users to sort by a field and filter by open factor names. |
|
|
39
|
+
| `get_a_list_of_users` | Searches for users with optional pagination parameters to specify the page number and number of results per page. |
|
|
40
|
+
| `get_a_list_of_email_accounts` | Retrieves a list of all available email accounts and their summary information. |
|
|
41
|
+
| `get_a_list_of_all_liststags` | Retrieves a list of labels. |
|
|
42
|
+
| `get_a_list_of_all_custom_fields` | Retrieves a list of all typed custom fields configured in the system. |
|
|
43
|
+
| `view_deal` | View Deal by opportunity_id |
|
|
44
|
+
| `search_for_sequences` | Search for Sequences by name |
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .app import ApolloApp
|