Last updated: September 2026
Post to LinkedIn and Bluesky from Hermes Agent
Add OpenTweet to ~/.hermes/config.yaml as a remote MCP server: url https://mcp.opentweet.io/mcp plus an Authorization: Bearer ot_... header. Run /reload-mcp. Hermes can then call opentweet_create_tweet with a platforms array to post to your LinkedIn profile, Bluesky and X. Connect LinkedIn and Bluesky once in OpenTweet.
Hermes Agent is the open-source agent from Nous Research. It already speaks MCP, so there is no plugin to install and no LinkedIn developer app to create.
7-day free trial. Cancel anytime.
1. Connect LinkedIn and Bluesky once in OpenTweet
Sign up, then connect each network in Settings > Accounts. LinkedIn uses LinkedIn sign-in, Bluesky uses atproto OAuth (no App Password), and X uses X OAuth. Hermes never sees any of those credentials.
Open the API section and generate a key. It starts with ot_. Put it in the environment Hermes runs in:
export OPENTWEET_API_KEY="ot_your_key_here"
2. Add OpenTweet to config.yaml
Hermes reads MCP servers from the mcp_servers block of ~/.hermes/config.yaml. A server with a url connects over Streamable HTTP, and headers carries the key. Hermes fills in ${OPENTWEET_API_KEY} from the environment, or you can paste the key in directly.
# ~/.hermes/config.yaml
mcp_servers:
opentweet:
url: "https://mcp.opentweet.io/mcp"
headers:
Authorization: "Bearer ${OPENTWEET_API_KEY}"Then run /reload-mcp in your Hermes session. The messaging gateway (Telegram, Discord, Slack) picks up the change by itself within about a minute. The header is required: the hosted server has no OAuth flow, and the URL alone returns 401.
Prefer a local process? The npm package runs over stdio with the key in env. It exposes the same tools.
# ~/.hermes/config.yaml
mcp_servers:
opentweet:
command: "npx"
args: ["-y", "@opentweet/mcp-server"]
env:
OPENTWEET_API_KEY: "ot_your_key_here"Config keys as described in the Hermes MCP config reference, checked September 2026.
3. Ask Hermes to post
Plain requests work. Name the networks in the prompt so Hermes sets platforms:
> Write a LinkedIn post about why we moved our job queue to Postgres. Save it as a draft for LinkedIn only. > Turn that into a Bluesky version under 300 characters and post it now. > Post "Shipped: CSV export is live for every plan." to LinkedIn, Bluesky and X right now.
Behind those prompts, Hermes calls the OpenTweet tools like this:
opentweet_create_tweet({
text: "We moved our job queue to Postgres. Three things we learned...",
platforms: ["linkedin"]
})
// no scheduled_date and no publish_now: saved as a draft
opentweet_create_tweet({
text: "Shipped: CSV export is live for every plan.",
platforms: ["linkedin", "bluesky", "x"],
publish_now: true
})
// Unsure where a post without platforms would go? Ask first.
opentweet_list_platforms({})Always pass platforms
A post with noplatforms follows the account's auto cross-post setting, which can mean every connected network. An explicit list is honoured exactly. Add a line to your Hermes instructions such as "always set platforms when posting".4. Schedule a week of posts
The safe pattern is draft, review, then schedule. Hermes creates each post as a draft pinned to LinkedIn and Bluesky, you read them in the dashboard or in chat, and one opentweet_batch_schedule call sets the times.
> Draft five LinkedIn and Bluesky posts for next week from the changelog below, one per weekday. Keep each Bluesky-safe (under 300 characters). Save them as drafts and show me the ids. > Looks good. Schedule them Monday to Friday at 14:00 UTC.
// Step 1, once per post: create a draft pinned to both networks
opentweet_create_tweet({
text: "Monday: CSV export now includes custom fields.",
platforms: ["linkedin", "bluesky"]
})
// Step 2, one call for the week (up to 50 entries)
opentweet_batch_schedule({
schedules: [
{ post_id: "66f1a0c2e4b0a1b2c3d4e5f1", scheduled_date: "2026-09-28T14:00:00Z" },
{ post_id: "66f1a0c2e4b0a1b2c3d4e5f2", scheduled_date: "2026-09-29T14:00:00Z" },
{ post_id: "66f1a0c2e4b0a1b2c3d4e5f3", scheduled_date: "2026-09-30T14:00:00Z" },
{ post_id: "66f1a0c2e4b0a1b2c3d4e5f4", scheduled_date: "2026-10-01T14:00:00Z" },
{ post_id: "66f1a0c2e4b0a1b2c3d4e5f5", scheduled_date: "2026-10-02T14:00:00Z" }
]
})opentweet_batch_schedule takes a schedules array of post_id and scheduled_date pairs, up to 50, with dates in the future. It only sets times: each post keeps the networks it was drafted with. Your plan's daily post limit still applies. For a single post, passing scheduled_date straight to opentweet_create_tweet does the same job.
What LinkedIn and Bluesky do differently
As of September 2026.
Bluesky stops at 300 characters
A post over 300 is skipped on Bluesky with a stated reason, and the other networks still publish. The tool result lists each network, so Hermes can write a shorter Bluesky version and post it on its own.
LinkedIn allows 3,000
Counted strictly, so an emoji counts as 2. A thread sent to LinkedIn becomes one post, with the parts joined by blank lines.
LinkedIn means your personal profile
Posts go to the member profile you connected. Company Pages are not supported, and there are no DMs or connection requests.
Hashtags and mentions are plain text on LinkedIn
They publish as text, not links. LinkedIn takes up to 4 images and no video.
X is strict, the others skip
If x is one of the platforms and the text is over your X limit, the whole call fails validation. Bluesky and LinkedIn overflow only skips that one network.
Links depend on your plan
Pro includes no posts with URLs; Advanced allows 10 a day and Agency 20. Over the allowance the URL is removed from the text, unless you have purchased URL credits.
LinkedIn sign-in expires every 60 days
LinkedIn gives self-serve apps no refresh token. When the sign-in expires, scheduled LinkedIn posts are held and OpenTweet emails you to reconnect.OpenTweet vs calling the LinkedIn API yourself
You can give Hermes LinkedIn access without OpenTweet. It is more work, and Bluesky is a second integration on top.
| LinkedIn API directly | Through OpenTweet | |
|---|---|---|
| LinkedIn setup | Create an app in the LinkedIn Developer Portal, add the Share on LinkedIn product, and run the OAuth flow for the w_member_social scope yourself. | Sign in with LinkedIn once in OpenTweet. No developer app. |
| Token upkeep | The access token lasts 60 days and self-serve apps get no refresh token, so you build your own expiry handling. | Same 60-day LinkedIn limit. OpenTweet holds scheduled LinkedIn posts and emails you to reconnect. |
| Hermes integration | You write and host an MCP server or tool that calls LinkedIn, and another one for Bluesky. | One mcp_servers entry. 43 tools, with a platforms parameter on the posting tools. |
| Scheduling | You run your own queue and a worker that posts at the set time. | scheduled_date on any post, or opentweet_batch_schedule for up to 50 at once. |
| Cost | Free, plus your time and hosting. | From $11.99 a month, after a 7-day trial. |
If you only need LinkedIn, never schedule, and are happy to maintain the OAuth flow, going direct is reasonable. If you want LinkedIn, Bluesky and X from one Hermes config with a queue you can review, OpenTweet is less to build.
Frequently asked questions
Can Hermes Agent post to LinkedIn?
Yes, to your personal LinkedIn profile. Add OpenTweet as an MCP server in ~/.hermes/config.yaml, connect LinkedIn once in OpenTweet, and ask Hermes to post. It calls opentweet_create_tweet with platforms set to ["linkedin"]. Company Pages are not supported.
Can Hermes Agent post to Bluesky?
Yes. Connect Bluesky in OpenTweet over atproto OAuth, so no App Password goes in your Hermes config, then pass "bluesky" in platforms. Posts over 300 characters are skipped on Bluesky with a reason, and the tool result tells Hermes so it can shorten and retry.
Does Hermes support remote MCP servers with an Authorization header?
Yes. The Hermes MCP docs describe HTTP servers configured with url and headers under mcp_servers, using Streamable HTTP by default, and values like ${OPENTWEET_API_KEY} are read from the environment. The OpenTweet hosted server needs that header; the URL alone returns 401.
Do I need a LinkedIn developer app or API key?
No. OpenTweet uses LinkedIn's self-serve Share on LinkedIn product on your behalf. Hermes only holds an OpenTweet key that starts with ot_, which you can revoke at any time.
How do I schedule a week of LinkedIn posts with Hermes?
Ask Hermes to draft the posts with platforms set, review them, then have it call opentweet_batch_schedule with a list of post_id and scheduled_date pairs. One call takes up to 50 posts. Or ask for a scheduled_date on each post as it is created.
Can I use Hermes from Telegram to post to LinkedIn?
The MCP tools come from config.yaml, so they are available wherever Hermes runs, including its messaging gateway. The Hermes docs say the gateway picks up config.yaml changes within about a minute without a restart.
Does this post to Instagram, Threads or Facebook?
No. OpenTweet posts to X, Bluesky and LinkedIn only, so platforms accepts exactly those three values.
Keep exploring
The X side of Hermes, the same tools in other agents, and the schedulers.
Hermes Agent integration
The X side of the same setup: threads, evergreen, analytics.
Give any AI agent a LinkedIn and Bluesky tool
The same posting as a function tool for CrewAI, LangChain and others.
Post to LinkedIn from Claude Code
One claude mcp add command, same hosted server.
LinkedIn scheduler
See and edit what Hermes scheduled in the dashboard queue.
Bluesky MCP server
atproto OAuth instead of an App Password in your config.
One config entry, three networks
Hermes posts to LinkedIn, Bluesky and X through one ot_ key. Plans from $11.99 a month.
7-day free trial. Cancel anytime.