hermoso 0.1.392 → 0.1.393
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/mcp/tools.mjs +17 -9
- package/package.json +1 -1
package/mcp/tools.mjs
CHANGED
|
@@ -3325,6 +3325,12 @@ function buildTools(rawServer, opts = {}, sink = null) {
|
|
|
3325
3325
|
// what a video SAYS: analyze_video returns the verbatim transcript (voiceover + on-screen text). 2026-10-04 dead end: "readtranscript".
|
|
3326
3326
|
transcript: ['transcript', 'analyze', 'video'], transcribe: ['transcript', 'analyze', 'video'], transcrib: ['transcript', 'analyze', 'video'], transcription: ['transcript', 'analyze', 'video'],
|
|
3327
3327
|
caption: ['caption', 'subtitles', 'analyze'], word: ['transcript', 'analyze'], spoken: ['analyze', 'voice'], verbatim: ['analyze'],
|
|
3328
|
+
// AUTOPILOT AND AUTOMATIONS IN THE USER'S WORDS (2026-10-06): "autopilot" found NOTHING and "post 2 times a day",
|
|
3329
|
+
// "pause autopilot", "when someone comments GUIDE send them a dm" all missed the tools, because autopilot's tools are
|
|
3330
|
+
// named after the "post refill" and nobody says that. A rule-shaped ask ("when someone…", "anyone who…") is an automation.
|
|
3331
|
+
autopilot: ['refill', 'post'], autopost: ['refill', 'post'], autoposting: ['refill', 'post'], autopublish: ['refill'], frequency: ['refill'], times: ['refill', 'schedule'], daily: ['refill', 'schedule'], cadence: ['refill', 'schedule'],
|
|
3332
|
+
draft: ['refill', 'draft'], approve: ['refill', 'approve'], automatic: ['automation', 'refill'], automatically: ['automation', 'refill'], auto: ['automation', 'refill'],
|
|
3333
|
+
automation: ['automation'], automate: ['automation', 'refill'], manychat: ['automation', 'dm'], someone: ['automation'], anyone: ['automation'], whenever: ['automation'],
|
|
3328
3334
|
});
|
|
3329
3335
|
const stemWord = (w) => {
|
|
3330
3336
|
if (w.length <= 3) return w;
|
|
@@ -5708,8 +5714,8 @@ function buildTools(rawServer, opts = {}, sink = null) {
|
|
|
5708
5714
|
// list_scheduled shows and cancel_scheduled cancels. It ALWAYS makes new content within the user's render budget and
|
|
5709
5715
|
// never re-posts the Library; in 'review' mode each batch waits as drafts until approved.
|
|
5710
5716
|
server.registerTool('get_post_refill', {
|
|
5711
|
-
title: '
|
|
5712
|
-
description: 'Show autoposting
|
|
5717
|
+
title: 'Autopilot posting status',
|
|
5718
|
+
description: 'Show AUTOPILOT POSTING (autoposting, the posting refill) for this profile — "is autopilot on?", "what is waiting for review?": whether it is on, its mode (review = each batch of fresh posts waits as drafts for approval; auto = fresh posts are scheduled straight away), WHICH CHANNELS it posts to with each one’s posts per day and posting times, roughly what it costs a day, when it next runs, how many posts are queued, the DRAFTS waiting for approval (id, time, channels, caption, the new image or video), and the notes it learned from reviews. It also names the channels that CANNOT be posted to and why. Read-only, free.',
|
|
5713
5719
|
inputSchema: {},
|
|
5714
5720
|
outputSchema: {
|
|
5715
5721
|
enabled: z.boolean().optional(), mode: z.string().optional(), daysAhead: z.number().optional(),
|
|
@@ -5737,13 +5743,15 @@ function buildTools(rawServer, opts = {}, sink = null) {
|
|
|
5737
5743
|
].filter(Boolean).join('\n'), d);
|
|
5738
5744
|
}));
|
|
5739
5745
|
server.registerTool('set_post_refill', {
|
|
5740
|
-
title: '
|
|
5741
|
-
description: 'Turn autoposting
|
|
5746
|
+
title: 'Set up, change or pause autopilot posting',
|
|
5747
|
+
description: 'Turn AUTOPILOT POSTING (autoposting, the posting refill) on, change it or pause it: "post 2 times a day on Instagram and Bluesky about …, let me review first", "make it 1 a day", "switch to auto-publish", "pause autopilot". PASS ONLY WHAT CHANGES. It always makes NEW posts (a fresh image, carousel or video for each) and never re-posts the Library. WHERE: every connected channel by default (channels narrows it); HOW OFTEN: the brand’s posting times, and channelPostsPerDay sets fewer on a channel (e.g. {"x":1}). There are no credit limits to set — get_post_refill shows roughly what it costs a day. Switching it on is refused when no channel is connected or nothing a day would be made. SWITCHING IT ON ASKS THE BRIEF ONCE: a goal (followers / sales / launch / other) is required; content pillars (get_post_refill suggests some from the brand), formats (mix / video / carousel / image) and an avoid list are optional. Posts are written from the brief, the brand profile, what has worked on each channel (compared only within a channel), the brand’s skills and playbooks and the ads it saved. Ask the user for anything missing (goal, mode, channels) rather than guessing. `mode` picks what happens to each batch: "review" (the default) keeps the fresh posts as drafts until a human approves them (run_post_refill approve), "auto" schedules them straight away. `enabled:false` is the PAUSE — it removes the recurring job outright, and posts already queued are left alone (cancel those with cancel_scheduled). Three posting times means up to three posts a day; postsPerDay sets fewer, and to post MORE per day pass postingTimes (one time per post a day) — e.g. "2 a day" on a brand with 3 posting times is postsPerDay:2, "4 a day" needs four postingTimes.',
|
|
5742
5748
|
inputSchema: {
|
|
5743
5749
|
enabled: z.boolean().optional().describe('on/off. true needs a connected channel and a goal (refused otherwise). false PAUSES it: the recurring job is deleted and nothing new is made. Already-queued posts are untouched.'),
|
|
5744
5750
|
mode: z.enum(['review', 'auto']).optional().describe('"review" (default): each batch of fresh posts waits as drafts for approval. "auto": fresh posts are scheduled to publish automatically.'),
|
|
5745
5751
|
daysAhead: z.number().optional().describe('how far ahead to keep the queue full, 1–30 (default 7)'),
|
|
5746
|
-
postsPerDay: z.number().optional().describe('
|
|
5752
|
+
postsPerDay: z.number().optional().describe('posts a day, up to the number of posting times ("2 times a day" = 2). 0 (default) = one per posting time. To post MORE per day than there are posting times, also pass postingTimes.'),
|
|
5753
|
+
postingTimes: z.array(z.string()).optional().describe('the brand\'s daily posting times, 24-hour "HH:MM" (e.g. ["09:00","13:00","18:00"]); REPLACES the list. Autopilot makes one post per posting time, and scheduled posts use the same times. get_post_refill shows the current ones.'),
|
|
5754
|
+
timezone: z.string().optional().describe('IANA timezone the posting times are in, e.g. "America/New_York" (default: the brand\'s, else UTC)'),
|
|
5747
5755
|
channelPostsPerDay: z.record(z.number()).optional().describe('per channel, how many posts a day (the first N of the posting times), e.g. {"x":1,"instagram":3}. 0 turns a channel off; null resets it to every posting time. Merged into what is saved.'),
|
|
5748
5756
|
goal: z.enum(['followers', 'sales', 'launch', 'other']).optional().describe('THE BRIEF: what the posts are for — grow followers, drive sales, promote a launch, or other (say what in goalNote). Required to switch it on.'),
|
|
5749
5757
|
goalNote: z.string().optional().describe('THE BRIEF: a line about the goal (e.g. the launch date and what is launching).'),
|
|
@@ -5766,11 +5774,11 @@ function buildTools(rawServer, opts = {}, sink = null) {
|
|
|
5766
5774
|
const d = await apiPut('/api/schedule/refill', { ...rest, ...(Object.keys(brief).length ? { brief } : {}) });
|
|
5767
5775
|
return ok((d.enabled
|
|
5768
5776
|
? `Autoposting is ON in ${d.mode === 'auto' ? 'AUTO-PUBLISH mode — each run makes fresh posts and schedules them to go out on their own.' : 'REVIEW mode — each run makes fresh posts and keeps them as drafts; nothing is scheduled until you approve them with run_post_refill.'} get_post_refill lists the channels it posts to and what it costs a day. Run run_post_refill (a preview by default: it renders and queues nothing, and writing its copy costs a few credits) to see a plan.`
|
|
5769
|
-
: 'Autoposting is OFF. The recurring job is gone and nothing new will be made. Posts already in the calendar are untouched — cancel those with cancel_scheduled if you want them gone.') + (d.creditNote ? `\n${d.creditNote}` : ''), d);
|
|
5777
|
+
: 'Autoposting is OFF. The recurring job is gone and nothing new will be made. Posts already in the calendar are untouched — cancel those with cancel_scheduled if you want them gone.') + (Array.isArray(d.postingTimes) ? `\nPosting times are now ${d.postingTimes.join(', ')} (${d.timezone || 'UTC'}).` : '') + (d.creditNote ? `\n${d.creditNote}` : ''), d);
|
|
5770
5778
|
}));
|
|
5771
5779
|
server.registerTool('run_post_refill', {
|
|
5772
|
-
title: 'Run
|
|
5773
|
-
description: 'Run autoposting NOW instead of waiting for its daily turn, or
|
|
5780
|
+
title: 'Run autopilot now / approve its drafts',
|
|
5781
|
+
description: 'Run AUTOPILOT POSTING (autoposting) NOW instead of waiting for its daily turn, or REVIEW the drafts it made — "approve them all", "delete that one", "change the caption", "too salesy, remember that". PREVIEW BY DEFAULT: it returns the posts it WOULD make — each new picture’s scene, the caption, the channels and the price — rendering nothing and queueing nothing. The preview still WRITES the scenes and copy with a model, which bills a few credits (the reply says how many). dryRun:false actually renders a fresh image or video for each post within the budget (credits are spent) and then, by mode, schedules them ("auto") or keeps them as drafts ("review"). It never re-posts the Library. REVIEWING A BATCH: pass approve (draft ids, or ["all"]) to schedule drafts, discard to delete them, edit ([{id, message?, captions?, title?, at?, channels?}]) to change one first (a new `at` reschedules it); get_post_refill lists them. learn saves notes future batches follow (free). redo remakes ONE draft from a note: PAID, so without confirm:true it returns only the price; confirm only on the user’s yes. A scheduled post can still be pulled before it goes out with cancel_scheduled. Every caption is screened against the voice rules and a failing one is dropped, so a plan can come back shorter than the cadence — the reason is in the notes.',
|
|
5774
5782
|
inputSchema: {
|
|
5775
5783
|
dryRun: z.boolean().optional().describe('default TRUE (a preview: nothing rendered, nothing queued; the copy it writes bills a few credits). false renders fresh creative and schedules or drafts it per the mode.'),
|
|
5776
5784
|
force: z.boolean().optional().describe('plan a preview even while autoposting is switched off — useful for showing someone what it would do before they turn it on.'),
|
|
@@ -7944,7 +7952,7 @@ function buildTools(rawServer, opts = {}, sink = null) {
|
|
|
7944
7952
|
}));
|
|
7945
7953
|
server.registerTool('save_dm_automation', {
|
|
7946
7954
|
title: 'Create or edit a DM automation (Instagram, Facebook, X)',
|
|
7947
|
-
description: 'Create (no id) or edit (id) a ManyChat-style automation. Instagram/Facebook: a keyword comment (one post, the next post, any post; on Facebook also ads) gets a private reply in DMs/Messenger, a DM keyword or ig.me/m.me ref link gets a message, with optional link buttons and rotated public replies. X: a keyword @mention or a reply under your post gets a public reply, a DM keyword gets a DM (X allows an automated DM only after the person DMed you). Once per person per post; a DM saying STOP opts that person out. Instagram and Facebook are free; X is billed in credits for every mention, reply or DM X delivers to the account plus each reply or DM sent, and running out stops the X rules. It messages real people, so confirm the text first.',
|
|
7955
|
+
description: 'Create (no id) or edit (id) a ManyChat-style AUTO-DM / AUTO-REPLY automation: "when someone comments GUIDE on my posts, DM them my guide link", "reply to anyone who DMs PRICE with our pricing page", "reply to people who mention us on X". PAUSE one with {id, enabled:false}; PRACTICE MODE (dryRun:true) logs what it would send and sends nothing. Instagram/Facebook: a keyword comment (one post, the next post, any post; on Facebook also ads) gets a private reply in DMs/Messenger, a DM keyword or ig.me/m.me ref link gets a message, with optional link buttons and rotated public replies. X: a keyword @mention or a reply under your post gets a public reply, a DM keyword gets a DM (X allows an automated DM only after the person DMed you). Once per person per post; a DM saying STOP opts that person out. Instagram and Facebook are free; X is billed in credits for every mention, reply or DM X delivers to the account plus each reply or DM sent, and running out stops the X rules. It messages real people, so confirm the text first.',
|
|
7948
7956
|
inputSchema: { id: z.string().optional(), ...dmaAnyShape },
|
|
7949
7957
|
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
7950
7958
|
}, wrap(async (a) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hermoso",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.393",
|
|
4
4
|
"mcpName": "io.github.hermoso-ai/hermoso",
|
|
5
5
|
"description": "Marketing on autopilot, run from your own AI agent. 906 tools. Publishing, scheduling, ad campaign management, comments, DMs and analytics cost no credits on every plan; credits are only for generating creative and for Ad Spy research. 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 and Telegram. 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",
|