Skip to main content
Glama
jefflee1990710

Hyperlink MCP

README.md
# Hyperlink MCP

One MCP server, many platforms. Hyperlink MCP gives an LLM agent a single connection through which it can **read, post, comment, and engage** on forums, comment sections, and social media **as the user** — for marketing, SEO research, and community engagement.

Instead of wiring one MCP server per platform into every client, you connect Hyperlink once and add platforms as adapters.

## Status

| Platform | Adapter | Auth | Capabilities |
|---|---|---|---|
| Substack | ✅ opt-in (`SUBSTACK_ENABLE`) | session cookie | full substack-mcp surface (drafts, Notes, feed, comments, restack, tags, settings, stats) |
| Reddit | ✅ opt-in (`REDDIT_ENABLE`) | OAuth | whoami, feed, search, thread, submit, comment, vote |
| Hacker News | ✅ always on | none (public API) | feed, thread, search, user profile (read-only) |
| X (Twitter) | 🔜 planned | session cookie | read + post + reply |
| Threads | 🔜 planned | session cookie | read + post + reply |
| LinkedIn | 🔜 planned | session cookie | read + post + reply |
| LIHKG | 🔜 planned | session cookie | read + post + reply |
| Discourse forums | 🔜 planned | API key | read + post + reply |
| Medium | 🔜 planned | session cookie | read + comment + clap |
| Quora | 🔜 planned | session cookie | read + answer + comment |
| Dev.to | 🔜 planned | API key | read + post + comment |
| Product Hunt | 🔜 planned | OAuth | read + comment + upvote |
| YouTube comments | 🔜 planned | OAuth | read + comment |

(See `src/platforms/_template/` to add one.)

## Quick start

```bash
nvm use
npm install                 # also runs tsc via prepare
npx playwright install chromium   # needed for Substack Notes
npm run smoke               # build + list platforms/tools + live HN
```

Register with an MCP client (e.g. Claude Code):

```bash
claude mcp add hyperlink -- node /path/to/hyperlink-mcp/dist/src/index.js
```

Or in a JSON MCP config (enable platforms via `env`):

```json
{
  "mcpServers": {
    "hyperlink": {
      "command": "node",
      "args": ["/path/to/hyperlink-mcp/dist/src/index.js"],
      "env": {
        "REDDIT_ENABLE": "true",
        "REDDIT_CLIENT_ID": "...",
        "REDDIT_CLIENT_SECRET": "...",
        "REDDIT_REFRESH_TOKEN": "...",
        "SUBSTACK_ENABLE": "true",
        "SUBSTACK_PUBLICATION_URL": "https://yourname.substack.com",
        "SUBSTACK_SESSION_TOKEN": "...",
        "SUBSTACK_USER_ID": "..."
      }
    }
  }
}
```

## Platform setup

A platform is enabled only when its `*_ENABLE` flag is truthy (`true` / `1` / `yes`) **and** every required parameter below is set. `list_platforms` shows what is missing.

### Substack

Session-cookie auth. Log in to Substack in your browser, then copy the `substack.sid` cookie value and your numeric user id.

| Parameter | Required | Description |
|---|---|---|
| `SUBSTACK_ENABLE` | ✅ | Set to `true` to enable the adapter |
| `SUBSTACK_PUBLICATION_URL` | ✅ | Your publication URL, e.g. `https://yourname.substack.com` |
| `SUBSTACK_SESSION_TOKEN` | ✅ | `substack.sid` session cookie value |
| `SUBSTACK_USER_ID` | ✅ | Numeric Substack user id |
| `SUBSTACK_USE_CHROME` | optional | Set to `1` to prefer installed Chrome over bundled Chromium for Notes |

Notes create/reply drive a real browser (Cloudflare-protected endpoints) — install Playwright Chromium once:

```bash
npx playwright install chromium
```

### Reddit

OAuth with a permanent refresh token. Create an app at <https://www.reddit.com/prefs/apps> (type **script** or **web app**), then run the OAuth code flow once with `duration=permanent` to obtain a refresh token.

| Parameter | Required | Description |
|---|---|---|
| `REDDIT_ENABLE` | ✅ | Set to `true` to enable the adapter |
| `REDDIT_CLIENT_ID` | ✅ | App client id from reddit.com/prefs/apps |
| `REDDIT_CLIENT_SECRET` | ✅ | App client secret |
| `REDDIT_REFRESH_TOKEN` | ✅ | Permanent OAuth refresh token |
| `REDDIT_USER_AGENT` | optional | Custom user agent, e.g. `hyperlink-mcp/0.1.0 (by /u/yourusername)` |

### Hacker News

No setup — public Firebase/Algolia APIs, read-only, always on.

| Parameter | Required | Description |
|---|---|---|
| — | — | No configuration needed |

## How it works

```
src/
  index.ts              MCP server bootstrap (stdio transport)
  core/registry.ts      collects adapters, namespaces tools, gates on enableEnv + requiredEnv
  platforms/
    index.ts            the adapter list — register new platforms here
    _template/          copy me: documented adapter skeleton
    hackernews/         reference adapter (public API, no auth)
    reddit/             OAuth adapter (adapter.ts + api.ts)
    substack/           full port of substack-mcp (adapter.ts + api/ + tools/ + utils/)
dist/                   tsc output — MCP clients point here
```

- Every adapter exposes tools namespaced by platform: `hackernews_search`, `reddit_comment`, …
- Optional `enableEnv` (e.g. `REDDIT_ENABLE`) must be truthy (`true` / `1` / `yes`); then every `requiredEnv` credential must be set. Until then the platform is **disabled but visible** — `list_platforms` lists what is missing.
- Adapters aim for a shared verb set (`whoami`, `get_feed`, `search`, `get_thread`, `create_post`, `comment`, `react`) plus platform-specific extras, so agent skills transfer between platforms.

## Adding a platform

1. Copy `src/platforms/_template/` to `src/platforms/<platform>/`.
2. Fill in `id`, `name`, optional `enableEnv`, `requiredEnv`, and implement the tool handlers (`adapter.ts` + `api.ts` as needed).
3. Register the adapter in `src/platforms/index.ts`.
4. `npm run build` then `npm run smoke` / `npm run test:registry`.

Auth guidance lives in the template. For cookie-auth platforms behind bot detection (Cloudflare etc.), the proven pattern is playwright-extra + stealth with in-page `fetch()` calls — see `src/platforms/substack/tools/create_note.ts` and `utils/notesBrowser.ts`.

## Configuration

All credentials come from environment variables, one prefix per platform (see `.env.example`). No credentials are ever written to disk by this server.

## A note on responsible use

This server acts **as the authenticated user, on their own accounts, at their direction**. Use it for genuine engagement and research. Platform terms of service still apply — spam and inauthentic behaviour will get accounts banned regardless of tooling.