hermoso 0.1.520 → 0.1.522

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 +11 -5
  2. package/package.json +1 -1
package/mcp/tools.mjs CHANGED
@@ -18645,13 +18645,16 @@ function buildTools(rawServer, opts = {}, sink = null) {
18645
18645
  inputSchema: {
18646
18646
  advertiserId: z.string().optional().describe('from list_tiktok_ads_accounts — TikTok scopes these lookups to an advertiser'),
18647
18647
  kind: z.enum(['location', 'interest', 'interest_keyword', 'hashtag', 'language']).optional().describe('default location. interest_keyword and hashtag both REQUIRE keyword.'),
18648
- keyword: z.string().optional().describe('narrows the lookup, e.g. "Canada", "Beauty", "skincare"'),
18648
+ keyword: z.string().optional().describe('narrows the lookup by name, e.g. "Canada" returns Canada rather than every place TikTok has; REQUIRED for interest_keyword and hashtag'),
18649
+ regionCode: z.string().optional().describe('location only: two-letter country code, e.g. CA, to list the places inside one country'),
18650
+ level: z.enum(['country', 'province', 'city', 'district']).optional().describe('location only: return one level'),
18651
+ limit: z.number().optional().describe('rows to return, default 50, max 200; total always counts every match'),
18649
18652
  },
18650
- outputSchema: { advertiserId: z.string().optional(), kind: z.string().optional(), results: z.array(z.any()).optional() },
18653
+ outputSchema: { advertiserId: z.string().optional(), kind: z.string().optional(), results: z.array(z.any()).optional(), total: z.number().optional(), returned: z.number().optional(), truncated: z.boolean().optional(), note: z.string().optional() },
18651
18654
  annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: true },
18652
18655
  }, wrap(async (a) => {
18653
18656
  const d = await apiGet('/api/tiktok-ads/targeting', a);
18654
- return ok(`${(d.results || []).length} TikTok ${d.kind || a.kind || 'location'} result(s) on advertiser ${d.advertiserId}:\n${JSON.stringify((d.results || []).slice(0, 30))}`, d);
18657
+ return ok(`${d.note || `${(d.results || []).length} TikTok ${d.kind || a.kind || 'location'} result(s).`} Advertiser ${d.advertiserId}:\n${JSON.stringify(d.results || [])}`, d);
18655
18658
  }));
18656
18659
  server.registerTool('tiktok_ads_report', {
18657
18660
  title: 'TikTok ads performance report',
@@ -19302,7 +19305,7 @@ function buildTools(rawServer, opts = {}, sink = null) {
19302
19305
  registeredArea: z.string().optional().describe('two-letter country of registration, e.g. US'),
19303
19306
  timezone: z.string().optional().describe('IANA time zone, e.g. America/New_York'),
19304
19307
  currency: z.string().optional().describe('must match the Business Center currency; defaults to it'),
19305
- promotionLink: z.string().optional().describe('company website; required for an agency Business Center'),
19308
+ promotionLink: z.string().optional().describe('company website; required for an agency Business Center. Pass the brand site when you have it: Hermoso sends it only where TikTok takes it and the reply says when it was not sent'),
19306
19309
  contactName: z.string().optional(), contactEmail: z.string().optional(), contactPhone: z.string().optional(),
19307
19310
  billingAddress: z.string().optional().describe('required for France, Brazil and Mexico'),
19308
19311
  taxId: z.string().optional().describe('VAT, tax id or ABN depending on the country'),
@@ -26036,7 +26039,10 @@ function memoryNoteVerdict(text) {
26036
26039
  // `pp`). Ungated, a SERVICE or APP brand acquired a "product library" from its own og:image — and brandContext
26037
26040
  // would then print "SERVICE BUSINESS — there is NO physical product. NEVER invent a box, bottle, package…"
26038
26041
  // directly above a populated photo library, while assembleAdRender attached that image to every render.
26039
- if (p && p.domain && p.physical_product !== false) {
26042
+ // A CREATOR'S SITE IS READ FOR PHOTOS ONLY WHEN THE DRAFT NAMED A PRODUCT (journey QA 2026-11-05, @cookingwithlynja): the
26043
+ // photo review is paid, and a handle draft's domain is usually a link-in-bio page. Same rule as the web (brandSellsProduct).
26044
+ const _creatorNoProduct = !!a.socialHandle && !(Array.isArray(p?.productNames) && p.productNames.some((x) => typeof x === 'string' && x.trim()));
26045
+ if (p && p.domain && p.physical_product !== false && !_creatorNoProduct) {
26040
26046
  try {
26041
26047
  const site = await apiGet('/api/site/images', { url: p.domain });
26042
26048
  const imgs = [...(site?.images || [])].filter(Boolean);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hermoso",
3
- "version": "0.1.520",
3
+ "version": "0.1.522",
4
4
  "mcpName": "io.github.hermoso-ai/hermoso",
5
5
  "description": "AI marketing agent and AI ad generator, run from your own AI agent. 1177 tools. No markup on models on Starter and up. Publishing, scheduling, ad campaign management, comments, DMs and analytics cost no credits on any plan; Free includes 10 posts a month and every paid plan posts without a limit. AD PLATFORMS: Meta, Google Ads, TikTok Ads, LinkedIn Ads, Reddit Ads, X Ads, Pinterest Ads, Snapchat Ads, Microsoft Advertising, Apple Search Ads, ChatGPT Ads and AppLovin Ads, plus product feeds in Google Merchant Center. PUBLISHING AND SCHEDULING: Facebook, Instagram, Threads, TikTok, YouTube, X, LinkedIn, Pinterest, Bluesky, Telegram, WordPress, Discord, Slack, Whop and Google Business Profile. INSTAGRAM DM AUTOMATIONS: a keyword comment, a DM, a story reply or an ig.me link gets an automatic private reply from the brand. 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",