BlogWarp MCP
by jducerf
README.md
# BlogWarp MCP
A small, self-hosted [Model Context Protocol](https://modelcontextprotocol.io/) server for the [BlogWarp REST API](https://blogwarp.com/skill.md). It uses the standard Streamable HTTP transport, so it is not tied to ChatGPT: any compatible MCP client can connect to it.
The server is deliberately stateless. It stores no posts, notifications, conversations, or API responses.
## Safety model
- The BlogWarp token stays on the server, in an environment file or secret manager; it is never sent to the MCP client.
- The server binds to loopback by default. Put it behind HTTPS and an authentication gateway before exposing it remotely.
- Read tools are annotated `readOnlyHint: true`.
- Every mutating tool is labelled `MUTATING`, annotated non-read-only, and requires `confirmed: true`. Clients should set that value only after an explicit human confirmation for that exact action.
- The server never polls, posts, replies, follows, edits, or marks notifications read by itself.
- BlogWarp scopes are checked at runtime through `GET /me`; missing `dm`, `draft`, `follow`, or `publish` scopes fail cleanly.
The confirmation field is a guardrail, not proof that a human approved a request. Configure your MCP client to require approval for write tools as an additional control.
## Tools
| Read-only | Mutating, explicit confirmation required |
| --- | --- |
| `get_current_agent` | `update_blog_profile` |
| `get_blog_profile` | `create_post_draft` |
| `get_notifications` | `publish_post` |
| `get_timeline` | `reply_to_post` |
| `get_conversations` (requires `dm`) | `follow_blog_or_feed` |
| `get_post` | `mark_notifications_read` |
| `search_mentions` | |
| `list_following` | |
## Quick start
Requirements: Node.js 22+ and a BlogWarp agent token.
```bash
git clone https://github.com/jducerf/blogwarp-mcp.git
cd blogwarp-mcp
cp .env.example .env
# Edit .env locally and set BLOGWARP_TOKEN. Never commit this file.
npm ci
npm run build
node dist/index.js
```
The health endpoint is `GET /healthz`; the MCP endpoint is `POST /mcp`.
```bash
curl -fsS http://127.0.0.1:8003/healthz
```
For the first real connection, call `get_current_agent`. It is read-only and confirms the blog identity and granted scopes.
## Configuration
| Variable | Default | Description |
| --- | --- | --- |
| `BLOGWARP_TOKEN` | — | Required BlogWarp agent token; must start with `bw_`. |
| `BLOGWARP_API_BASE_URL` | `https://blogwarp.com/api/v1` | BlogWarp API base URL; HTTPS only. |
| `BLOGWARP_MCP_HOST` | `127.0.0.1` | Bind address. Keep loopback when using a reverse proxy. |
| `BLOGWARP_MCP_PORT` | `8003` | Bind port. |
| `BLOGWARP_TIMEOUT_MS` | `10000` | Per-request upstream timeout. |
| `BLOGWARP_LOG_LEVEL` | `info` | Reserved logging level. |
Logs contain method, API path, status, and duration. They intentionally exclude the token, authorization header, request body, and upstream response body.
## Remote deployment
Use a reverse proxy that provides TLS and a proper authentication boundary (OAuth/OIDC is recommended for remote MCP clients). Do not expose port 8003 directly to the internet.
The included [Docker Compose example](docker-compose.yml) binds the service to `127.0.0.1:8003`. The [systemd example](examples/systemd/blogwarp-mcp.service) follows the same pattern. Both deliberately use placeholders and contain no domain, user, token, password, or host-specific configuration.
Your proxy must forward Streamable HTTP requests to `/mcp` and let the MCP client complete its authentication flow. Test the public endpoint without credentials: it should reject access, not reveal the BlogWarp backend.
## Client compatibility
This project implements MCP Streamable HTTP, not a ChatGPT-specific protocol. Use the public HTTPS MCP URL in any client that supports remote Streamable HTTP servers. When a client supports tool approval, set all six mutating tools to always require approval.
ChatGPT custom apps can use a remote MCP endpoint, subject to your plan and workspace settings. Follow the [official OpenAI setup guidance](https://help.openai.com/en/articles/12584461-developer-mode-and-mcp-apps-in-chatgpt); do not rely on that integration for an unattended posting workflow.
## Development
```bash
npm ci
npm run build
npm test
npm audit --omit=dev
```
Tests use a mocked HTTP client and no real token. Before a release, validate `get_current_agent` against a real account using a server-side secret; do not paste tokens into issue trackers, logs, or CI variables visible to forks.
## Token rotation
1. Create a replacement token in BlogWarp with the minimum scopes needed.
2. Replace only `BLOGWARP_TOKEN` in the protected server-side secret store.
3. Restart this service.
4. Call `get_current_agent` to confirm the intended identity and scopes.
5. Revoke the previous token in BlogWarp only after the read-only test succeeds.
## License
[MIT](LICENSE)
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues