@relvo/mcp 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +47 -154
- package/bin/relvo-mcp.mjs +1 -1
- package/dist/client/agent-run.js +681 -0
- package/dist/client/browser.js +652 -0
- package/dist/client/evm-wallet.js +214 -0
- package/dist/client/index.js +3 -360
- package/dist/client/local-input.js +18 -11
- package/dist/client/local-profile.js +22 -110
- package/dist/client/local-setup.js +0 -1
- package/dist/client/tool-name-hints.js +48 -0
- package/dist/client/wallet-access.js +207 -0
- package/dist/mcp/agent-server.js +237 -0
- package/dist/mcp/context.js +3 -2
- package/dist/mcp/host-schema.js +47 -0
- package/dist/mcp/instructions.js +12 -2
- package/dist/mcp/local-upload.js +12 -4
- package/dist/mcp/operations.js +30 -0
- package/dist/mcp/runtime.js +25 -5
- package/dist/mcp/server.js +191 -37
- package/dist/mcp/version.js +1 -0
- package/dist/schema/accountRequestMethods.js +1 -0
- package/dist/schema/cronValidator.js +150 -0
- package/dist/schema/platformApiKey.js +5 -5
- package/dist/schema/platformBillingConstants.js +3 -0
- package/dist/schema/platformCapabilityFamilies.js +269 -0
- package/dist/schema/platformConnectionCatalog.js +20 -3
- package/dist/schema/platformConnectionPolicy.js +26 -0
- package/dist/schema/platformCustomTools.js +113 -0
- package/dist/schema/platformFunding.js +9 -0
- package/dist/schema/platformHttpConstraints.js +7 -0
- package/dist/schema/platformMcpTools.js +7 -0
- package/dist/schema/platformMetaTools.js +8 -6
- package/dist/schema/platformMonitorSchedule.js +123 -0
- package/dist/schema/platformMonitors.js +159 -0
- package/dist/schema/platformOAuth.js +7 -0
- package/dist/schema/platformPublicExecution.js +53 -15
- package/dist/schema/platformRoutes.js +61 -1
- package/dist/schema/platformSkills.js +1 -1
- package/dist/schema/platformTeamSecretName.js +3 -0
- package/dist/schema/platformTeamSkills.js +49 -0
- package/dist/schema/platformToolAccess.js +18 -0
- package/dist/schema/platformTriggers.js +152 -0
- package/dist/schema/platformWorkflows.js +100 -0
- package/dist/schema/scheduleTimeZone.js +15 -0
- package/dist/schema/toolDiscovery.js +20 -3
- package/dist/schema/toolInputRepair.js +110 -0
- package/dist/schema/toolResultContext.js +1 -1
- package/package.json +1 -1
- package/dist/schema/amazonAds.js +0 -13
- package/dist/schema/oauth2.js +0 -64
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
const variants = {
|
|
2
|
+
generate_video: ["generate_openrouter_video"],
|
|
3
|
+
generate_avatar_video: ["animate_kling_avatar", "generate_omnihuman_video"],
|
|
4
|
+
search_people: ["apollo_people_search", "anyapi_apollo_people_search", "anyapi_people_search_ai_ark", "anyapi_people_search_crustdata",
|
|
5
|
+
"anyapi_people_search_crustdata_v3", "anyapi_people_search_fullenrich", "anyapi_people_search_lusha", "anyapi_people_search_peopledatalabs",
|
|
6
|
+
"anyapi_people_search_prospeo", "anyapi_people_search_quickenrich", "pdl_people_search", "prospeo_people_search",
|
|
7
|
+
"firecrawl_fullenrich_people_search", "brightdata_business_people_search"],
|
|
8
|
+
search_organizations: ["apollo_company_search", "anyapi_apollo_organizations_search", "anyapi_company_search_ai_ark",
|
|
9
|
+
"anyapi_company_search_crustdata", "anyapi_company_search_crustdata_v3", "anyapi_company_search_fullenrich",
|
|
10
|
+
"anyapi_company_search_peopledatalabs", "anyapi_company_search_prospeo", "anyapi_company_search_quickenrich", "pdl_company_search",
|
|
11
|
+
"prospeo_company_search", "firecrawl_fullenrich_companies_search", "brightdata_business_company_search",
|
|
12
|
+
"predictleads_discover_companies", "predictleads_discover_extended_companies"],
|
|
13
|
+
find_companies: ["hunter_discover", "hunter_discover_people"],
|
|
14
|
+
enrich_organization: ["apollo_company_enrich", "apollo_companies_enrich", "anyapi_apollo_organization_enrich",
|
|
15
|
+
"anyapi_apollo_organizations_bulk_enrich", "anyapi_company_enrichment_crustdata", "anyapi_company_enrichment_crustdata_v3",
|
|
16
|
+
"anyapi_company_enrichment_lusha", "anyapi_company_enrichment_peopledatalabs", "anyapi_company_enrichment_prospeo", "pdl_company_enrich",
|
|
17
|
+
"pdl_companies_bulk_enrich", "prospeo_company_enrich", "prospeo_companies_enrich", "hunter_company_enrich", "findymail_company_enrich",
|
|
18
|
+
"firecrawl_datalegion_companies_enrich_base", "firecrawl_datalegion_companies_enrich_premium", "firecrawl_fullenrich_companies_lookup",
|
|
19
|
+
"predictleads_company", "predictleads_extended_company"],
|
|
20
|
+
get_organization_job_postings: ["apollo_company_jobs", "anyapi_apollo_organization_jobs"],
|
|
21
|
+
find_work_email: ["hunter_email_find", "findymail_email_find", "findymail_email_find_profile", "anyapi_email_find",
|
|
22
|
+
"anyapi_email_finding_dropleads", "anyapi_email_finding_icypeas", "anyapi_email_finding_quickenrich", "anyapi_email_finding_zerobounce",
|
|
23
|
+
"anyapi_linkedin_email", "anyapi_person_enrichment_bettercontact"],
|
|
24
|
+
find_company_emails: ["hunter_domain_search", "anyapi_email_finding_hunter_domain", "findymail_domain_contacts",
|
|
25
|
+
"anyapi_people_search_quickenrich_company"],
|
|
26
|
+
verify_email: ["hunter_email_verify", "debounce_email_verify", "findymail_email_verify", "anyapi_email_verify",
|
|
27
|
+
"anyapi_email_verification_allegrow", "anyapi_email_verification_bounceban", "anyapi_email_verification_icypeas",
|
|
28
|
+
"anyapi_email_verification_zerobounce"],
|
|
29
|
+
search_x_posts: ["anyapi_twitter_search", "tikhub_x_web_fetch_search_timeline"],
|
|
30
|
+
fetch_x_posts: ["tikhub_x_web_fetch_tweet_detail"],
|
|
31
|
+
fetch_x_posts_by_url: ["anyapi_twitter_tweet", "brightdata_twitter_posts_collect_by_url"],
|
|
32
|
+
get_x_post_comments: ["anyapi_twitter_replies", "tikhub_x_web_fetch_post_comments"],
|
|
33
|
+
get_x_profile: ["anyapi_twitter_profile", "tikhub_x_web_fetch_user_profile", "brightdata_twitter_profiles_collect_by_url"],
|
|
34
|
+
get_x_trends: ["anyapi_twitter_trends", "tikhub_x_web_fetch_trending"],
|
|
35
|
+
search_x_communities: ["anyapi_twitter_search_communities", "tikhub_x_web_fetch_search_communities"],
|
|
36
|
+
get_x_community_posts: ["anyapi_twitter_community_tweets", "tikhub_x_web_fetch_community_timeline"],
|
|
37
|
+
search_threads: ["anyapi_threads_search", "apify_threads_search", "tikhub_threads_web_search_posts", "tikhub_threads_web_search_top",
|
|
38
|
+
"tikhub_threads_web_search_recent"],
|
|
39
|
+
search_threads_profiles: ["anyapi_threads_search_users", "tikhub_threads_web_search_profiles"],
|
|
40
|
+
fetch_threads_post: ["anyapi_threads_post", "tikhub_threads_web_fetch_post_detail", "tikhub_threads_web_fetch_post_detail_v2",
|
|
41
|
+
"brightdata_threads_posts_collect_by_url"],
|
|
42
|
+
get_bluesky_profile: ["anyapi_bluesky_profile"],
|
|
43
|
+
get_instagram_profile: ["anyapi_instagram_profile", "anyapi_instagram_basic_profile", "tikhub_instagram_v1_fetch_user_info_by_username",
|
|
44
|
+
"tikhub_instagram_v1_fetch_user_info_by_username_v2", "tikhub_instagram_v1_fetch_user_info_by_username_v3",
|
|
45
|
+
"tikhub_instagram_v2_fetch_user_info", "tikhub_instagram_v3_get_user_profile", "apify_instagram_profile",
|
|
46
|
+
"brightdata_instagram_profiles_collect_by_url", "brightdata_instagram_profiles_discover_by_username", "searchapi_instagram_profile", "serpapi_instagram_profile",
|
|
47
|
+
"firecrawl_oriane_instagram_profile_lookup"],
|
|
48
|
+
search_instagram_posts: ["anyapi_instagram_user_posts", "tikhub_instagram_v1_fetch_user_posts", "tikhub_instagram_v1_fetch_user_posts_v2",
|
|
49
|
+
"tikhub_instagram_v2_fetch_user_posts", "tikhub_instagram_v3_get_user_posts", "apify_instagram_posts",
|
|
50
|
+
"brightdata_instagram_posts_discover_by_url"],
|
|
51
|
+
search_instagram_reels: ["anyapi_instagram_user_reels", "tikhub_instagram_v1_fetch_user_reels", "tikhub_instagram_v2_fetch_user_reels",
|
|
52
|
+
"tikhub_instagram_v3_get_user_reels", "apify_instagram_reels", "brightdata_instagram_reels_discover_by_url",
|
|
53
|
+
"brightdata_instagram_reels_discover_by_url_all_reels"],
|
|
54
|
+
search_instagram_by_keyword: ["anyapi_instagram_hashtag_recent_posts", "anyapi_instagram_hashtag_top_posts", "anyapi_instagram_search_hashtag",
|
|
55
|
+
"tikhub_instagram_v1_fetch_hashtag_posts", "tikhub_instagram_v2_fetch_hashtag_posts", "tikhub_instagram_v3_get_hashtag_posts",
|
|
56
|
+
"apify_instagram_hashtags"],
|
|
57
|
+
search_instagram_keyword: ["anyapi_instagram_search", "tikhub_instagram_v1_fetch_search", "tikhub_instagram_v2_search_users",
|
|
58
|
+
"tikhub_instagram_v2_search_hashtags", "tikhub_instagram_v3_search_users", "tikhub_instagram_v3_search_hashtags"],
|
|
59
|
+
search_instagram_phrase: ["tikhub_instagram_v2_general_search", "tikhub_instagram_v3_general_search"],
|
|
60
|
+
search_instagram_places: ["anyapi_instagram_search_locations", "tikhub_instagram_v2_search_locations",
|
|
61
|
+
"tikhub_instagram_v2_search_by_coordinates", "tikhub_instagram_v3_search_by_coordinates"],
|
|
62
|
+
search_instagram_audio: ["anyapi_instagram_audio_reels", "tikhub_instagram_v1_fetch_music_posts", "tikhub_instagram_v2_fetch_music_posts",
|
|
63
|
+
"tikhub_instagram_v3_get_music_posts", "tikhub_instagram_v2_search_music"],
|
|
64
|
+
get_instagram_post_comments: ["anyapi_instagram_post_comments", "tikhub_instagram_v1_fetch_post_comments_v2",
|
|
65
|
+
"tikhub_instagram_v2_fetch_post_comments", "tikhub_instagram_v3_get_post_comments", "brightdata_instagram_comments_collect_by_url",
|
|
66
|
+
"searchapi_instagram_comments"],
|
|
67
|
+
get_instagram_comment_replies: ["anyapi_instagram_comment_replies", "tikhub_instagram_v1_fetch_comment_replies",
|
|
68
|
+
"tikhub_instagram_v2_fetch_comment_replies", "tikhub_instagram_v3_get_comment_replies"],
|
|
69
|
+
get_instagram_stories: ["anyapi_instagram_stories_full", "anyapi_instagram_stories_thin", "tikhub_instagram_v2_fetch_user_stories",
|
|
70
|
+
"tikhub_instagram_v3_get_user_stories"],
|
|
71
|
+
get_instagram_highlights: ["anyapi_instagram_user_highlights", "tikhub_instagram_v2_fetch_user_highlights",
|
|
72
|
+
"tikhub_instagram_v3_get_user_highlights"],
|
|
73
|
+
get_instagram_tagged_posts: ["anyapi_instagram_tagged_posts", "tikhub_instagram_v1_fetch_user_tagged_posts",
|
|
74
|
+
"tikhub_instagram_v2_fetch_user_tagged_posts", "tikhub_instagram_v3_get_user_tagged_posts"],
|
|
75
|
+
get_instagram_former_usernames: ["tikhub_instagram_v3_get_user_former_usernames"],
|
|
76
|
+
get_instagram_account_network: ["anyapi_instagram_followers", "anyapi_instagram_following", "tikhub_instagram_v2_fetch_user_followers",
|
|
77
|
+
"tikhub_instagram_v2_fetch_user_following", "tikhub_instagram_v3_get_user_followers", "tikhub_instagram_v3_get_user_following"],
|
|
78
|
+
get_instagram_reposts: ["anyapi_instagram_user_reposts", "tikhub_instagram_v1_fetch_user_reposts"],
|
|
79
|
+
find_similar_instagram_accounts: ["anyapi_instagram_similar_profiles", "tikhub_instagram_v1_fetch_related_profiles",
|
|
80
|
+
"tikhub_instagram_v2_fetch_similar_users", "tikhub_instagram_v3_get_similar_users"],
|
|
81
|
+
scrape_facebook: ["anyapi_facebook_profile", "brightdata_facebook_pages_and_profiles_collect_by_url", "searchapi_facebook_business_page",
|
|
82
|
+
"serpapi_facebook_profile"],
|
|
83
|
+
scrape_facebook_posts: ["anyapi_facebook_profile_posts", "apify_facebook_posts", "brightdata_facebook_pages_posts_collect_by_url"],
|
|
84
|
+
search_facebook: ["anyapi_facebook_search_pages", "anyapi_facebook_page_lookup", "apify_facebook_search"],
|
|
85
|
+
search_facebook_posts: ["anyapi_facebook_search_posts", "apify_facebook_post_search"],
|
|
86
|
+
search_facebook_people: ["apify_facebook_people_search"],
|
|
87
|
+
fetch_facebook_post: ["anyapi_facebook_post", "brightdata_facebook_posts_collect_by_url"],
|
|
88
|
+
search_tiktok_posts: ["anyapi_tiktok_search_keyword", "anyapi_tiktok_search_top", "anyapi_tiktok_search_hashtag", "anyapi_tiktok_hashtag_videos",
|
|
89
|
+
"anyapi_tiktok_profile_videos", "tikhub_tiktok_app_v3_fetch_video_search_result", "tikhub_tiktok_web_fetch_search_video",
|
|
90
|
+
"tikhub_tiktok_app_v3_fetch_hashtag_video_list", "tikhub_tiktok_web_fetch_tag_post", "tikhub_tiktok_app_v3_fetch_user_post_videos",
|
|
91
|
+
"tikhub_tiktok_app_v3_fetch_user_post_videos_v2", "tikhub_tiktok_app_v3_fetch_user_post_videos_v3", "tikhub_tiktok_web_fetch_user_post",
|
|
92
|
+
"searchapi_tiktok_search", "searchapi_tiktok_profile_videos", "brightdata_tiktok_posts_discover_by_keyword",
|
|
93
|
+
"brightdata_tiktok_posts_discover_by_profile_url", "brightdata_tiktok_posts_by_profile_fast_api_collect_by_url",
|
|
94
|
+
"firecrawl_oriane_tiktok_posts_search", "apify_tiktok_scrape"],
|
|
95
|
+
get_tiktok_profile: ["anyapi_tiktok_profile", "tikhub_tiktok_web_fetch_user_profile", "tikhub_tiktok_app_v3_handler_user_profile",
|
|
96
|
+
"searchapi_tiktok_profile", "brightdata_tiktok_profiles_collect_by_url", "firecrawl_oriane_tiktok_profile_lookup"],
|
|
97
|
+
get_tiktok_comments: ["anyapi_tiktok_video_comments", "tiktok_comments", "tikhub_tiktok_web_fetch_post_comment",
|
|
98
|
+
"tikhub_tiktok_app_v3_fetch_video_comments", "searchapi_tiktok_comments", "brightdata_tiktok_comments_collect_by_url"],
|
|
99
|
+
get_tiktok_comment_replies: ["anyapi_tiktok_comment_replies", "tikhub_tiktok_web_fetch_post_comment_reply",
|
|
100
|
+
"tikhub_tiktok_app_v3_fetch_video_comment_replies"],
|
|
101
|
+
get_tiktok_video_metrics: ["tikhub_tiktok_analytics_fetch_video_metrics", "anyapi_tiktok_video", "tikhub_tiktok_app_v3_fetch_one_video",
|
|
102
|
+
"tikhub_tiktok_app_v3_fetch_one_video_v2", "tikhub_tiktok_app_v3_fetch_one_video_v3", "tikhub_tiktok_web_fetch_post_detail",
|
|
103
|
+
"tikhub_tiktok_web_fetch_post_detail_v2", "searchapi_tiktok_video", "brightdata_tiktok_posts_collect_by_url",
|
|
104
|
+
"firecrawl_oriane_tiktok_video_lookup"],
|
|
105
|
+
get_tiktok_video_transcript: ["anyapi_tiktok_video_transcript", "anyapi_tiktok_video_transcript_full", "searchapi_tiktok_transcripts",
|
|
106
|
+
"apify_tiktok_transcript"],
|
|
107
|
+
get_tiktok_sound_posts: ["anyapi_tiktok_song_videos", "tikhub_tiktok_app_v3_fetch_music_video_list"],
|
|
108
|
+
get_tiktok_sounds: ["tikhub_tiktok_app_v3_fetch_music_search_result", "tikhub_tiktok_app_v3_fetch_music_chart_list"],
|
|
109
|
+
get_tiktok_trends: ["apify_tiktok_trends", "anyapi_tiktok_trending_feed"],
|
|
110
|
+
get_tiktok_trending_hashtags: ["anyapi_tiktok_trending_hashtags", "tikhub_tiktok_ads_get_trends_hashtag_list"],
|
|
111
|
+
get_tiktok_hashtag_trend_detail: ["tikhub_tiktok_ads_get_trends_hashtag_detail"],
|
|
112
|
+
get_tiktok_search_insights: ["tikhub_tiktok_app_v3_fetch_creator_search_insights"],
|
|
113
|
+
get_tiktok_search_insight_detail: ["tikhub_tiktok_app_v3_fetch_creator_search_insights_detail"],
|
|
114
|
+
get_tiktok_comment_themes: ["tikhub_tiktok_analytics_fetch_comment_keywords"],
|
|
115
|
+
get_tiktok_video_article: ["tikhub_tiktok_web_fetch_post_ai_article"],
|
|
116
|
+
check_tiktok_video_authenticity: ["tikhub_tiktok_analytics_detect_fake_views"],
|
|
117
|
+
find_similar_tiktok_accounts: ["tikhub_tiktok_app_v3_fetch_similar_user_recommendations"],
|
|
118
|
+
search_tiktok_creators: ["anyapi_tiktok_search_users", "tikhub_tiktok_app_v3_fetch_user_search_result"],
|
|
119
|
+
get_tiktok_account_region: ["anyapi_tiktok_profile_region"],
|
|
120
|
+
get_tiktok_ad_detail: ["tikhub_tiktok_ads_get_ads_detail"],
|
|
121
|
+
search_tiktok_top_ads: ["anyapi_tiktok_top_ads_search", "tikhub_tiktok_ads_search_ads"],
|
|
122
|
+
search_tiktok_shop_products: ["anyapi_tiktok_shop_search", "tikhub_tiktok_shop_web_fetch_search_products_list",
|
|
123
|
+
"tikhub_tiktok_shop_web_fetch_search_products_list_v2", "brightdata_tiktok_shop_discover_by_keyword"],
|
|
124
|
+
get_tiktok_shop_product: ["anyapi_tiktok_shop_product", "tikhub_tiktok_shop_web_fetch_product_detail",
|
|
125
|
+
"tikhub_tiktok_shop_web_fetch_product_detail_v3"],
|
|
126
|
+
get_tiktok_shop_product_reviews: ["anyapi_tiktok_shop_product_reviews", "tikhub_tiktok_shop_web_fetch_product_reviews_v2"],
|
|
127
|
+
search_youtube: ["dataforseo_serp_youtube_organic_advanced", "anyapi_youtube_search", "tikhub_youtube_web_search_video", "tikhub_youtube_web_v2_get_general_search_v2",
|
|
128
|
+
"brightdata_youtube_videos_discover_by_keyword", "searchapi_youtube", "serpapi_youtube"],
|
|
129
|
+
search_youtube_channels: ["tikhub_youtube_web_search_channel", "tikhub_youtube_web_v2_search_channels",
|
|
130
|
+
"brightdata_youtube_channels_discover_by_keyword"],
|
|
131
|
+
search_youtube_shorts: ["anyapi_youtube_search_shorts", "tikhub_youtube_web_v2_get_shorts_search", "tikhub_youtube_web_v2_get_shorts_search_v2"],
|
|
132
|
+
get_youtube_video_info: ["dataforseo_serp_youtube_video_info_advanced", "anyapi_youtube_video", "tikhub_youtube_web_v2_get_video_info", "tikhub_youtube_web_v2_get_video_info_v2",
|
|
133
|
+
"brightdata_youtube_videos_collect_by_url", "searchapi_youtube_video", "serpapi_youtube_video"],
|
|
134
|
+
get_youtube_comments: ["dataforseo_serp_youtube_video_comments_advanced", "anyapi_youtube_video_comments", "tikhub_youtube_web_v2_get_video_comments", "searchapi_youtube_comments",
|
|
135
|
+
"brightdata_youtube_comments_collect_by_url"],
|
|
136
|
+
get_youtube_comment_replies: ["anyapi_youtube_comment_replies", "tikhub_youtube_web_v2_get_video_comment_replies",
|
|
137
|
+
"tikhub_youtube_web_v2_get_post_comment_replies"],
|
|
138
|
+
get_youtube_channel_about: ["tikhub_youtube_web_v2_get_channel_description", "tikhub_youtube_web_get_channel_info", "anyapi_youtube_channel",
|
|
139
|
+
"searchapi_youtube_channel", "serpapi_youtube_channel"],
|
|
140
|
+
get_youtube_channel_shorts: ["anyapi_youtube_channel_shorts", "tikhub_youtube_web_v2_get_channel_shorts",
|
|
141
|
+
"tikhub_youtube_web_get_channel_short_videos", "searchapi_youtube_channel_shorts"],
|
|
142
|
+
get_youtube_community_posts: ["anyapi_youtube_channel_community_posts", "tikhub_youtube_web_v2_get_channel_community_posts",
|
|
143
|
+
"searchapi_youtube_channel_posts"],
|
|
144
|
+
get_youtube_related_videos: ["tikhub_youtube_web_get_relate_video", "tikhub_youtube_web_v2_get_related_videos"],
|
|
145
|
+
get_youtube_transcript: ["dataforseo_serp_youtube_video_subtitles_advanced", "anyapi_youtube_video_transcript", "anyapi_youtube_video_transcript_full", "searchapi_youtube_transcripts",
|
|
146
|
+
"serpapi_youtube_video_transcript"],
|
|
147
|
+
get_youtube_trends: ["searchapi_youtube_trends"],
|
|
148
|
+
search_reddit: ["anyapi_reddit_search", "tikhub_reddit_app_fetch_dynamic_search", "brightdata_reddit_posts_discover_by_keyword",
|
|
149
|
+
"apify_reddit_scrape"],
|
|
150
|
+
fetch_reddit_post: ["anyapi_reddit_post", "tikhub_reddit_app_fetch_post_details", "brightdata_reddit_posts_collect_by_url"],
|
|
151
|
+
get_reddit_post_comments: ["anyapi_reddit_post_comments", "tikhub_reddit_app_fetch_post_comments", "brightdata_reddit_comments_collect_by_url"],
|
|
152
|
+
get_subreddit_posts: ["anyapi_reddit_subreddit_posts", "tikhub_reddit_app_fetch_subreddit_feed",
|
|
153
|
+
"brightdata_reddit_posts_discover_by_subreddit_url"],
|
|
154
|
+
get_subreddit_info: ["anyapi_reddit_subreddit_details", "tikhub_reddit_app_fetch_subreddit_info"],
|
|
155
|
+
get_reddit_popular_posts: ["tikhub_reddit_app_fetch_popular_feed", "anyapi_reddit_trending_posts"],
|
|
156
|
+
get_reddit_trending_searches: ["tikhub_reddit_app_fetch_trending_searches"],
|
|
157
|
+
get_reddit_user_profile: ["anyapi_reddit_profile", "tikhub_reddit_app_fetch_user_profile", "brightdata_reddit_profiles_1c7f260527ac"],
|
|
158
|
+
get_reddit_user_posts: ["anyapi_reddit_user_posts", "tikhub_reddit_app_fetch_user_posts"],
|
|
159
|
+
get_reddit_user_comments: ["anyapi_reddit_user_comments", "tikhub_reddit_app_fetch_user_comments"],
|
|
160
|
+
fetch_linkedin_post: ["anyapi_linkedin_post", "tikhub_linkedin_web_v2_get_post_detail", "brightdata_linkedin_posts_collect_by_url"],
|
|
161
|
+
get_linkedin_post_comments: ["anyapi_linkedin_post_comments", "tikhub_linkedin_web_v2_get_post_comments"],
|
|
162
|
+
get_linkedin_job_posting: ["anyapi_linkedin_job", "tikhub_linkedin_web_v2_get_job_detail", "searchapi_linkedin_job_details",
|
|
163
|
+
"brightdata_linkedin_jobs_collect_by_url"],
|
|
164
|
+
search_linkedin_job_postings: ["anyapi_linkedin_jobs", "anyapi_linkedin_jobs_thin", "tikhub_linkedin_web_v2_search_jobs",
|
|
165
|
+
"searchapi_linkedin_jobs", "brightdata_linkedin_jobs_discover_by_keyword"],
|
|
166
|
+
get_substack_post: ["firecrawl_substack_com_newsletters_post"],
|
|
167
|
+
list_substack_posts: ["firecrawl_substack_com_newsletters_archive", "anyapi_substack_posts"],
|
|
168
|
+
search_podcasts: ["firecrawl_particle_podcasts_search"],
|
|
169
|
+
search_podcast_episodes: ["firecrawl_particle_podcasts_episodes_search"],
|
|
170
|
+
get_podcast_show: ["firecrawl_particle_podcasts_show", "anyapi_spotify_podcast"],
|
|
171
|
+
get_podcast_episodes: ["firecrawl_particle_podcasts_show_episodes", "anyapi_spotify_podcast_episodes"],
|
|
172
|
+
web_search: ["search_web", "exa_search", "brave_web", "anyapi_brave_search", "crawl4ai_search"],
|
|
173
|
+
search_news: ["dataforseo_serp_google_news_advanced", "dataforseo_serp_google_news_html", "anyapi_google_news", "searchapi_google_news", "searchapi_google_news_light", "searchapi_bing_news", "brave_news",
|
|
174
|
+
"anyapi_hackernews_search", "serpapi_google_news", "serpapi_google_news_light", "serpapi_bing_news", "serpapi_duckduckgo_news", "serpapi_baidu_news"],
|
|
175
|
+
search_image: ["dataforseo_serp_google_images_advanced", "dataforseo_serp_google_images_html", "brave_images", "anyapi_google_images", "searchapi_google_images", "searchapi_google_images_light", "searchapi_bing_images",
|
|
176
|
+
"searchapi_duckduckgo_images", "serpapi_google_images", "serpapi_google_images_light", "serpapi_bing_images", "serpapi_yahoo_images", "serpapi_yandex_images"],
|
|
177
|
+
search_maps: ["dataforseo_serp_google_maps_advanced", "dataforseo_serp_google_local_finder_advanced", "dataforseo_serp_google_local_finder_html",
|
|
178
|
+
"dataforseo_business_business_listings_search", "anyapi_maps_search", "searchapi_google_maps", "firecrawl_firecrawl_maps_businesses_search", "serpapi_google_maps", "serpapi_google_local",
|
|
179
|
+
"serpapi_bing_maps", "serpapi_apple_maps", "serpapi_duckduckgo_maps", "serpapi_naver_maps"],
|
|
180
|
+
search_github: ["searchapi_github_search"],
|
|
181
|
+
serp_lookup: ["dataforseo_serp_google_organic_advanced", "dataforseo_serp_google_organic_regular", "dataforseo_serp_google_organic_html",
|
|
182
|
+
"dataforseo_serp_bing_organic_advanced", "dataforseo_serp_bing_organic_regular", "dataforseo_serp_bing_organic_html",
|
|
183
|
+
"dataforseo_serp_yahoo_organic_advanced", "dataforseo_serp_yahoo_organic_regular", "dataforseo_serp_yahoo_organic_html",
|
|
184
|
+
"dataforseo_serp_baidu_organic_advanced", "dataforseo_serp_baidu_organic_regular", "dataforseo_serp_baidu_organic_html",
|
|
185
|
+
"dataforseo_serp_naver_organic_advanced", "dataforseo_serp_naver_organic_regular", "dataforseo_serp_naver_organic_html",
|
|
186
|
+
"dataforseo_serp_seznam_organic_advanced", "dataforseo_serp_seznam_organic_regular", "dataforseo_serp_seznam_organic_html", "anyapi_google_search", "anyapi_google_search_100", "anyapi_bing_search", "searchapi_google", "searchapi_google_light",
|
|
187
|
+
"searchapi_google_rank_tracking", "searchapi_bing", "searchapi_naver", "serpapi_google", "serpapi_google_light", "serpapi_bing", "serpapi_naver", "crawl4ai_serp"],
|
|
188
|
+
google_ai_mode: ["dataforseo_serp_google_ai_mode_advanced", "dataforseo_serp_google_ai_mode_html", "anyapi_google_ai_mode", "searchapi_google_ai_mode", "serpapi_google_ai_mode"],
|
|
189
|
+
google_ai_overview: ["anyapi_google_ai_overview", "searchapi_google_ai_overview", "serpapi_google_ai_overview"],
|
|
190
|
+
google_trends: ["searchapi_google_trends_trending_now", "firecrawl_firecrawl_trends_trends_trending_now", "serpapi_google_trends_trending_now"],
|
|
191
|
+
google_trends_interest: ["dataforseo_keywords_google_trends_explore", "dataforseo_keywords_dataforseo_trends_explore", "anyapi_google_trends", "searchapi_google_trends", "firecrawl_firecrawl_trends_trends_interest_over_time", "serpapi_google_trends"],
|
|
192
|
+
seo_keyword_metrics: ["dataforseo_labs_google_keyword_overview", "dataforseo_keywords_google_ads_search_volume", "dataforseo_labs_google_bulk_keyword_difficulty"],
|
|
193
|
+
seo_domain_overview: ["dataforseo_labs_google_domain_rank_overview", "dataforseo_labs_google_bulk_traffic_estimation"],
|
|
194
|
+
seo_domain_keywords: ["dataforseo_labs_google_ranked_keywords", "dataforseo_labs_google_keywords_for_site"],
|
|
195
|
+
get_website_traffic: ["anyapi_similarweb_overview", "firecrawl_similarweb_web_traffic"],
|
|
196
|
+
search_meta_ads_library: ["anyapi_facebook_ads_search", "anyapi_facebook_company_ads", "searchapi_meta_ad_library",
|
|
197
|
+
"brightdata_meta_ad_library__fe525218deb2", "apify_facebook_ads"],
|
|
198
|
+
search_meta_ad_library_details: ["anyapi_facebook_ad_details", "anyapi_facebook_ad_details_full", "searchapi_meta_ad_library_ad_details"],
|
|
199
|
+
search_meta_ad_library_pages: ["anyapi_facebook_search_companies", "searchapi_meta_ad_library_page_search"],
|
|
200
|
+
search_google_ads_transparency: ["anyapi_google_ads_company_ads", "anyapi_google_ads_search", "searchapi_google_ads_transparency_center",
|
|
201
|
+
"serpapi_google_ads_transparency_center"],
|
|
202
|
+
search_google_ads_transparency_details: ["anyapi_google_ads_ad_details", "searchapi_google_ads_transparency_center_ad_details",
|
|
203
|
+
"serpapi_google_ads_transparency_center_ad_details"],
|
|
204
|
+
search_linkedin_ads_library: ["anyapi_linkedin_ads_search", "anyapi_linkedin_ad", "searchapi_linkedin_ad_library",
|
|
205
|
+
"searchapi_linkedin_ad_library_ad_details"],
|
|
206
|
+
search_tiktok_ads_library: ["anyapi_tiktok_ad_library_search", "searchapi_tiktok_ads_library"],
|
|
207
|
+
search_tiktok_ads_library_details: ["anyapi_tiktok_ad_library_ad", "searchapi_tiktok_ads_library_ad_details"],
|
|
208
|
+
search_mobile_apps: ["dataforseo_app_data_apple_app_searches_advanced", "dataforseo_app_data_google_app_searches_advanced", "dataforseo_app_data_google_app_searches_html",
|
|
209
|
+
"dataforseo_app_data_apple_app_listings_search", "dataforseo_app_data_google_app_listings_search", "anyapi_appstore_search", "anyapi_playstore_search", "searchapi_apple_app_store", "searchapi_google_play_store",
|
|
210
|
+
"firecrawl_apps_apple_com_apps_search", "firecrawl_play_google_com_media_app_search", "serpapi_apple_app_store", "serpapi_google_play"],
|
|
211
|
+
get_mobile_app: ["dataforseo_app_data_apple_app_info_advanced", "dataforseo_app_data_google_app_info_advanced", "dataforseo_app_data_google_app_info_html", "anyapi_appstore_app", "anyapi_playstore_app", "searchapi_google_play_product", "firecrawl_apps_apple_com_apps_app",
|
|
212
|
+
"firecrawl_play_google_com_media_app", "serpapi_google_play_product", "serpapi_apple_product"],
|
|
213
|
+
get_public_reviews: ["dataforseo_business_google_reviews", "dataforseo_business_google_extended_reviews", "dataforseo_business_trustpilot_reviews",
|
|
214
|
+
"dataforseo_business_tripadvisor_reviews", "anyapi_trustpilot_reviews", "anyapi_g2_reviews", "anyapi_maps_reviews", "brightdata_trustpilot_reviews_collect_by_url",
|
|
215
|
+
"brightdata_g2_reviews_collect_by_url", "brightdata_google_maps_reviews_collect_by_url", "searchapi_google_maps_reviews", "serpapi_google_maps_reviews",
|
|
216
|
+
"firecrawl_firecrawl_maps_businesses_reviews"],
|
|
217
|
+
};
|
|
218
|
+
const additions = {
|
|
219
|
+
scrape_page: ["read_jina_page", "crawl4ai_scrape"],
|
|
220
|
+
get_x_profile: ["scrapecreators_v1_twitter_profile"],
|
|
221
|
+
get_x_community_posts: ["scrapecreators_v1_twitter_community_tweets"],
|
|
222
|
+
search_threads: ["scrapecreators_v1_threads_search"],
|
|
223
|
+
search_threads_profiles: ["scrapecreators_v1_threads_search_users"],
|
|
224
|
+
fetch_threads_post: ["scrapecreators_v1_threads_post"],
|
|
225
|
+
fetch_reddit_post: ["scrapecreators_v1_reddit_post"],
|
|
226
|
+
fetch_facebook_post: ["scrapecreators_v1_facebook_post"],
|
|
227
|
+
fetch_instagram_post: ["scrapecreators_v1_instagram_post"],
|
|
228
|
+
get_instagram_profile: ["scrapecreators_v1_instagram_profile", "scrapecreators_v1_instagram_basic_profile"],
|
|
229
|
+
search_instagram_posts: ["scrapecreators_v2_instagram_user_posts"],
|
|
230
|
+
search_instagram_keyword: ["scrapecreators_v1_instagram_search_profiles"],
|
|
231
|
+
get_instagram_post_comments: ["scrapecreators_v2_instagram_post_comments"],
|
|
232
|
+
get_instagram_highlights: ["scrapecreators_v1_instagram_user_highlights", "scrapecreators_v1_instagram_user_highlight_detail"],
|
|
233
|
+
get_instagram_comment_replies: ["scrapecreators_v1_instagram_post_comment_replies"],
|
|
234
|
+
get_instagram_tagged_posts: ["scrapecreators_v1_instagram_user_tagged_posts"],
|
|
235
|
+
scrape_facebook: ["scrapecreators_v1_facebook_profile"],
|
|
236
|
+
scrape_facebook_posts: ["scrapecreators_v1_facebook_profile_posts"],
|
|
237
|
+
search_tiktok_posts: ["scrapecreators_v1_tiktok_search_keyword", "scrapecreators_v1_tiktok_search_hashtag", "scrapecreators_v3_tiktok_profile_videos"],
|
|
238
|
+
get_tiktok_profile: ["scrapecreators_v1_tiktok_profile"],
|
|
239
|
+
get_tiktok_comments: ["scrapecreators_v1_tiktok_video_comments"],
|
|
240
|
+
get_tiktok_comment_replies: ["scrapecreators_v1_tiktok_video_comment_replies"],
|
|
241
|
+
get_tiktok_sound_posts: ["scrapecreators_v1_tiktok_song_videos"],
|
|
242
|
+
get_tiktok_video_metrics: ["scrapecreators_v2_tiktok_video"],
|
|
243
|
+
get_tiktok_video_transcript: ["scrapecreators_v1_tiktok_video_transcript"],
|
|
244
|
+
search_tiktok_shop_products: ["scrapecreators_v1_tiktok_shop_search"],
|
|
245
|
+
get_tiktok_shop_product_reviews: ["scrapecreators_v1_tiktok_shop_product_reviews"],
|
|
246
|
+
search_tiktok_creators: ["scrapecreators_v1_tiktok_search_users"],
|
|
247
|
+
get_tiktok_account_region: ["scrapecreators_v1_tiktok_profile_region"],
|
|
248
|
+
search_youtube: ["scrapecreators_v1_youtube_search"],
|
|
249
|
+
get_youtube_comments: ["scrapecreators_v1_youtube_video_comments"],
|
|
250
|
+
get_youtube_video_info: ["scrapecreators_v1_youtube_video"],
|
|
251
|
+
get_youtube_community_posts: ["scrapecreators_v1_youtube_channel_community_posts"],
|
|
252
|
+
get_youtube_channel_shorts: ["scrapecreators_v1_youtube_channel_shorts"],
|
|
253
|
+
get_youtube_channel_about: ["scrapecreators_v1_youtube_channel"],
|
|
254
|
+
get_youtube_transcript: ["scrapecreators_v1_youtube_video_transcript"],
|
|
255
|
+
get_youtube_community_post: ["scrapecreators_v1_youtube_community_post"],
|
|
256
|
+
search_reddit: ["scrapecreators_v1_reddit_search"],
|
|
257
|
+
get_subreddit_posts: ["scrapecreators_v1_reddit_subreddit"],
|
|
258
|
+
get_reddit_post_comments: ["scrapecreators_v1_reddit_post_comments", "scrapecreators_v1_reddit_post_comments_post"],
|
|
259
|
+
get_subreddit_info: ["scrapecreators_v1_reddit_subreddit_details"],
|
|
260
|
+
fetch_linkedin_post: ["scrapecreators_v1_linkedin_post"],
|
|
261
|
+
search_meta_ads_library: ["scrapecreators_v1_facebook_ad_library_search_ads", "scrapecreators_v1_facebook_ad_library_search_ads_post",
|
|
262
|
+
"scrapecreators_v1_facebook_ad_library_company_ads", "scrapecreators_v1_facebook_ad_library_company_ads_post"],
|
|
263
|
+
search_google_ads_transparency: ["scrapecreators_v1_google_company_ads"],
|
|
264
|
+
search_google_ads_transparency_details: ["scrapecreators_v1_google_ad"],
|
|
265
|
+
search_linkedin_ads_library: ["scrapecreators_v1_linkedin_ads_search", "scrapecreators_v1_linkedin_ad"],
|
|
266
|
+
search_meta_ad_library_pages: ["scrapecreators_v1_facebook_ad_library_search_companies"],
|
|
267
|
+
search_tiktok_ads_library: ["scrapecreators_v1_tiktok_ad_library_search"],
|
|
268
|
+
};
|
|
269
|
+
export const AUTO_CAPABILITY_VARIANTS = Object.fromEntries(Object.keys({ ...variants, ...additions }).map(name => [name, [...variants[name] ?? [], ...additions[name] ?? []]]));
|
|
@@ -1,20 +1,37 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { TOOL_RESULT_CONTEXT_MAX_BYTES } from "./toolResultContext.js";
|
|
3
|
+
import { platformConnectionPolicySchema } from "./platformConnectionPolicy.js";
|
|
4
|
+
import { platformAppApiPathSchema } from "./platformHttpConstraints.js";
|
|
5
|
+
export { platformOAuthScopeAlternativesSchema, platformOAuthPermissionSchema } from "./platformOAuth.js";
|
|
6
|
+
export const PLATFORM_APP_ID_PATTERN = /^[a-z0-9][a-z0-9_]{0,63}$/;
|
|
7
|
+
export const platformAppIdSchema = z.string().regex(PLATFORM_APP_ID_PATTERN);
|
|
8
|
+
export const platformAppConnectionProviderSchema = z.templateLiteral(["app:", platformAppIdSchema]);
|
|
3
9
|
export const platformConnectionProviderSchema = z.enum(["x", "gsc", "ga", "google", "github", "notion", "slack", "linear", "linkedin", "pinterest", "tiktok", "microsoftAds", "amazonAds"]);
|
|
10
|
+
export const platformAnyConnectionProviderSchema = z.union([platformConnectionProviderSchema, platformAppConnectionProviderSchema]);
|
|
4
11
|
export function platformConnectionOAuthProvider(provider) {
|
|
5
12
|
return provider === "gsc" || provider === "ga" ? "google" : provider === "microsoftAds" ? "microsoft" : provider === "amazonAds" ? "amazon" : provider;
|
|
6
13
|
}
|
|
7
|
-
export const PLATFORM_CONNECTION_CATALOG_LIMITS = { maxRows: 20, responseBytes: 65_536, metadataBytes: 60_000, contextBytes: TOOL_RESULT_CONTEXT_MAX_BYTES };
|
|
14
|
+
export const PLATFORM_CONNECTION_CATALOG_LIMITS = { maxRows: 20, responseBytes: 65_536, metadataBytes: 60_000, policyBytes: 8192, contextBytes: TOOL_RESULT_CONTEXT_MAX_BYTES };
|
|
8
15
|
export const PLATFORM_CONNECTION_PAGE_MAX = PLATFORM_CONNECTION_CATALOG_LIMITS.maxRows;
|
|
9
16
|
export const platformConnectionCatalogQuerySchema = z.object({
|
|
10
|
-
provider:
|
|
17
|
+
provider: platformAnyConnectionProviderSchema.optional(),
|
|
11
18
|
offset: z.number().int().min(0).max(Number.MAX_SAFE_INTEGER).default(0),
|
|
12
19
|
limit: z.number().int().min(1).max(PLATFORM_CONNECTION_PAGE_MAX).default(10),
|
|
13
20
|
}).strict();
|
|
21
|
+
export const platformConnectionAppSchema = z.object({ id: platformAppIdSchema, name: z.string(), docs: z.string(), baseUrl: z.string(),
|
|
22
|
+
baseUrls: z.array(z.string()).optional(),
|
|
23
|
+
apiPaths: z.array(platformAppApiPathSchema).optional(),
|
|
24
|
+
uploadUrls: z.array(z.object({ prefix: z.string(), credentials: z.boolean() })).optional(),
|
|
25
|
+
transport: z.literal("mcp").optional() });
|
|
14
26
|
export const platformConnectionCatalogSchema = z.object({
|
|
15
27
|
connections: z.array(z.object({
|
|
16
|
-
id: z.string(), provider:
|
|
28
|
+
id: z.string(), provider: platformAnyConnectionProviderSchema, label: z.string(),
|
|
17
29
|
status: z.enum(["connected", "reauth_required"]), scopes: z.array(z.string()),
|
|
30
|
+
scopeSyncedAt: z.iso.datetime().nullable().default(null),
|
|
31
|
+
personal: z.boolean().optional(),
|
|
32
|
+
policy: platformConnectionPolicySchema.nullable().optional(),
|
|
33
|
+
policyRestricted: z.boolean().optional(),
|
|
34
|
+
app: platformConnectionAppSchema.optional(),
|
|
18
35
|
})).max(PLATFORM_CONNECTION_PAGE_MAX),
|
|
19
36
|
total: z.number().int().nonnegative(), nextOffset: z.number().int().nonnegative().nullable(),
|
|
20
37
|
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { ACCOUNT_REQUEST_HTTP_METHODS } from "./accountRequestMethods.js";
|
|
3
|
+
export const PLATFORM_CONNECTION_POLICY_LIMITS = { rules: 64, subjects: 100, conditions: 16, pathChars: 2048, pointerChars: 256, valueChars: 2048, jsonChars: 12_000,
|
|
4
|
+
operations: 2_000, operationChars: 128, signInOperationsChars: 32_000 };
|
|
5
|
+
const limits = PLATFORM_CONNECTION_POLICY_LIMITS;
|
|
6
|
+
const ids = z.array(z.string().min(1).max(128)).min(1).max(limits.subjects);
|
|
7
|
+
const condition = z.object({ pointer: z.string().startsWith("/").max(limits.pointerChars),
|
|
8
|
+
operator: z.enum(["equals", "prefix"]).default("equals"), value: z.union([z.string().max(limits.valueChars), z.number().finite(), z.boolean()]) }).strict()
|
|
9
|
+
.refine(value => value.operator !== "prefix" || typeof value.value === "string", "A prefix is a string");
|
|
10
|
+
const common = { effect: z.enum(["allow", "deny"]).default("allow"), memberIds: ids.optional(), apiKeyIds: ids.optional(),
|
|
11
|
+
directoryGroupIds: ids.optional(),
|
|
12
|
+
conditions: z.array(condition).max(limits.conditions).default([]), approvalRequired: z.boolean().default(false) };
|
|
13
|
+
const path = z.string().startsWith("/").max(limits.pathChars).refine(value => !/[?#\\\u0000-\u001f\u007f]/.test(value) && !value.includes("//") && !value.split("/").some(part => part === "." || part === ".."));
|
|
14
|
+
export const platformConnectionPolicyRuleSchema = z.discriminatedUnion("kind", [
|
|
15
|
+
z.object({ ...common, kind: z.literal("http"), methods: z.array(z.enum(ACCOUNT_REQUEST_HTTP_METHODS)).min(1).max(ACCOUNT_REQUEST_HTTP_METHODS.length),
|
|
16
|
+
path, prefix: z.boolean().default(false), baseUrl: z.string().max(limits.pathChars).optional() }).strict(),
|
|
17
|
+
z.object({ ...common, kind: z.literal("mcp"), tool: z.string().min(1).max(256) }).strict(),
|
|
18
|
+
z.object({ ...common, kind: z.literal("database"), operations: z.array(z.enum(["schema", "query", "execute"])).min(1).max(3) }).strict(),
|
|
19
|
+
z.object({ ...common, kind: z.literal("operation"), action: z.string().min(1).max(128) }).strict(),
|
|
20
|
+
]).refine(rule => rule.effect !== "deny" || !rule.approvalRequired, "A refusal cannot be approved");
|
|
21
|
+
export const PLATFORM_CONNECTION_READ_OPERATIONS = "reads";
|
|
22
|
+
const operationNames = z.array(z.string().min(1).max(limits.operationChars)).max(limits.operations);
|
|
23
|
+
export const platformConnectionOperationsSchema = z.object({ allow: operationNames.optional(), deny: operationNames.default([]) }).strict();
|
|
24
|
+
export const platformConnectionPolicySchema = z.object({ version: z.literal(1), defaultEffect: z.enum(["allow", "deny"]).default("deny"),
|
|
25
|
+
rules: z.array(platformConnectionPolicyRuleSchema).max(limits.rules), operations: platformConnectionOperationsSchema.optional() }).strict()
|
|
26
|
+
.refine(value => JSON.stringify({ ...value, operations: undefined }).length <= limits.jsonChars, "Policy is too large");
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { projectScopeSchema, platformJsonObjectSchema, PLATFORM_SANDBOX_LIMITS } from "./platformPublicExecution.js";
|
|
3
|
+
import { PLATFORM_APP_HOST_PATTERN, PLATFORM_APP_RESERVED_HEADERS } from "./platformHttpConstraints.js";
|
|
4
|
+
import { platformTeamSecretNameSchema } from "./platformTeamSecretName.js";
|
|
5
|
+
export const PLATFORM_CUSTOM_TOOL_PREFIX = "custom__";
|
|
6
|
+
export const PLATFORM_CUSTOM_TOOL_LIMITS = {
|
|
7
|
+
perProject: 100,
|
|
8
|
+
versions: 50,
|
|
9
|
+
titleChars: 80,
|
|
10
|
+
descriptionChars: 1_000,
|
|
11
|
+
codeChars: 40_000,
|
|
12
|
+
schemaBytes: 16_384,
|
|
13
|
+
inputBytes: 16_384,
|
|
14
|
+
};
|
|
15
|
+
export const PLATFORM_CUSTOM_ENDPOINT_LIMITS = { bindings: 5, baseUrlChars: 2_048, nameChars: 64, templateChars: 256, secretChars: 4_096 };
|
|
16
|
+
export const platformCustomToolKindSchema = z.enum(["python", "http"]);
|
|
17
|
+
export const platformCustomEndpointLocationSchema = z.enum(["header", "query"]);
|
|
18
|
+
const HEADER_NAME = /^[A-Za-z0-9_-]{1,64}$/;
|
|
19
|
+
const QUERY_NAME = /^[A-Za-z0-9_.$-]{1,64}$/;
|
|
20
|
+
const FORBIDDEN_BINDING_HEADER = /^(?:keep-alive|trailer|proxy-.*|x-forwarded-.*|x-real-ip|set-cookie|accept-encoding|content-type|accept)$/i;
|
|
21
|
+
const CONTROL = /[\u0000-\u001f\u007f]/;
|
|
22
|
+
export const PLATFORM_CUSTOM_ENDPOINT_SECRET_PLACEHOLDER = "{secret}";
|
|
23
|
+
export function isPlatformCustomEndpointBaseUrl(value) {
|
|
24
|
+
try {
|
|
25
|
+
const url = new URL(value);
|
|
26
|
+
return url.protocol === "https:" && !url.username && !url.password && !url.hash && !url.search && !value.includes("?") && !value.includes("#")
|
|
27
|
+
&& PLATFORM_APP_HOST_PATTERN.test(url.host) && !/(?:^|\/)\.{1,2}(?:\/|$)/.test(url.pathname) && !/[\\\s]/.test(value) && !CONTROL.test(value);
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export const platformCustomEndpointBaseUrlSchema = z.string().trim().min(1).max(PLATFORM_CUSTOM_ENDPOINT_LIMITS.baseUrlChars)
|
|
34
|
+
.refine(isPlatformCustomEndpointBaseUrl, "An https URL on a public host name, without credentials, a query or a fragment")
|
|
35
|
+
.describe("The API root, e.g. https://api.example.com or https://api.example.com/v1. Requests go to a path under it.");
|
|
36
|
+
const bindingTemplateSchema = z.string().min(1).max(PLATFORM_CUSTOM_ENDPOINT_LIMITS.templateChars)
|
|
37
|
+
.refine(value => value.includes(PLATFORM_CUSTOM_ENDPOINT_SECRET_PLACEHOLDER) && value.replaceAll(PLATFORM_CUSTOM_ENDPOINT_SECRET_PLACEHOLDER, "").search(/[{}]/) === -1 && !CONTROL.test(value), "The template contains {secret} and no other braces or control characters");
|
|
38
|
+
const bindingNameCheck = (binding) => binding.location === "header"
|
|
39
|
+
? HEADER_NAME.test(binding.name) && !PLATFORM_APP_RESERVED_HEADERS.has(binding.name.toLowerCase()) && !FORBIDDEN_BINDING_HEADER.test(binding.name)
|
|
40
|
+
: QUERY_NAME.test(binding.name);
|
|
41
|
+
const bindingLocation = platformCustomEndpointLocationSchema.describe("header or query: where Relvo puts the credential on every request.");
|
|
42
|
+
const bindingName = z.string().min(1).max(PLATFORM_CUSTOM_ENDPOINT_LIMITS.nameChars).describe("The header or query parameter name, e.g. Authorization or api_key.");
|
|
43
|
+
export const platformCustomEndpointBindingInputSchema = z.object({
|
|
44
|
+
id: z.string().regex(/^[a-z0-9]{8,32}$/).optional().describe("Only when editing: the id of a saved binding whose secret is kept when no new secret is sent."),
|
|
45
|
+
location: bindingLocation,
|
|
46
|
+
name: bindingName,
|
|
47
|
+
template: bindingTemplateSchema.default(PLATFORM_CUSTOM_ENDPOINT_SECRET_PLACEHOLDER).describe("The value sent, with {secret} where the secret goes, e.g. Bearer {secret}."),
|
|
48
|
+
secret: z.string().min(1).max(PLATFORM_CUSTOM_ENDPOINT_LIMITS.secretChars).refine(value => !CONTROL.test(value), "The secret has no control characters").optional()
|
|
49
|
+
.describe("The credential. Required for a new binding without secretRef; sent again only to replace it. Relvo never returns it."),
|
|
50
|
+
secretRef: platformTeamSecretNameSchema.optional().describe("The name of a saved team secret to use instead of an inline secret. Only the console may set it."),
|
|
51
|
+
}).strict().refine(bindingNameCheck, "A valid header or query parameter name that is not reserved")
|
|
52
|
+
.refine(binding => binding.id !== undefined || binding.secret !== undefined || binding.secretRef !== undefined, "A new binding needs its secret")
|
|
53
|
+
.refine(binding => binding.secret === undefined || binding.secretRef === undefined, "A binding takes a secret or a secretRef, not both");
|
|
54
|
+
export const platformCustomEndpointBindingSchema = z.object({ id: z.string(), location: bindingLocation, name: bindingName, template: bindingTemplateSchema,
|
|
55
|
+
maskedSecret: z.string().nullable(), secretRef: platformTeamSecretNameSchema.nullable().default(null) }).strict();
|
|
56
|
+
export const platformCustomEndpointSchema = z.object({ baseUrl: platformCustomEndpointBaseUrlSchema,
|
|
57
|
+
bindings: z.array(platformCustomEndpointBindingSchema).min(1).max(PLATFORM_CUSTOM_ENDPOINT_LIMITS.bindings) }).strict();
|
|
58
|
+
export const platformCustomToolSlugSchema = z.string().regex(/^[a-z][a-z0-9_]{1,39}$/)
|
|
59
|
+
.describe("Lowercase letters, digits and underscores, starting with a letter; the tool is named custom__<slug>.");
|
|
60
|
+
export const PLATFORM_CUSTOM_TOOL_NAME = /^custom__[a-z][a-z0-9_]{1,39}$/;
|
|
61
|
+
export const platformCustomToolNameSchema = z.string().regex(PLATFORM_CUSTOM_TOOL_NAME);
|
|
62
|
+
export const isPlatformCustomToolName = (name) => PLATFORM_CUSTOM_TOOL_NAME.test(name);
|
|
63
|
+
export const platformCustomToolInputSchemaSchema = platformJsonObjectSchema
|
|
64
|
+
.refine(schema => schema.type === "object" && schema.properties !== null && typeof schema.properties === "object" && !Array.isArray(schema.properties), "The input schema is an object schema with properties")
|
|
65
|
+
.refine(schema => new TextEncoder().encode(JSON.stringify(schema)).byteLength <= PLATFORM_CUSTOM_TOOL_LIMITS.schemaBytes, "The input schema is too large");
|
|
66
|
+
export const platformCustomToolDefinitionSchema = z.object({
|
|
67
|
+
kind: z.literal("python").default("python"),
|
|
68
|
+
title: z.string().trim().min(1).max(PLATFORM_CUSTOM_TOOL_LIMITS.titleChars),
|
|
69
|
+
description: z.string().trim().min(1).max(PLATFORM_CUSTOM_TOOL_LIMITS.descriptionChars).describe("What the tool does and returns; agents choose tools by it."),
|
|
70
|
+
inputSchema: platformCustomToolInputSchemaSchema.describe("JSON Schema of the input object, e.g. {\"type\":\"object\",\"properties\":{\"days\":{\"type\":\"integer\"}},\"required\":[\"days\"]}."),
|
|
71
|
+
code: z.string().min(1).max(PLATFORM_CUSTOM_TOOL_LIMITS.codeChars)
|
|
72
|
+
.describe("Python. The validated input is the dict `input`; print the result (JSON is easiest to read back). Files of sourceExecutionIds are listed in /home/user/tool-results/manifest.json. No credentials are present."),
|
|
73
|
+
timeoutMs: z.number().int().min(1000).max(PLATFORM_SANDBOX_LIMITS.timeoutMs).default(30_000),
|
|
74
|
+
enabled: z.boolean().default(true),
|
|
75
|
+
}).strict();
|
|
76
|
+
const uniqueBindings = (bindings) => new Set(bindings.map(binding => `${binding.location}:${binding.name.toLowerCase()}`)).size === bindings.length;
|
|
77
|
+
export const platformCustomEndpointDefinitionSchema = z.object({
|
|
78
|
+
kind: z.literal("http"),
|
|
79
|
+
title: z.string().trim().min(1).max(PLATFORM_CUSTOM_TOOL_LIMITS.titleChars),
|
|
80
|
+
description: z.string().trim().min(1).max(PLATFORM_CUSTOM_TOOL_LIMITS.descriptionChars).describe("What the API is and when to use it; agents choose tools by it."),
|
|
81
|
+
baseUrl: platformCustomEndpointBaseUrlSchema,
|
|
82
|
+
bindings: z.array(platformCustomEndpointBindingInputSchema).min(1).max(PLATFORM_CUSTOM_ENDPOINT_LIMITS.bindings).refine(uniqueBindings, "Each header or query parameter is bound once")
|
|
83
|
+
.describe("Credentials Relvo adds to every request, in the header or query parameter named. Agents never see them."),
|
|
84
|
+
enabled: z.boolean().default(true),
|
|
85
|
+
}).strict();
|
|
86
|
+
const slugged = { slug: platformCustomToolSlugSchema };
|
|
87
|
+
const versioned = { expectedVersion: z.number().int().min(1) };
|
|
88
|
+
export const platformCustomToolCreateSchema = z.union([platformCustomToolDefinitionSchema.extend(slugged).strict(), platformCustomEndpointDefinitionSchema.extend(slugged).strict()]);
|
|
89
|
+
export const platformCustomToolUpdateSchema = z.union([platformCustomToolDefinitionSchema.extend(versioned).strict(), platformCustomEndpointDefinitionSchema.extend(versioned).strict()]);
|
|
90
|
+
export const platformCustomToolRestoreSchema = z.object({ version: z.number().int().min(1), expectedVersion: z.number().int().min(1) }).strict();
|
|
91
|
+
export const platformCustomToolSchema = z.object({
|
|
92
|
+
kind: platformCustomToolKindSchema.default("python"), endpoint: platformCustomEndpointSchema.nullable().default(null),
|
|
93
|
+
name: platformCustomToolNameSchema, slug: platformCustomToolSlugSchema, title: z.string(), description: z.string(), inputSchema: platformJsonObjectSchema,
|
|
94
|
+
code: z.string(), timeoutMs: z.number().int(), enabled: z.boolean(), version: z.number().int().min(1), createdAt: z.string(), updatedAt: z.string(),
|
|
95
|
+
});
|
|
96
|
+
export const platformCustomToolSummarySchema = platformCustomToolSchema.omit({ code: true, inputSchema: true });
|
|
97
|
+
export const platformCustomToolVersionSchema = z.object({ version: z.number().int().min(1), title: z.string(), createdAt: z.string() });
|
|
98
|
+
export const platformVersionAuthorSchema = z.object({ email: z.string().nullable(), apiKey: z.string().nullable() }).strict();
|
|
99
|
+
export const platformCustomToolHistorySchema = platformCustomToolVersionSchema.extend({ author: platformVersionAuthorSchema });
|
|
100
|
+
export const platformCustomToolVersionDetailSchema = platformCustomToolSchema.pick({ kind: true, endpoint: true, title: true, description: true, inputSchema: true, code: true, timeoutMs: true, enabled: true })
|
|
101
|
+
.extend({ version: z.number().int().min(1), createdAt: z.string(), author: platformVersionAuthorSchema });
|
|
102
|
+
const toolInput = projectScopeSchema.extend({ name: platformCustomToolNameSchema });
|
|
103
|
+
const toolResult = z.object({ tool: platformCustomToolSchema }).strict();
|
|
104
|
+
export const platformCustomToolContracts = {
|
|
105
|
+
listDeveloperCustomTools: { input: projectScopeSchema.strict(), output: z.object({ tools: z.array(platformCustomToolSummarySchema) }).strict() },
|
|
106
|
+
getDeveloperCustomTool: { input: toolInput.strict(), output: toolResult },
|
|
107
|
+
createDeveloperCustomTool: { input: projectScopeSchema.extend({ tool: platformCustomToolCreateSchema }).strict(), output: toolResult },
|
|
108
|
+
updateDeveloperCustomTool: { input: toolInput.extend({ tool: platformCustomToolUpdateSchema }).strict(), output: toolResult },
|
|
109
|
+
restoreDeveloperCustomTool: { input: toolInput.merge(platformCustomToolRestoreSchema).strict(), output: toolResult },
|
|
110
|
+
deleteDeveloperCustomTool: { input: toolInput.strict(), output: z.object({ success: z.literal(true) }).strict() },
|
|
111
|
+
listDeveloperCustomToolVersions: { input: toolInput.strict(), output: z.object({ versions: z.array(platformCustomToolHistorySchema) }).strict() },
|
|
112
|
+
getDeveloperCustomToolVersion: { input: toolInput.extend({ version: z.number().int().min(1) }).strict(), output: z.object({ version: platformCustomToolVersionDetailSchema }).strict() },
|
|
113
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { PLATFORM_CHECKOUT_MIN_CENTS } from "./platformBillingConstants.js";
|
|
3
|
+
const micros = z.string().regex(/^\d{1,20}$/);
|
|
4
|
+
export const platformFundingShortfallSchema = z.object({
|
|
5
|
+
reason: z.enum(["balance", "organization_monthly_limit", "project_monthly_limit", "organization_daily_limit", "api_key_daily_limit"]),
|
|
6
|
+
requiredMicros: micros,
|
|
7
|
+
availableMicros: micros,
|
|
8
|
+
});
|
|
9
|
+
export const PLATFORM_WALLET_TOP_UP_MIN_CENTS = PLATFORM_CHECKOUT_MIN_CENTS;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { ACCOUNT_REQUEST_HTTP_METHODS } from "./accountRequestMethods.js";
|
|
3
|
+
export const PLATFORM_APP_HOST_PATTERN = /^(?=[^:]{4,253}(?::|$))(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z][a-z0-9-]{0,61}[a-z0-9](?::[1-9][0-9]{0,4})?$/;
|
|
4
|
+
export const PLATFORM_APP_RESERVED_HEADERS = new Set(["host", "cookie", "content-length", "transfer-encoding", "connection", "proxy-authorization", "forwarded", "te", "upgrade", "expect"]);
|
|
5
|
+
export const platformAppApiPathSchema = z.object({ baseUrl: z.number().int().min(0).max(8), method: z.enum(ACCOUNT_REQUEST_HTTP_METHODS),
|
|
6
|
+
path: z.string().startsWith("/").max(2048).refine(path => !/[?#\\\s\u0000-\u001f]/.test(path) && !path.includes("//")
|
|
7
|
+
&& path.split("/").every(segment => segment !== "." && segment !== ".." && (!/[{}]/.test(segment) || /^\{[A-Za-z_][A-Za-z0-9_]*\}$/.test(segment)))) }).strict();
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export const PLATFORM_MCP_DIRECT_TOOLS_MAX = 20;
|
|
2
|
+
export function platformMcpDirectToolNames(list) {
|
|
3
|
+
const names = [...new Set((list ?? "").split(",").map(name => name.trim()).filter(Boolean))];
|
|
4
|
+
if (names.length > PLATFORM_MCP_DIRECT_TOOLS_MAX || names.some(name => !/^[a-z][a-z0-9_]{1,63}$/u.test(name)))
|
|
5
|
+
throw new Error(`Name at most ${PLATFORM_MCP_DIRECT_TOOLS_MAX} catalog tools, separated by commas.`);
|
|
6
|
+
return names;
|
|
7
|
+
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { platformCatalogSchema, platformCreateExecutionSchema, platformExecutionIdSchema, platformExecutionStatusSchema, platformMicrosSchema, platformQuoteSchema, platformToolNameSchema, platformToolSessionIdSchema, platformOptionalToolSessionIdSchema, PLATFORM_SANDBOX_LIMITS, platformExecutionSchema, platformExecutionContextSchema, platformRequestIntentSchema } from "./platformPublicExecution.js";
|
|
3
|
-
import {
|
|
2
|
+
import { platformCatalogSchema, platformCreateExecutionSchema, platformExecutionIdSchema, platformExecutionStatusSchema, platformMicrosSchema, platformQuoteSchema, platformToolNameSchema, platformToolSessionIdSchema, platformOptionalToolSessionIdSchema, PLATFORM_SANDBOX_LIMITS, platformExecutionSchema, platformExecutionContextSchema, platformRequestIntentSchema, validatePlatformArgumentIdentifiers } from "./platformPublicExecution.js";
|
|
3
|
+
import { platformAnyConnectionProviderSchema, platformConnectionCatalogSchema } from "./platformConnectionCatalog.js";
|
|
4
4
|
import { toolDiscoveryInputSchema, toolDiscoveryResultSchema } from "./toolDiscovery.js";
|
|
5
|
+
export { PLATFORM_MCP_DIRECT_TOOLS_MAX, platformMcpDirectToolNames } from "./platformMcpTools.js";
|
|
5
6
|
export const PLATFORM_META_LIMITS = { queries: 4, schemas: 12, batch: 50, concurrency: 4, contextBytes: 24_000,
|
|
6
7
|
requestBytes: 1_048_576, requestTimeoutMs: 90_000, sessionLifetimeMs: 86_400_000, activeSessions: 100,
|
|
7
8
|
codeChars: PLATFORM_SANDBOX_LIMITS.code, commandChars: 16_000, sourceExecutions: PLATFORM_SANDBOX_LIMITS.sourceExecutions, timeoutMs: PLATFORM_SANDBOX_LIMITS.timeoutMs };
|
|
@@ -21,15 +22,16 @@ export const platformMetaSchemasSchema = z.object({ ...sessionInput,
|
|
|
21
22
|
export const platformMetaSchemasResultSchema = z.object({ session: platformToolSessionSchema,
|
|
22
23
|
tools: platformCatalogSchema.shape.tools, remaining: z.array(platformToolNameSchema) });
|
|
23
24
|
export const platformMetaConnectionsSchema = z.object({ ...sessionInput,
|
|
24
|
-
providers: z.array(
|
|
25
|
-
.describe("OAuth providers
|
|
25
|
+
providers: z.array(platformAnyConnectionProviderSchema).max(32).default([])
|
|
26
|
+
.describe("Providers to inspect: OAuth providers or connected apps as app:<id> (e.g. app:airtable). Empty means every connection. Data-provider API keys are managed by Relvo.") }).strict();
|
|
26
27
|
export const platformMetaConnectionsResultSchema = z.object({ session: platformToolSessionSchema,
|
|
27
28
|
developerOrganizationId: z.string(), developerProjectId: z.string(),
|
|
28
29
|
manageUrl: z.url(), connections: platformConnectionCatalogSchema.shape.connections,
|
|
29
|
-
total: z.number().int().nonnegative(), providers: z.array(z.object({ provider:
|
|
30
|
+
total: z.number().int().nonnegative(), providers: z.array(z.object({ provider: platformAnyConnectionProviderSchema,
|
|
30
31
|
status: z.enum(["connected", "reauth_required", "not_connected"]) })),
|
|
31
32
|
instruction: z.string() });
|
|
32
|
-
const item = platformCreateExecutionSchema.omit({ sessionId: true }).extend({ idempotencyKey: z.string().regex(/^[A-Za-z0-9._:-]{8,128}$/) }).strict()
|
|
33
|
+
const item = z.object(platformCreateExecutionSchema.shape).omit({ sessionId: true }).extend({ idempotencyKey: z.string().regex(/^[A-Za-z0-9._:-]{8,128}$/) }).strict()
|
|
34
|
+
.superRefine((value, context) => validatePlatformArgumentIdentifiers(value.tool, value.arguments, context));
|
|
33
35
|
export const platformMetaExecuteSchema = z.object({ ...sessionInput,
|
|
34
36
|
maximumChargeMicros: platformMicrosSchema.describe("Accepted total reservation ceiling across this batch, in addition to each accepted quote."),
|
|
35
37
|
tools: z.array(item).min(1).max(PLATFORM_META_LIMITS.batch)
|