@rolino/mcp 0.9.0 → 0.10.0

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/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # @rolino/mcp
2
2
 
3
+ ## 0.10.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 601eda2: Add Bluesky account and media policy discovery, confirmed future local schedule cancellation, and hosted MCP media upload preparation and verification. Keep OAuth approval with the account owner and reject cancellation when delivery may have started.
8
+
9
+ Add image alt text, confirmed untouched draft deletion, and confirmed Bluesky account disconnection with independent optional permissions. Preserve original media and prevent late token refresh from restoring disconnected authorization.
10
+
11
+ - support for multiple social accounts under one brand
12
+
13
+ ### Patch Changes
14
+
15
+ - Updated dependencies [601eda2]
16
+ - Updated dependencies
17
+ - @rolino/contracts@0.10.0
18
+ - @rolino/sdk@0.10.0
19
+ - @rolino/local-auth@0.10.0
20
+
3
21
  ## 0.9.0
4
22
 
5
23
  ### Minor Changes
package/README.md CHANGED
@@ -1,262 +1,279 @@
1
- # `@rolino/mcp`
2
-
3
- Rolino's Model Context Protocol adapter. Rolino supports hosted Streamable HTTP
4
- with client-owned OAuth and local STDIO with the shared CLI OAuth session. The
5
- hosted route is stateless and does not need this package on the caller's
6
- computer. This package supplies the local STDIO process and the shared MCP tool
7
- definitions used by both transports.
8
-
9
- ## Installation
10
-
11
- Local STDIO MCP remains a separate, explicit installation so CLI-only and
12
- remote users do not receive MCP runtime dependencies:
13
-
14
- ```bash
15
- npm install --global @rolino/cli @rolino/mcp
16
- ```
17
-
18
- For hosted Streamable HTTP, run `rolino setup mcp --client codex --transport
19
- http`, then `codex mcp login rolino`. For local STDIO, the CLI handles standard
20
- OAuth Authorization Code with PKCE and writes token-free Codex or Claude Code
21
- configuration that points to this package's installed entry point.
22
- Headless operators may install only `@rolino/mcp` and provide a scoped
23
- `ROLINO_TOKEN` explicitly.
24
-
25
- Initial tools:
26
-
27
- - `whoami`
28
- - `list_projects`
29
- - `get_project`
30
- - `create_project`
31
- - `list_media_assets`
32
- - `get_storage_usage`
33
- - `preview_media_cleanup`
34
- - `execute_media_cleanup`
35
- - `get_media_cleanup_status`
36
- - `upload_media_asset`
37
- - `list_posts`
38
- - `get_post`
39
- - `create_draft_post`
40
- - `update_draft_post`
41
- - `get_post_readiness`
42
- - `preview_post_schedule`
43
- - `execute_post_schedule`
44
- - `preview_post_publish`
45
- - `execute_post_publish`
46
- - `list_integration_health`
47
- - `refresh_delivery_options`
48
- - `list_seo_opportunities`
49
- - `get_seo_opportunity`
50
- - `list_seo_reports`
51
- - `get_seo_report`
52
- - `start_backlink_discovery`
53
- - `get_backlink_discovery`
54
- - `list_backlink_prospects`
55
- - `get_backlink_prospect`
56
- - `research_backlink_contact`
57
- - `update_backlink_stage`
58
- - `update_backlink_outreach`
59
- - `list_backlink_contacts`
60
- - `verify_backlink`
61
- - `list_calendar_events`
62
-
63
- Backlink tools use independent opt-in scopes. Provider-calling tools are bounded and open-world. Stored reads are closed-world. No tool accepts an arbitrary search query or a user-supplied email. Rolino never sends email.
64
-
65
- The media tools discover reusable project assets and stream one explicitly
66
- approved local JPEG, PNG, WebP, MP4, or MOV file directly to configured
67
- storage. Rolino derives dimensions and video duration from the stored object.
68
- Uploading never creates, schedules, or publishes a post; the returned
69
- asset ID is passed into a later draft operation.
70
-
71
- `get_storage_usage` and `list_media_assets` are bounded closed-world reads.
72
- Cleanup requires the separate `media:delete` permission. Preview creates an
73
- exact confirmation but deletes nothing. Before execute, show the upload-age
74
- cutoff, candidate count, excluded in-use count, unknown-size count, and estimated
75
- space. A general request to free space is not execute approval. Execute queues
76
- only the unchanged confirmed files with an idempotency key. In-use files are
77
- never detached, and queued bytes remain counted until physical deletion succeeds.
78
- The deletion worker skips a file without contacting storage if its confirmed
79
- workspace, project, asset, storage identity, or version changed.
80
-
81
- The tool set includes discovery and inspection tools that are read-only.
82
- The four SEO tools require the exact optional `seo:read` capability. They are
83
- bounded, read-only, idempotent, and closed-world. They return canonical tasks,
84
- evidence, neutral provenance, separate topic-relevance and action-readiness
85
- confidence, and recommended actions. They cannot
86
- run analysis, change settings, delete data, enable reports, send email, or call
87
- an external provider.
88
- Opportunity detail also returns the bounded versioned task: exact decision,
89
- format, target, deliverables, research, safe URLs, evidence, limitations, and
90
- success metric. Ready can request final deliverables for human review. Research
91
- selects only `RESEARCH_TASK`, compares all reasonable formats without a
92
- preferred final format, and must return `VALIDATED` with a complete next task
93
- or `REJECTED` with evidence before any separately allowed draft
94
- action. Every copied task forbids publishing and other Rolino writes.
95
- `create_project` is an additive, closed-world mutation that requires
96
- `projects:write` and a caller-supplied idempotency key. It atomically saves the
97
- project and its paired brand without starting research, connecting accounts,
98
- scheduling posts, or publishing. The two draft tools can create or selectively
99
- update draft content but cannot schedule or publish it. Omitted update fields
100
- preserve current media, destinations, captions, and provider settings. Both require caller-supplied
101
- idempotency keys, and updates also require the version returned by `get_post`
102
- so stale writes fail safely. Every tool returns output-schema-validated
103
- `structuredContent` plus a JSON text fallback.
104
- YouTube drafts require exactly one stored video, explicit title/category/
105
- visibility/audience/declaration settings, and optional tags. The YOUTUBE caption
106
- override becomes the video description, with the shared caption as fallback.
107
- Unaudited Google API projects may be restricted to Private uploads; the tools
108
- do not infer audit approval from server configuration.
109
- Bluesky drafts can be text-only or contain up to four stored JPEG, PNG, or WebP
110
- images. The BLUESKY caption override accepts up to 300 graphemes, with the
111
- shared caption as fallback.
112
- Before preparing TikTok settings, call `refresh_delivery_options`. It contacts
113
- TikTok and returns secret-safe account choices: allowed delivery modes, exact
114
- visibility values, interaction availability, and maximum video duration.
115
- Direct drafts must make every declaration explicit and mark the choices
116
- reviewed only after inspecting this result. That review is distinct from MCP
117
- mutation consent. Changing TikTok content clears the prior review, and Rolino
118
- never silently turns off a requested interaction.
119
- For LinkedIn, `refresh_delivery_options` returns the connected member plus the
120
- strict text/single-image/multi-image/video policy and JPEG/PNG/MP4 limits.
121
- LinkedIn drafts can be text-only, contain up to ten stored images, or contain
122
- exactly one stored MP4 without mixing images and video. Native video must be
123
- 75 KB to 500 MB and 3 seconds to 30 minutes, and execution remains in
124
- preparation until LinkedIn confirms upload and processing. An optional
125
- 3,000-character LINKEDIN caption override uses the shared caption as fallback.
126
- The connected member is always the author; Company Page publishing is outside
127
- this contract.
128
- Google Business Profile drafts can be text-only or contain one stored JPEG or
129
- PNG image with a stable public URL. The optional 1,500-character
130
- GOOGLE_BUSINESS_PROFILE update override uses the shared caption as fallback.
131
- The tools use the location selected in Rolino, create only standard updates,
132
- and never choose or change a Business Profile location. If final creation has
133
- an unknown outcome, inspect the selected Business Profile before retrying.
134
- Integration health is cached and secret-safe, post
135
- readiness reuses Rolino's publishing checks, and calendar reads use bounded
136
- date windows with cursor pagination. After `rolino auth login`, configure `ROLINO_URL` and
137
- the server automatically obtains and refreshes the API-resource OAuth token saved for
138
- that exact host. `ROLINO_TOKEN` remains an explicit override for CI and other
139
- headless environments. `ROLINO_CONFIG_DIR` can override the portable credential
140
- directory, and `ROLINO_TIMEOUT` is optional. Stdout is reserved for MCP
141
- messages; startup failures go to stderr without secrets or stack traces.
142
- `ROLINO_TIMEOUT` accepts integer milliseconds or values such as `500ms`, `15s`,
143
- and `1m`, matching the CLI.
144
-
145
- Scheduling uses two separate tools. `preview_post_schedule` contacts the
146
- configured providers, validates the exact post version, time, timezone, and
147
- readiness, and returns a five-minute single-use confirmation without scheduling
148
- anything. `execute_post_schedule` is marked consequential and open-world; it
149
- requires the unchanged preview values, confirmation token, and a stable
150
- idempotency key. The server repeats readiness and live-health checks and rejects
151
- expired, consumed, stale, cross-credential, or mismatched confirmation.
152
- For YouTube, the preview explains that confirmed scheduling starts or resumes a
153
- private upload immediately so processing can complete before the Public target.
154
- Execution may return a typed `PENDING` result with phase
155
- `REMOTE_SCHEDULE_CONFIRMATION` after the upload completes while YouTube
156
- acknowledges the requested publish time. The video remains private, the result
157
- does not report it as published, and no second publish tool call is required.
158
-
159
- Immediate publishing also uses two tools. `preview_post_publish` checks the
160
- exact destination set, post version, readiness, live provider health, and retry
161
- safety without contacting a publish endpoint. `execute_post_publish` requires
162
- the unchanged preview values, confirmation token, and stable idempotency key,
163
- then durably queues the selected destinations for immediate delivery. Provider
164
- calls happen after that database commit, and Rolino's existing reconciliation
165
- rules block blind retries after ambiguous external results. YouTube remains
166
- `PREPARING` until upload and processing are provider-confirmed, and its exact
167
- configured Public, Unlisted, or Private visibility is reconciled before
168
- publication is reported. The preview reports `deliveryMode: "IMMEDIATE"` and
169
- `createsSchedule: false`; immediate publishing never enters schedule
170
- confirmation.
171
-
172
- MCP tools cannot enable YouTube, Bluesky, LinkedIn, or Google Business Profile,
173
- or bypass a deployment's provider approval boundary. Self-hosted operators
174
- should complete the
175
- [YouTube operations guide](https://github.com/deifos/rolino/blob/main/docs/integrations/youtube.md)
176
- and
177
- [Bluesky operations guide](https://github.com/deifos/rolino/blob/main/docs/integrations/bluesky.md),
178
- [LinkedIn operations guide](https://github.com/deifos/rolino/blob/main/docs/integrations/linkedin.md)
179
- and the
180
- [Google Business Profile operations guide](https://github.com/deifos/rolino/blob/main/docs/integrations/google-business-profile.md)
181
- before live testing.
182
-
183
- ## Support, security, and license
184
-
185
- Stable releases are published only after the maintainer approves the release
186
- gate. Report bugs through the
187
- [Rolino issue tracker](https://github.com/deifos/rolino/issues) and security
188
- issues through the repository's
189
- [security policy](https://github.com/deifos/rolino/security/policy).
190
-
191
- `@rolino/mcp` is available under the MIT License.
192
- ## Agent-first Blog Studio tools
193
-
194
- The local stdio server exposes Blog readiness, import, cadence planning,
195
- plan-item evidence and state, editable article creation, connection status,
196
- confirmed provisioning, signed revalidation testing, and these provider-neutral
197
- publishing reads:
198
-
199
- - `list_blog_publishing_providers` requires `blog:manage` and returns only
200
- enabled providers, safe capabilities, and official documentation.
201
- - `list_blog_publishing_destinations` requires `blog:read` and returns safe
202
- connection readiness without credentials or private provider data.
203
- - `list_blog_delivery_attempts` requires `blog:read`, accepts an optional exact
204
- article ID, and returns safe delivery states, retry times, error codes, and
205
- remote URLs.
206
- - `generate_blog_image`, `upload_blog_image`, and `review_blog_image` require
207
- `blog:write`. They cannot approve an article or publish it. Upload reads only
208
- the exact local JPEG, PNG, or WebP path supplied to the tool.
209
- - `preview_blog_plan_cadence` and `apply_blog_plan_cadence` require
210
- `blog:write`. Preview first, show every editorial move and locked item, then
211
- apply only the unchanged preview values with its confirmation and a stable
212
- idempotency key.
213
- - These cadence tools never change `scheduledPublishAt` and never schedule,
214
- publish, or unpublish an article.
215
- - `generate_blog_image` already accepts optional editorial direction through
216
- `editorialBrief` with a 500-character limit.
217
- - `preview_blog_revision_approval` and `execute_blog_revision_approval` require
218
- the independent `blog:approve` capability. Execution makes the confirmed
219
- exact bundle eligible for a separate publication operation; it cannot
220
- publish.
221
- - `preview_blog_schedule`, `execute_blog_schedule`,
222
- `preview_blog_schedule_cancellation`, and
223
- `execute_blog_schedule_cancellation` require the independent `blog:publish`
224
- capability. Scheduling causes future external publication but does not grant
225
- approval. Cancellation removes only the confirmed future schedule and never
226
- unpublishes a live article.
227
-
228
- The three publishing-read tools are closed-world reads. They do not contact a provider or
229
- change content. They do not return draft content, prompts, evidence, secrets,
230
- or raw provider responses. Setup requires the
231
- independent optional `blog:manage` capability; it is never inferred from
232
- `blog:write` or `blog:publish` and is not added to existing credentials.
233
-
234
- Read tools are closed-world. The signed revalidation test is accurately marked
235
- as an open-world write. Connection execute is confirmed, destructive, and
236
- idempotent; its first success may return one-time values that must be written
237
- only to server-side environment configuration. Errors and replays never reveal
238
- those values. These tools remain available over local stdio. The remote profile
239
- omits both caller-local media and Blog image uploads, and the hosted route stays hidden while its
240
- deployment gate is off. Publication still requires a user-approved exact revision and the
241
- separate publish preview/execute tools.
242
-
243
- Use the Blog tools in this order: read setup and current article or plan state;
244
- ask for a missing website, cadence, destination, or access level; import and
245
- plan through polled durable jobs; present evidence before bounded plan
246
- acceptance; create one immutable revision with catalog-backed links; generate
247
- or upload and review one image with alt text; stop for user approval when
248
- `blog:approve` is missing; otherwise preview and execute exact-bundle approval
249
- with its confirmation token and a stable idempotency key; stop after approval
250
- when `blog:publish` is missing; otherwise preview and execute unchanged
251
- publication or scheduling; poll delivery and verify the live URL; and restart
252
- from approval preview after any content or image change. Existing credentials
253
- do not gain `blog:approve`, and a queued delivery is not published.
254
-
255
-
256
- ## Existing delivery recovery
257
-
258
- `check_post_delivery` reads an existing upload and updates Rolino. It requires `posts:write` and does not publish. `UNKNOWN` requires manual review.
259
-
260
- `preview_post_recovery` verifies an existing YouTube video and returns the account, consequence, and a short-lived confirmation. After the user approves it, `execute_post_recovery` accepts identical action, video ID, publication time, post version, and token with a stable idempotency key. `ATTACH` cannot publish; `RESUME` requires an explicit future `publishAt` or `null` for publication now, plus `posts:schedule` or `posts:publish`. `QUEUED` is pending, not published. All recovery tools are marked as writes because they change local records. No recovery tool uploads another copy.
261
-
262
- The same tools are available through packaged and hosted MCP. Upgrade the server and packaged client before using them.
1
+ # `@rolino/mcp`
2
+
3
+ Rolino's Model Context Protocol adapter. Rolino supports hosted Streamable HTTP
4
+ with client-owned OAuth and local STDIO with the shared CLI OAuth session. The
5
+ hosted route is stateless and does not need this package on the caller's
6
+ computer. This package supplies the local STDIO process and the shared MCP tool
7
+ definitions used by both transports.
8
+
9
+ ## Installation
10
+
11
+ Local STDIO MCP remains a separate, explicit installation so CLI-only and
12
+ remote users do not receive MCP runtime dependencies:
13
+
14
+ ```bash
15
+ npm install --global @rolino/cli @rolino/mcp
16
+ ```
17
+
18
+ For hosted Streamable HTTP, run `rolino setup mcp --client codex --transport
19
+ http`, then `codex mcp login rolino`. For local STDIO, the CLI handles standard
20
+ OAuth Authorization Code with PKCE and writes token-free Codex or Claude Code
21
+ configuration that points to this package's installed entry point.
22
+ Headless operators may install only `@rolino/mcp` and provide a scoped
23
+ `ROLINO_TOKEN` explicitly.
24
+
25
+ Initial tools:
26
+
27
+ - `whoami`
28
+ - `list_projects`
29
+ - `get_project`
30
+ - `create_project`
31
+ - `list_media_assets`
32
+ - `get_storage_usage`
33
+ - `preview_media_cleanup`
34
+ - `execute_media_cleanup`
35
+ - `get_media_cleanup_status`
36
+ - `upload_media_asset`
37
+ - `list_posts`
38
+ - `get_post`
39
+ - `create_draft_post`
40
+ - `update_draft_post`
41
+ - `get_post_readiness`
42
+ - `preview_post_schedule`
43
+ - `execute_post_schedule`
44
+ - `preview_post_publish`
45
+ - `execute_post_publish`
46
+ - `list_integration_health`
47
+ - `refresh_delivery_options`
48
+ - `list_seo_opportunities`
49
+ - `get_seo_opportunity`
50
+ - `list_seo_reports`
51
+ - `get_seo_report`
52
+ - `start_backlink_discovery`
53
+ - `get_backlink_discovery`
54
+ - `list_backlink_prospects`
55
+ - `get_backlink_prospect`
56
+ - `research_backlink_contact`
57
+ - `update_backlink_stage`
58
+ - `update_backlink_outreach`
59
+ - `list_backlink_contacts`
60
+ - `verify_backlink`
61
+ - `list_calendar_events`
62
+
63
+ Backlink tools use independent opt-in scopes. Provider-calling tools are bounded and open-world. Stored reads are closed-world. No tool accepts an arbitrary search query or a user-supplied email. Rolino never sends email.
64
+
65
+ The media tools discover reusable project assets and stream one explicitly
66
+ approved local JPEG, PNG, WebP, MP4, or MOV file directly to configured
67
+ storage. Rolino derives dimensions and video duration from the stored object.
68
+ Uploading never creates, schedules, or publishes a post; the returned
69
+ asset ID is passed into a later draft operation.
70
+
71
+ `get_storage_usage` and `list_media_assets` are bounded closed-world reads.
72
+ Cleanup requires the separate `media:delete` permission. Preview creates an
73
+ exact confirmation but deletes nothing. Before execute, show the upload-age
74
+ cutoff, candidate count, excluded in-use count, unknown-size count, and estimated
75
+ space. A general request to free space is not execute approval. Execute queues
76
+ only the unchanged confirmed files with an idempotency key. In-use files are
77
+ never detached, and queued bytes remain counted until physical deletion succeeds.
78
+ The deletion worker skips a file without contacting storage if its confirmed
79
+ workspace, project, asset, storage identity, or version changed.
80
+
81
+ The tool set includes discovery and inspection tools that are read-only.
82
+ The four SEO tools require the exact optional `seo:read` capability. They are
83
+ bounded, read-only, idempotent, and closed-world. They return canonical tasks,
84
+ evidence, neutral provenance, separate topic-relevance and action-readiness
85
+ confidence, and recommended actions. They cannot
86
+ run analysis, change settings, delete data, enable reports, send email, or call
87
+ an external provider.
88
+ Opportunity detail also returns the bounded versioned task: exact decision,
89
+ format, target, deliverables, research, safe URLs, evidence, limitations, and
90
+ success metric. Ready can request final deliverables for human review. Research
91
+ selects only `RESEARCH_TASK`, compares all reasonable formats without a
92
+ preferred final format, and must return `VALIDATED` with a complete next task
93
+ or `REJECTED` with evidence before any separately allowed draft
94
+ action. Every copied task forbids publishing and other Rolino writes.
95
+ `create_project` is an additive, closed-world mutation that requires
96
+ `projects:write` and a caller-supplied idempotency key. It atomically saves the
97
+ project and its paired brand without starting research, connecting accounts,
98
+ scheduling posts, or publishing. The two draft tools can create or selectively
99
+ update draft content but cannot schedule or publish it. Omitted update fields
100
+ preserve current media, destinations, captions, and provider settings. Both require caller-supplied
101
+ idempotency keys, and updates also require the version returned by `get_post`
102
+ so stale writes fail safely. Every tool returns output-schema-validated
103
+ `structuredContent` plus a JSON text fallback.
104
+ YouTube drafts require exactly one stored video, explicit title/category/
105
+ visibility/audience/declaration settings, and optional tags. The YOUTUBE caption
106
+ override becomes the video description, with the shared caption as fallback.
107
+ Unaudited Google API projects may be restricted to Private uploads; the tools
108
+ do not infer audit approval from server configuration.
109
+ Bluesky drafts can be text-only or contain up to four stored JPEG, PNG, or WebP
110
+ images. The BLUESKY caption override accepts up to 300 graphemes, with the
111
+ shared caption as fallback.
112
+ Before preparing TikTok settings, call `refresh_delivery_options`. It contacts
113
+ TikTok and returns secret-safe account choices: allowed delivery modes, exact
114
+ visibility values, interaction availability, and maximum video duration.
115
+ Direct drafts must make every declaration explicit and mark the choices
116
+ reviewed only after inspecting this result. That review is distinct from MCP
117
+ mutation consent. Changing TikTok content clears the prior review, and Rolino
118
+ never silently turns off a requested interaction.
119
+ For LinkedIn, `refresh_delivery_options` returns the connected member plus the
120
+ strict text/single-image/multi-image/video policy and JPEG/PNG/MP4 limits.
121
+ LinkedIn drafts can be text-only, contain up to ten stored images, or contain
122
+ exactly one stored MP4 without mixing images and video. Native video must be
123
+ 75 KB to 500 MB and 3 seconds to 30 minutes, and execution remains in
124
+ preparation until LinkedIn confirms upload and processing. An optional
125
+ 3,000-character LINKEDIN caption override uses the shared caption as fallback.
126
+ The connected member is always the author; Company Page publishing is outside
127
+ this contract.
128
+ Google Business Profile drafts can be text-only or contain one stored JPEG or
129
+ PNG image with a stable public URL. The optional 1,500-character
130
+ GOOGLE_BUSINESS_PROFILE update override uses the shared caption as fallback.
131
+ The tools use the location selected in Rolino, create only standard updates,
132
+ and never choose or change a Business Profile location. If final creation has
133
+ an unknown outcome, inspect the selected Business Profile before retrying.
134
+ Integration health is cached and secret-safe, post
135
+ readiness reuses Rolino's publishing checks, and calendar reads use bounded
136
+ date windows with cursor pagination. After `rolino auth login`, configure `ROLINO_URL` and
137
+ the server automatically obtains and refreshes the API-resource OAuth token saved for
138
+ that exact host. `ROLINO_TOKEN` remains an explicit override for CI and other
139
+ headless environments. `ROLINO_CONFIG_DIR` can override the portable credential
140
+ directory, and `ROLINO_TIMEOUT` is optional. Stdout is reserved for MCP
141
+ messages; startup failures go to stderr without secrets or stack traces.
142
+ `ROLINO_TIMEOUT` accepts integer milliseconds or values such as `500ms`, `15s`,
143
+ and `1m`, matching the CLI.
144
+
145
+ Scheduling uses two separate tools. `preview_post_schedule` contacts the
146
+ configured providers, validates the exact post version, time, timezone, and
147
+ readiness, and returns a five-minute single-use confirmation without scheduling
148
+ anything. `execute_post_schedule` is marked consequential and open-world; it
149
+ requires the unchanged preview values, confirmation token, and a stable
150
+ idempotency key. The server repeats readiness and live-health checks and rejects
151
+ expired, consumed, stale, cross-credential, or mismatched confirmation.
152
+ For YouTube, the preview explains that confirmed scheduling starts or resumes a
153
+ private upload immediately so processing can complete before the Public target.
154
+ Execution may return a typed `PENDING` result with phase
155
+ `REMOTE_SCHEDULE_CONFIRMATION` after the upload completes while YouTube
156
+ acknowledges the requested publish time. The video remains private, the result
157
+ does not report it as published, and no second publish tool call is required.
158
+
159
+ Immediate publishing also uses two tools. `preview_post_publish` checks the
160
+ exact destination set, post version, readiness, live provider health, and retry
161
+ safety without contacting a publish endpoint. `execute_post_publish` requires
162
+ the unchanged preview values, confirmation token, and stable idempotency key,
163
+ then durably queues the selected destinations for immediate delivery. Provider
164
+ calls happen after that database commit, and Rolino's existing reconciliation
165
+ rules block blind retries after ambiguous external results. YouTube remains
166
+ `PREPARING` until upload and processing are provider-confirmed, and its exact
167
+ configured Public, Unlisted, or Private visibility is reconciled before
168
+ publication is reported. The preview reports `deliveryMode: "IMMEDIATE"` and
169
+ `createsSchedule: false`; immediate publishing never enters schedule
170
+ confirmation.
171
+
172
+ MCP tools cannot enable YouTube, Bluesky, LinkedIn, or Google Business Profile,
173
+ or bypass a deployment's provider approval boundary. Self-hosted operators
174
+ should complete the
175
+ [YouTube operations guide](https://github.com/deifos/rolino/blob/main/docs/integrations/youtube.md)
176
+ and
177
+ [Bluesky operations guide](https://github.com/deifos/rolino/blob/main/docs/integrations/bluesky.md),
178
+ [LinkedIn operations guide](https://github.com/deifos/rolino/blob/main/docs/integrations/linkedin.md)
179
+ and the
180
+ [Google Business Profile operations guide](https://github.com/deifos/rolino/blob/main/docs/integrations/google-business-profile.md)
181
+ before live testing.
182
+
183
+ ## Support, security, and license
184
+
185
+ Stable releases are published only after the maintainer approves the release
186
+ gate. Report bugs through the
187
+ [Rolino issue tracker](https://github.com/deifos/rolino/issues) and security
188
+ issues through the repository's
189
+ [security policy](https://github.com/deifos/rolino/security/policy).
190
+
191
+ `@rolino/mcp` is available under the MIT License.
192
+ ## Agent-first Blog Studio tools
193
+
194
+ The local stdio server exposes Blog readiness, import, cadence planning,
195
+ plan-item evidence and state, editable article creation, connection status,
196
+ confirmed provisioning, signed revalidation testing, and these provider-neutral
197
+ publishing reads:
198
+
199
+ - `list_blog_publishing_providers` requires `blog:manage` and returns only
200
+ enabled providers, safe capabilities, and official documentation.
201
+ - `list_blog_publishing_destinations` requires `blog:read` and returns safe
202
+ connection readiness without credentials or private provider data.
203
+ - `list_blog_delivery_attempts` requires `blog:read`, accepts an optional exact
204
+ article ID, and returns safe delivery states, retry times, error codes, and
205
+ remote URLs.
206
+ - `generate_blog_image`, `upload_blog_image`, and `review_blog_image` require
207
+ `blog:write`. They cannot approve an article or publish it. Upload reads only
208
+ the exact local JPEG, PNG, or WebP path supplied to the tool.
209
+ - `preview_blog_plan_cadence` and `apply_blog_plan_cadence` require
210
+ `blog:write`. Preview first, show every editorial move and locked item, then
211
+ apply only the unchanged preview values with its confirmation and a stable
212
+ idempotency key.
213
+ - These cadence tools never change `scheduledPublishAt` and never schedule,
214
+ publish, or unpublish an article.
215
+ - `generate_blog_image` already accepts optional editorial direction through
216
+ `editorialBrief` with a 500-character limit.
217
+ - `preview_blog_revision_approval` and `execute_blog_revision_approval` require
218
+ the independent `blog:approve` capability. Execution makes the confirmed
219
+ exact bundle eligible for a separate publication operation; it cannot
220
+ publish.
221
+ - `preview_blog_schedule`, `execute_blog_schedule`,
222
+ `preview_blog_schedule_cancellation`, and
223
+ `execute_blog_schedule_cancellation` require the independent `blog:publish`
224
+ capability. Scheduling causes future external publication but does not grant
225
+ approval. Cancellation removes only the confirmed future schedule and never
226
+ unpublishes a live article.
227
+
228
+ The three publishing-read tools are closed-world reads. They do not contact a provider or
229
+ change content. They do not return draft content, prompts, evidence, secrets,
230
+ or raw provider responses. Setup requires the
231
+ independent optional `blog:manage` capability; it is never inferred from
232
+ `blog:write` or `blog:publish` and is not added to existing credentials.
233
+
234
+ Read tools are closed-world. The signed revalidation test is accurately marked
235
+ as an open-world write. Connection execute is confirmed, destructive, and
236
+ idempotent; its first success may return one-time values that must be written
237
+ only to server-side environment configuration. Errors and replays never reveal
238
+ those values. These tools remain available over local stdio. The remote profile
239
+ omits both caller-local media and Blog image uploads, and the hosted route stays hidden while its
240
+ deployment gate is off. Publication still requires a user-approved exact revision and the
241
+ separate publish preview/execute tools.
242
+
243
+ Use the Blog tools in this order: read setup and current article or plan state;
244
+ ask for a missing website, cadence, destination, or access level; import and
245
+ plan through polled durable jobs; present evidence before bounded plan
246
+ acceptance; create one immutable revision with catalog-backed links; generate
247
+ or upload and review one image with alt text; stop for user approval when
248
+ `blog:approve` is missing; otherwise preview and execute exact-bundle approval
249
+ with its confirmation token and a stable idempotency key; stop after approval
250
+ when `blog:publish` is missing; otherwise preview and execute unchanged
251
+ publication or scheduling; poll delivery and verify the live URL; and restart
252
+ from approval preview after any content or image change. Existing credentials
253
+ do not gain `blog:approve`, and a queued delivery is not published.
254
+
255
+
256
+ ## Existing delivery recovery
257
+
258
+ `check_post_delivery` reads an existing upload and updates Rolino. It requires `posts:write` and does not publish. `UNKNOWN` requires manual review.
259
+
260
+ `preview_post_recovery` verifies an existing YouTube video and returns the account, consequence, and a short-lived confirmation. After the user approves it, `execute_post_recovery` accepts identical action, video ID, publication time, post version, and token with a stable idempotency key. `ATTACH` cannot publish; `RESUME` requires an explicit future `publishAt` or `null` for publication now, plus `posts:schedule` or `posts:publish`. `QUEUED` is pending, not published. All recovery tools are marked as writes because they change local records. No recovery tool uploads another copy.
261
+
262
+ The same tools are available through packaged and hosted MCP. Upgrade the server and packaged client before using them.
263
+
264
+ ### Bluesky and media transfer
265
+
266
+ `refresh_delivery_options` accepts `BLUESKY` and returns account health, limits, and an owner OAuth handoff. `prepare_media_asset_upload` and `complete_media_asset_upload` work in local and hosted MCP. Transfer the approved bytes to the short-lived URL between these calls. Hosted MCP does not read caller-local paths. `preview_post_schedule_cancellation` and `execute_post_schedule_cancellation` require `posts:schedule`, exact user approval, the current version, confirmation, and a stable retry key. They reject started or uncertain delivery. See `docs/agent-platform/bluesky.md` in the repository.
267
+
268
+ Bluesky workflows also support image alt text, confirmed deletion of untouched drafts (`posts:delete`), and confirmed account disconnection (`integrations:disconnect`). These permissions are optional and independent. See [the complete workflow map](../../docs/agent-platform/bluesky.md).
269
+
270
+
271
+ ## Multiple publishing accounts
272
+
273
+ Use saved connection IDs from integration health, not account names. A draft's `destinations` array can select several accounts on the same network. Each item contains `integrationId`, `provider`, and optional `captionOverride`, `tiktokSettings`, and `youtubeSettings`. A null caption override uses the shared caption. Provide YouTube settings for every YouTube account. TikTok choices and consent belong to each account.
274
+
275
+ Do not combine `destinations` with legacy `platforms` or provider-level settings. A legacy provider-only request is accepted only when its account is unambiguous. The server returns a selection error otherwise. Missing or changed account identity never selects a replacement account.
276
+
277
+ Saved post destinations have their own `id`. Use these destination IDs for publish `destinationIds` and recovery `destinationId`; they are different from connection `integrationId`. Preview, version, confirmation token, and selected destination IDs must remain unchanged when confirming. A pending schedule response can contain several `destinations`, each with its own `mutationId`. Wait for each account's confirmed result.
278
+
279
+ These contracts are staged with the multi-account database migrations. Deploy the server and worker with the same schema before using them. Existing remote receipts remain attached to their saved accounts. No live provider acceptance test is implied by local contract tests.