hermoso 0.1.201 → 0.1.202

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.
Files changed (2) hide show
  1. package/mcp/tools.mjs +7 -6
  2. package/package.json +1 -1
package/mcp/tools.mjs CHANGED
@@ -4141,6 +4141,7 @@ function buildTools(rawServer, opts = {}, sink = null) {
4141
4141
  locationId: z.string().optional().describe("GOOGLE BUSINESS PROFILE — which listing, e.g. 'locations/123' from list_business_locations. Needed when the account manages more than one storefront; it is never chosen for the user."),
4142
4142
  visibility: z.enum(['public', 'unlisted', 'private', 'draft']).optional().describe("how it should be published — DEFAULT 'public' (live). Only pass something else if the user explicitly asked to stage/hide it. Not every channel supports every value; an impossible combination is refused when you schedule it, with the reason."),
4143
4143
  visibilityByChannel: z.record(z.string()).optional().describe('override visibility for one channel, e.g. { "tiktok": "draft" } to go live everywhere but stage TikTok for review'),
4144
+ optimizeCopy: z.boolean().optional().describe('RECOMMENDED when one caption goes to several channels: fit the shared caption to each channel’s own rules at publish time wherever no per-channel caption was written — YouTube gets a keyword title, a structured multi-paragraph description and search tags; Instagram/TikTok hashtags; LinkedIn longer; X/Bluesky short; Pinterest keyword-rich. The angle and every claim stay the author’s; a channel with its own caption is left exactly as written. Off by default so nobody’s words are rewritten unasked.'),
4144
4145
  },
4145
4146
  outputSchema: { id: z.string().optional(), at: z.string().optional(), channels: z.array(z.string()).optional(), label: z.string().optional() },
4146
4147
  annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
@@ -5082,8 +5083,8 @@ function buildTools(rawServer, opts = {}, sink = null) {
5082
5083
  account: z.string().optional().describe("WHICH connected account of this channel to post as — its @handle or id from list_connector_accounts. Needed only when the brand has more than one youtube account connected (several and none named is refused by name, never guessed); omit when there is one."),
5083
5084
  ...HOOK_ATTR,
5084
5085
  videoUrl: z.string().describe('the video to post — a Hermoso render URL or an upload_file url'),
5085
- title: z.string().optional().describe('video title (≤100 chars)'),
5086
- description: z.string().optional().describe('video description (≤5000 chars)'),
5086
+ title: z.string().optional().describe('REQUIRED in practice — the headline every search result and the Shorts feed shows (≤100 chars); an upload with no title is refused'),
5087
+ description: z.string().optional().describe('REQUIRED in practice — what the video shows, a line about the brand, a link and a few #hashtags (≤5000 chars); YouTube search, suggested videos and the Shorts feed rank on it, so an upload with no description (and no caption) is refused'),
5087
5088
  tags: z.array(z.string()).optional().describe('up to 30 tags'),
5088
5089
  privacy: z.enum(['private', 'unlisted', 'public']).optional().describe('default unlisted (anyone-with-link, ad-ready); public = live + searchable on the channel (confirm first); private = eyes-only (cannot run as an ad)'),
5089
5090
  categoryId: z.string().optional().describe('YouTube category id, NUMERIC — default "22" (People & Blogs), which is wrong for most ads. 1 Film & Animation · 2 Autos & Vehicles · 10 Music · 15 Pets & Animals · 17 Sports · 19 Travel & Events · 20 Gaming · 22 People & Blogs · 23 Comedy · 24 Entertainment · 25 News & Politics · 26 Howto & Style · 27 Education · 28 Science & Technology · 29 Nonprofits & Activism. The assignable set is region-specific, so the value is forwarded as given and YouTube has the last word.'),
@@ -11267,7 +11268,7 @@ function buildTools(rawServer, opts = {}, sink = null) {
11267
11268
  budget: z.number().describe('budget in the ad account’s currency (not micro-currency — the conversion is handled)'),
11268
11269
  objective: z.enum(['APP_INSTALLS', 'CATALOG_SALES', 'CLICKS', 'CONVERSIONS', 'IMPRESSIONS', 'LEAD_GENERATION', 'VIDEO_VIEWABLE_IMPRESSIONS']).optional().describe('default CLICKS'),
11269
11270
  goalType: z.enum(['DAILY_SPEND', 'LIFETIME_SPEND']).optional(),
11270
- bidType: z.enum(['CPC', 'CPM', 'CPV', 'CPV6']).optional(),
11271
+ bidType: z.enum(['CPC', 'CPM', 'CPV', 'CPV6', 'CPV15']).optional(),
11271
11272
  bidStrategy: z.enum(['BIDLESS', 'MANUAL_BIDDING', 'MAXIMIZE_VOLUME', 'TARGET_CPX']).optional(),
11272
11273
  bidAmount: z.number().optional(),
11273
11274
  startTime: z.string().optional().describe('ISO 8601'),
@@ -11287,7 +11288,7 @@ function buildTools(rawServer, opts = {}, sink = null) {
11287
11288
  adAccountId: z.string().optional(),
11288
11289
  budget: z.number().describe('budget in the ad account’s currency'),
11289
11290
  objective: z.enum(['APP_INSTALLS', 'CATALOG_SALES', 'CLICKS', 'CONVERSIONS', 'IMPRESSIONS', 'LEAD_GENERATION', 'VIDEO_VIEWABLE_IMPRESSIONS']).optional().describe('default CLICKS'),
11290
- bidType: z.enum(['CPC', 'CPM', 'CPV', 'CPV6']).optional().describe('default CPC — must fit the campaign objective'),
11291
+ bidType: z.enum(['CPC', 'CPM', 'CPV', 'CPV6', 'CPV15']).optional().describe('default CPC — must fit the campaign objective'),
11291
11292
  bidStrategy: z.enum(['BIDLESS', 'MANUAL_BIDDING', 'MAXIMIZE_VOLUME', 'TARGET_CPX']).optional(),
11292
11293
  goalType: z.enum(['DAILY_SPEND', 'LIFETIME_SPEND']).optional(),
11293
11294
  startTime: z.string().optional(),
@@ -11380,7 +11381,7 @@ function buildTools(rawServer, opts = {}, sink = null) {
11380
11381
  name: z.string(),
11381
11382
  budget: z.number().describe('budget in the ad account’s currency, paired with goalType'),
11382
11383
  goalType: z.enum(['DAILY_SPEND', 'LIFETIME_SPEND']).optional().describe('default DAILY_SPEND'),
11383
- bidType: z.enum(['CPC', 'CPM', 'CPV', 'CPV6']).describe('must fit the campaign objective — CLICKS campaigns take CPC'),
11384
+ bidType: z.enum(['CPC', 'CPM', 'CPV', 'CPV6', 'CPV15']).describe('must fit the campaign objective — CLICKS campaigns take CPC'),
11384
11385
  bidStrategy: z.enum(['BIDLESS', 'MANUAL_BIDDING', 'MAXIMIZE_VOLUME', 'TARGET_CPX']).describe('MANUAL_BIDDING needs bidAmount'),
11385
11386
  bidAmount: z.number().optional().describe('bid in the ad account’s currency — required for paid bid types; ask reddit_ads_bid_suggestion'),
11386
11387
  startTime: z.string().describe('ISO 8601, e.g. 2026-08-15T00:00:00Z — Reddit rejects the create without one'),
@@ -11432,7 +11433,7 @@ function buildTools(rawServer, opts = {}, sink = null) {
11432
11433
  budget: z.number().optional(),
11433
11434
  goalType: z.enum(['DAILY_SPEND', 'LIFETIME_SPEND']).optional(),
11434
11435
  bidAmount: z.number().optional(),
11435
- bidType: z.enum(['CPC', 'CPM', 'CPV', 'CPV6']).optional(),
11436
+ bidType: z.enum(['CPC', 'CPM', 'CPV', 'CPV6', 'CPV15']).optional(),
11436
11437
  bidStrategy: z.enum(['BIDLESS', 'MANUAL_BIDDING', 'MAXIMIZE_VOLUME', 'TARGET_CPX']).optional(),
11437
11438
  startTime: z.string().optional(),
11438
11439
  endTime: z.string().optional(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hermoso",
3
- "version": "0.1.201",
3
+ "version": "0.1.202",
4
4
  "mcpName": "io.github.hermoso-ai/hermoso",
5
5
  "description": "AI ad studio and marketing MCP server with 781 tools. Research the ads already running in any market, generate finished image, video and UGC avatar ads, publish and schedule them to your own channels, build and manage the ad campaigns behind them, and read what they achieved. AD PLATFORMS: Meta, Google Ads, TikTok Ads, LinkedIn Ads, Reddit Ads, X Ads, Pinterest Ads, Snapchat Ads, Microsoft Advertising, Apple Search Ads and ChatGPT Ads, plus product feeds in Google Merchant Center. PUBLISHING AND SCHEDULING: Facebook, Instagram, Threads, TikTok, YouTube, X, LinkedIn, Pinterest, Bluesky and Telegram. AD RESEARCH: the Meta, Google and LinkedIn ad libraries plus organic TikTok, Instagram, YouTube, Threads and Reddit. ANALYTICS: Google Analytics 4, Google Search Console and every connected platform's own post and campaign insights. Also brand onboarding, 50+ image and video generation models, ad scoring, competitor teardowns, Google Drive and OneDrive, a CLI and installable Claude skills.",
6
6
  "type": "module",