hermoso 0.1.162 → 0.1.163

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 +12 -3
  2. package/package.json +1 -1
package/mcp/tools.mjs CHANGED
@@ -355,7 +355,16 @@ const wrap = (fn) => {
355
355
  // connector not connected → hand the human a ONE-CLICK connect link (OAuth needs a browser, so it can't happen
356
356
  // in-agent) — Dave 2026-07-23. Detected from the STRUCTURED signal, never from the prose (see notConnectedHint).
357
357
  else msg += notConnectedHint(e, msg);
358
- return { content: [{ type: 'text', text: msg }], isError: true };
358
+ // ── THE STRUCTURED ERROR MARKER (2026-08-26) ──────────────────────────────────────────────────────────
359
+ // `msg` above is a SENTENCE, built for a model to read. `/v1/tools` — the REST passthrough — has to answer
360
+ // the same failure with an HTTP status and the v1 error envelope, and deriving one from prose is exactly
361
+ // the over-match that made every Meta not-found read as a permission problem, four separate times. So the
362
+ // two facts this codebase already treats as structured truth ride out beside the sentence: `err.status`
363
+ // and `err.connector`, the ONE not-connected shape. Nothing is parsed anywhere.
364
+ // `_meta` is MCP's own sanctioned extension point (spec: any result MAY carry it), so every MCP client
365
+ // sees an ordinary error result and ignores a key it does not recognise. `publishWrap` spreads the result,
366
+ // so its ambiguous-publish advice keeps the marker rather than dropping it.
367
+ return { content: [{ type: 'text', text: msg }], isError: true, _meta: { 'hermoso.ai/error': { status: Number(e?.status) || 0, connector: e?.connector ? String(e.connector) : '' } } };
359
368
  }
360
369
  };
361
370
  return outer;
@@ -454,7 +463,7 @@ const geoLine = (r) => {
454
463
  // always measured against the live catalog, never against this number. It deliberately stays at the length the
455
464
  // ORDINARY models render (15s) even though the catalog now carries a 30s single-take model: raising it to 30
456
465
  // would mean a 20s ask skips the probe entirely, and on an account where that model is not configured (no
457
- // FAL_KEY) the ask would sail through to a model that cannot render it. Low = one extra free round trip on a
466
+ // a render-provider key) the ask would sail through to a model that cannot render it. Low = one extra free round trip on a
458
467
  // long ask. High = a silently-truncated render. So it stays low, and the live catalog stays the authority.
459
468
  // AD_LENGTH_MAX — the longest STITCHED spot the planner can build: 12 acts (KEYFRAME_CAP) × 15s.
460
469
  const VIDEO_SINGLE_CLIP_CEILING = 15;
@@ -15662,7 +15671,7 @@ function buildTools(rawServer, opts = {}, sink = null) {
15662
15671
  },
15663
15672
  outputSchema: {
15664
15673
  candidates: z.array(z.any()).optional().describe('discovered brands ({name, domain, kind, reason})'),
15665
- diagnostics: z.any().optional().describe('discovery diagnostics (LLM tokens, web grounding)'),
15674
+ diagnostics: z.any().optional().describe('discovery diagnostics (model usage, web grounding)'),
15666
15675
  },
15667
15676
  annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: true },
15668
15677
  }, wrap(async ({ domain, mode = 'competitors' }) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hermoso",
3
- "version": "0.1.162",
3
+ "version": "0.1.163",
4
4
  "mcpName": "io.github.hermoso-ai/hermoso",
5
5
  "description": "AI ad studio and marketing MCP server with 718 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",