+ Integration Guide
· Updated August 29, 2026
How to Connect Twitter MCP to Hermes Agent
Set up FetchLayer's Twitter/X MCP server with Nous Research's Hermes Agent to search tweets, get profiles, and pull follower data — in YAML, not JSON.
Written by Alex P.
- MCP
- Hermes Agent
- Nous Research
- twitter scraping
- X scraping
- AI agent
Hermes Agent is Nous Research’s open-source, MIT-licensed terminal agent, with native MCP client support since v0.2.0. Unlike most MCP clients, Hermes configures servers in YAML, not JSON — if you’ve set up FetchLayer’s MCP server in Claude Desktop or Cursor already, you can’t just copy that block in; the shape is different.
Once connected, Hermes gets access to all 10 FetchLayer Twitter/X tools — search, tweet and reply lookups, profiles, and both sides of the follower graph — as structured results it can reason over inside your terminal session.
Prerequisites
- Hermes Agent installed (
pip install hermes-agentor per the official install docs) - A FetchLayer API key — get one free (no credit card)
Step 1: Open the Hermes config
Hermes stores all its settings under a single global directory in your home folder — this isn’t per-project like some IDE-based clients:
~/.hermes/config.yaml
The same directory also holds ~/.hermes/.env (secrets and API keys, kept separate from the main config on purpose), auth.json (OAuth credentials for any connected accounts), and the agent’s persistent memory files. Create config.yaml if it doesn’t already exist.
Step 2: Add the FetchLayer server
MCP servers live under the mcp_servers key. Since FetchLayer is a remote HTTP server (not a local process Hermes spawns via command/args, the way filesystem or git MCP servers usually work), the entry uses url and headers instead:
mcp_servers:
fetchlayer:
url: "https://mcp.fetchlayer.dev"
headers:
Authorization: "Bearer ss-your-api-key"
Replace ss-your-api-key with your key from the FetchLayer dashboard. If you’d rather keep the key out of config.yaml entirely, Hermes supports referencing values from ~/.hermes/.env — set FETCHLAYER_API_KEY=ss-your-api-key there and reference it in the header value per Hermes’ env-substitution syntax.
If you already have other MCP servers configured (a common one is a local filesystem server via npx), add fetchlayer as a sibling key under the same mcp_servers block — don’t create a second one.
Step 3: Restart Hermes
Hermes reads config.yaml on startup, so exit and relaunch your session for the new server to take effect. There isn’t a documented single command to verify an individual MCP server’s live connection status the way some other clients offer — the most reliable check is simply asking the agent to use a Twitter tool and confirming it responds with real data rather than an error about an unknown tool.
A note on tool filtering
By default, Hermes registers every tool an MCP server exposes. For FetchLayer that’s all 10 Twitter/X tools, which is fine — but if you’re also running several other MCP servers, the combined tool list can bloat your context window and make the agent more likely to call something you didn’t intend. Hermes supports a tools filtering block per server if you only want a subset (for example, just twitter_search and twitter_user_tweets for a narrower workflow):
mcp_servers:
fetchlayer:
url: "https://mcp.fetchlayer.dev"
headers:
Authorization: "Bearer ss-your-api-key"
tools:
allow: ["twitter_search", "twitter_user_tweets"]
Leave tools out entirely if you want the full set, as in Step 2.
Why YAML instead of JSON here
If you’re coming from a JSON-configured client, Hermes’ choice of YAML for config.yaml isn’t arbitrary — the same file also holds model selection, terminal behavior, compression settings, and other agent-wide preferences that benefit from inline comments explaining why a value is set the way it is, which plain JSON doesn’t support. The tradeoff is that YAML’s indentation-sensitive syntax is less forgiving of a stray space than JSON’s brace-delimited structure, so when a config edit doesn’t take effect, checking indentation consistency (spaces vs. tabs, correct nesting depth) is usually a faster diagnosis than assuming the server details themselves are wrong.
Try it out
Ask Hermes:
Search X/Twitter for “best database for side projects” and summarize what developers recommend.
The agent calls FetchLayer’s search tool and returns structured Twitter/X data as part of its response.
More examples:
- “What are people saying about Rust on X/Twitter this month?”
- “Get the profile and recent tweets from @rauchg”
- “Scrape replies to this tweet and find the most-liked opinions”
- “Get verified followers of @openai”
Available Tools
All 10 FetchLayer Twitter/X tools: twitter_search, twitter_tweet_detail, twitter_tweet_replies, twitter_user_profile_details, twitter_about_profile, twitter_user_tweets, twitter_user_replies, twitter_following, twitter_followers, and twitter_verified_followers. Full parameter reference: Twitter/X API endpoints.
Troubleshooting
Agent doesn’t recognize the server?
- Confirm
config.yamlis valid YAML — indentation matters, and a tab character where a space is expected will break the parse silently in some YAML loaders - Double-check the key is
mcp_servers(plural, underscore) — notmcpServers(the camelCase JSON convention other clients use) - Restart the session; Hermes doesn’t hot-reload config mid-run
Auth errors on tool calls?
- Verify the key is copied in full and starts with
ss- - If using
.envsubstitution, confirm the variable name in.envmatches exactly whatconfig.yamlreferences
Tool calls are slow on first use?
- This is more common with
npx-installed local MCP servers (Hermes recommends pre-installing those to avoid a first-launch timeout), but shouldn’t apply to a remote HTTP server like FetchLayer’s — if you see it, check your own network path tomcp.fetchlayer.devrather than a Hermes-side issue
Why a remote HTTP server instead of a local process
Most MCP servers you’ll add to Hermes — filesystem access, git, a local database — run as a child process Hermes spawns via command and args, communicating over stdio. FetchLayer’s server is different: it’s a hosted HTTP endpoint at mcp.fetchlayer.dev, which is why the config uses url instead. Practically, this means there’s nothing to install or keep updated locally — no npm package version to bump, no binary to rebuild — and no local process for Hermes to manage the lifecycle of. The tradeoff is that tool calls go over the network rather than a local pipe, so if your terminal session is somewhere with unreliable connectivity, that’s the layer to check first if a Twitter tool call hangs, rather than assuming Hermes itself is stuck.
Keeping your key out of version control
If you sync your dotfiles (including ~/.hermes/) to a personal repo, don’t let config.yaml hold your raw FetchLayer key even though it’s a “local” file — dotfile repos get pushed to remotes more often than people expect. Since Hermes already separates secrets into ~/.hermes/.env, and .env files are conventionally git-ignored, put the key there and reference it from config.yaml rather than pasting it inline in the headers block. It’s a small habit that avoids a key rotation scramble later.
What a tool call actually returns
Every result carries its author and engagement counts together:
{
"results": [
{
"id": "1942939879222220800",
"text": "Third outage this month. Looking at alternatives.",
"author": { "handle": "example_dev", "displayName": "Example Dev", "followersCount": 12400 },
"likeCount": 284,
"retweetCount": 41,
"replyCount": 63,
"createdAt": "2026-08-18T10:00:00.000Z",
"url": "https://x.com/example_dev/status/1942939879222220800"
}
]
}
That shape is what lets an agent triage without extra calls: rank by replyCount to find arguments, divide engagement by followersCount to find posts punching above their audience, and only then decide what deserves a tweet-replies call.
The cost model, in one table
| Call | Requests |
|---|---|
search | 1, regardless of result count |
tweet-detail / user-profile-details | 1 |
tweet-replies | 1 per page |
user-followers / user-following | 1 per page |
| Reasoning over fetched data | 0 |
The graph endpoints are the ones to watch. An agent asked to “analyze an audience” has no built-in reason to stop paging, and an unattended run is precisely where that matters.
Bounding an unattended run
State a limit and a stopping condition in the objective itself:
“Search X for mentions of our product from the last week, open replies on at most three posts, and stop once you have five distinct complaints.”
Two independent terminators — a call cap and a result target — whichever lands first. Compare with “find out what people think of our product”, which never terminates on its own.
For follower work, bound the pages explicitly:
“Pull the first 2 pages of followers for @example and characterize them.”
Asking for citations
Every post comes back with a url, so requiring them costs nothing and gives you a way to audit an unattended run:
“For each claim, include the post URL it came from.”
A claim without a URL came from the model, not from X. On a run nobody watched, that’s the cheapest verification available — and the URLs were already in the responses.
What’s Next
- Twitter/X MCP: All Clients Compared — every supported AI tool in one place
- Twitter MCP + Cursor — a JSON-configured alternative
- Twitter MCP + Claude Desktop
- Twitter MCP + Claude Code
- How to Scrape Twitter/X in 2026 — every method compared, not just MCP
- FetchLayer API Reference — full endpoint docs