Install
openclaw skills install @niyonx/postoncePublish or schedule social posts, inspect delivery, and manage automatic crossposting through a connected PostOnce MCP server. Use when the user wants to send content to their PostOnce accounts or configure a PostOnce workflow.
openclaw skills install @niyonx/postonceUse the connected PostOnce tools for the user's requested publishing or crossposting task. This skill supplies workflow guidance; installing it does not connect an account or grant access.
Requires a configured PostOnce MCP connection and account access. Local media upload also requires a client capable of reading the file and making an HTTP upload.
This skill is free. The external PostOnce API requires a paid Creator or Pro subscription; see current plans. Installing this skill does not purchase access, connect an account, or grant tool permissions. Respect the active OpenClaw tool policy and existing approvals.
Use an OpenClaw release with native openclaw mcp support (tested: 2026.9.3). Create a dedicated manual API key in PostOnce Preferences. For account discovery and draft create/read, select accounts:read, posts:read and posts:write; add media:write and media:read only for uploads. The posts:write scope also permits publishing: it is not a draft-only permission. Do not publish unless the user requests it.
Supply POSTONCE_API_KEY through the private environment of the actual Gateway/runtime process before starting it. Never place its value in chat, the skill, a committed file or command history. Check for an existing PostOnce MCP entry first and preserve it or update it deliberately; do not overwrite unrelated configuration. If absent, run:
openclaw mcp add postonce --url https://postonce.to/mcp --transport streamable-http --header 'Authorization=Bearer ${POSTONCE_API_KEY}' --no-probe
openclaw mcp probe postonce --json
The single quotes preserve the environment reference in saved configuration. A remote Gateway needs its own private environment. Restart the actual runtime after environment changes. This manual-key connection does not use auth: "oauth". Successful discovery should expose PostOnce tools; missing or revoked credentials must be resolved before proceeding. See OpenClaw setup.
For a request such as “Save this release note as a draft for review,” discover tool schemas and call list_accounts to confirm access. Then call create_draft with the user's content and a stable idempotency_key, for example openclaw:release-note:source-event-001. Derive that identity from the real source event; never reuse this example literally for unrelated drafts. Omit targets and media for a personal text draft. Do not substitute create_post.
Read the actual returned data.id, call get_draft with that ID, and report the returned status (inbox for the tested personal draft), content and ID. MCP clients may unwrap data; inspect the actual result instead of assuming a wrapper. If retrying the same operation, keep both key and payload unchanged; inspect the returned ID and timestamps. A changed body with the same key is a conflict, not a reason to generate a fresh key automatically. A saved draft is not published social content. Review it in PostOnce drafts.
If PostOnce tools are missing, use the client's setup at PostOnce integrations. The hosted endpoint is https://postonce.to/mcp (Streamable HTTP). Follow the currently supported authentication route for that client. Keep credentials in the client's private connection settings or secret environment; never ask for a key in chat.
list_accounts or list_active_accounts. Use returned IDs, status and usernames to select the user's intended accounts. An empty list is a successful connection with no usable accounts; guide the user to Connect accounts, then refresh the list. Do not invent IDs or select every account by default.capabilities and media_requirements before choosing text-only, image or video content. required_media takes precedence over a broad text capability. These are platform-level rules, not a guarantee that an account is currently authorized or that delivery will succeed. If an older server omits constraints, consult the current API documentation and the actual tool schema; do not infer limits from a platform's name.Use create_post with content, targets: [{"account_id": "<returned ID>"}], and supported media if needed. Per-target copy belongs in content_override; platform-specific settings belong in platform_options according to the current schema. Use publish_at only for a requested future time, resolved to an ISO timestamp with an explicit offset. Omitted publish_at requests immediate processing. Use create_draft when the user requests a draft instead of publishing.
Assign a stable idempotency_key to each intended mutating operation when the tool exposes it. Keep the same key and identical inputs if retrying an uncertain request; a new key means a new operation. Save returned IDs. After an ambiguous timeout, inspect list_posts/get_post and any returned ID or external reference before submitting again. Retry transient failures only within the user's requested scope; stop repeated failures with the exact next recovery action.
Call get_post with the returned post ID. Report the aggregate status and each target's status/error or actual published URL. Queued, scheduled, processing, failed and published are different outcomes. A successful creation response is not proof of delivery. If delivery is still pending, say so and provide the post ID and PostOnce publishing history. A TikTok draft delivered to the creator's inbox still requires them to finish publishing in TikTok.
Example user request: “Publish this release note to my connected LinkedIn account and show the result.” Discover the account, create the authorized post using the returned ID, then inspect that same post. Do not turn this into a recurring workflow.
For a user-approved, publicly fetchable media URL, pass media: [{"type": "image", "url": "<actual URL>"}] (or video) to create_post. Check destination requirements, including thumbnails when required. Avoid signed private URLs unless the user intends the media to become public and the source remains accessible for processing.
The hosted MCP cannot read files on the user's computer. Do not send a local file path to the remote endpoint or treat a chat attachment ID as a public URL.
If the client has access to the user's selected file and can upload bytes:
create_upload_url with its filename and actual content_type.data.upload.signedUrl using that content type. The upload URL is a short-lived credential: keep it out of messages, logs, persisted examples and analytics. Do not send the PostOnce API key to the storage host.get_media with data.media_id and use the returned data.public_url in create_post (or an explicitly requested create_draft). Media uploaded for publishing is publicly accessible. If supplying media size or duration, also supply its actual width and height; do not invent dimensions.If the client cannot upload the file or access a usable attachment URL, explain that limitation and request a supported URL or use PostOnce's existing media UI. Do not claim attachment support without the actual transfer.
Only a separately configured local stdio PostOnce MCP server exposes upload_media_from_path, create_media_post_from_path and create_tiktok_draft_from_path. Paths then refer to that local process's filesystem. These helpers are not part of the hosted connection. Video convenience helpers may require local ffmpeg for a poster image; a supplied supported thumbnail avoids generating one.
Example user request: “Publish this image from my project to Instagram.” Resolve the local file in the client, inspect the Instagram account's required media, upload bytes through the supported flow, then create and inspect the post. Never claim success from the signed-URL response.
Use workflows only when the user requests recurring crossposting of future source content. Discover source and destination accounts and check their capabilities. Some platforms cannot be a source; current account permissions and connection prerequisites are validated by the service.
Call list_workflows to avoid creating an unintended duplicate. For a new workflow use create_workflow with name, source_account_id, target_account_ids, and the user's requested settings. Future automatic crossposting uses future_content_enabled: true and is_active: true; set is_active: false if the user only wants a paused setup. Do not imply this imports historical posts. Use update_workflow for an existing rule; pause with is_active: false or delete only when requested.
Read the saved rule with get_workflow and report its ID, actual source, targets and active/future-content state. Creating a rule does not prove that a future source post has been detected or delivered. Review subsequent results in the workflows dashboard. Preserve each destination's outcome when partial failures occur.
Example user request: “Automatically crosspost future posts from this Instagram account to these two accounts.” Resolve those specific IDs, inspect existing workflows, create or update the intended rule, and read it back. Do not publish a test post without authorization.