Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .cursor-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "hackmd",
"version": "0.1.0",
"description": "Official HackMD plugin for Cursor with HackMD MCP setup, CLI skill, and guided setup workflow.",
"version": "0.2.0",
"description": "Official HackMD plugin for Cursor. Connects to HackMD through OAuth MCP; no API token for MCP.",
"author": {
"name": "HackMD"
},
Expand All @@ -11,6 +11,7 @@
"hackmd",
"cursor",
"mcp",
"oauth",
"notes",
"documentation"
]
Expand Down
10 changes: 2 additions & 8 deletions .mcp.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
{
"mcpServers": {
"hackmd-mcp": {
"command": "npx",
"args": [
"mcp-remote@0.1.38",
"https://mcp.hackmd.io/",
"--header",
"Authorization:Bearer ${env:HMD_API_ACCESS_TOKEN}"
]
"hackmd": {
"url": "https://mcp.hackmd.io/"
}
}
}
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ The format is based on Keep a Changelog, and this project follows Semantic Versi

## [Unreleased]

### Changed

- MCP connects to `https://mcp.hackmd.io/` with OAuth 2.1 (URL-only `.mcp.json`). No API token and no `mcp-remote` for MCP.
- README and `setup-hackmd` walk through the browser OAuth flow instead of `HMD_API_ACCESS_TOKEN` on the MCP path.
- CLI still uses `hackmd-cli login` or a personal API token; that token is independent of MCP OAuth.

## [0.1.0] - 2026-03-31

### Added
Expand Down
84 changes: 30 additions & 54 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
# HackMD Cursor Plugin

Official HackMD plugin scaffold for Cursor.
Official HackMD plugin scaffold for Cursor. Connects to HackMD through OAuth MCP.

This plugin provides:

- A repo-hosted `logo.png` wired into the plugin manifest
- A ready-to-configure `.mcp.json` entry for the HackMD MCP server
- A `hackmd-cli` skill adapted for Cursor plugin format
- A `.mcp.json` entry for the official remote MCP server (`https://mcp.hackmd.io/`, OAuth)
- A `hackmd-cli` skill for shell workflows
- A `setup-hackmd` command for local setup and verification
- A light HackMD workflow rule for note-related tasks

MCP does **not** use an API token. OAuth runs in the browser on first use. The REST API and CLI still use personal API tokens; those credentials do not belong in MCP config.

## Repository Layout

```text
Expand Down Expand Up @@ -61,7 +63,7 @@ Quit Cursor completely and reopen it (a window reload is not always enough). The
- the `hackmd-cli` skill is available
- the `setup-hackmd` command is available
- the `hackmd-workflow` rule is discoverable
- the `.mcp.json` template is at the repo root for merging into your user MCP config (see [Setup](#2-configure-hackmd-mcp-safely))
- Cursor has loaded the plugin MCP server `hackmd`

## Setup

Expand All @@ -75,60 +77,32 @@ The plugin entrypoint is:
.cursor-plugin/plugin.json
```

### 2. Configure HackMD MCP safely

Do not put API tokens inside `mcp.json`. In Cursor, `mcp.json` values support interpolation: strings like `${env:VAR}` are resolved from your environment when MCP loads.

1. Copy the `hackmd-mcp` entry from this repo's `.mcp.json`
2. Paste it into your user-level Cursor MCP config at `~/.cursor/mcp.json` (or merge into an existing file)
### 2. Connect HackMD MCP (OAuth)

The header uses the same variable as the HackMD CLI: `HMD_API_ACCESS_TOKEN`.

Example (no secrets in the file):
If Cursor does not pick up the plugin `.mcp.json` automatically, merge this into `~/.cursor/mcp.json`:

```json
{
"mcpServers": {
"hackmd-mcp": {
"command": "npx",
"args": [
"mcp-remote@0.1.38",
"https://mcp.hackmd.io/",
"--header",
"Authorization:Bearer ${env:HMD_API_ACCESS_TOKEN}"
]
"hackmd": {
"url": "https://mcp.hackmd.io/"
}
}
}
```

Cursor resolves `${env:HMD_API_ACCESS_TOKEN}` from the environment it inherits when it starts (not from secrets embedded in `mcp.json`). Set the variable in your **shell profile** (for example `~/.zshrc` or `~/.bashrc`) and fully restart Cursor, or define it in your **OS user / system environment** so GUI-launched Cursor sees it—same idea as Cursor’s MCP docs: use config interpolation in `mcp.json` and keep real values in the environment. Use the same token as in [Configure HackMD CLI authentication](#4-configure-hackmd-cli-authentication) below.
Fully restart Cursor, then invoke any HackMD tool (or ask Cursor to list your notes). Complete the browser OAuth prompt. Closing it leaves the client unauthorized.

To sanity-check the remote command from a terminal (shell variable, not Cursor interpolation):
Do not add `mcp-remote`, `Authorization` headers, or `HMD_API_ACCESS_TOKEN` to MCP config. Those are leftover from the token-era setup.

```bash
export HMD_API_ACCESS_TOKEN=YOUR_TOKEN
npx mcp-remote@0.1.38 https://mcp.hackmd.io/ --header "Authorization:Bearer $HMD_API_ACCESS_TOKEN"
```
### 3. Optional: HackMD CLI

### 3. Install HackMD CLI
CLI is not required for MCP. Use it for shell scripting and export.

```bash
npm install -g @hackmd/hackmd-cli
```

### 4. Configure HackMD CLI authentication

Use either interactive login:

```bash
hackmd-cli login
```

or an environment variable:

```bash
export HMD_API_ACCESS_TOKEN=YOUR_TOKEN
hackmd-cli whoami
```

For HackMD EE instances, also set:
Expand All @@ -137,40 +111,42 @@ For HackMD EE instances, also set:
export HMD_API_ENDPOINT_URL=https://your.hackmd-ee.endpoint
```

### 5. Verify CLI and MCP access
### 4. Verify

In Cursor, confirm the `hackmd` MCP server appears and a tool call succeeds after OAuth.

If you installed the CLI:

```bash
hackmd-cli whoami
hackmd-cli notes
```

In Cursor, confirm the `hackmd-mcp` server appears from your user MCP configuration.

## Included Components

### Skill: `hackmd-cli`

Use this when working with HackMD notes via CLI, including personal notes, team notes, exports, and scripting workflows.
Use this when working with HackMD notes via CLI, including personal notes, team notes, exports, and scripting workflows. MCP OAuth does not replace CLI login.

### Command: `setup-hackmd`

Use this command to guide users through:

- installing the HackMD CLI
- configuring authentication
- copying the MCP template into user-local Cursor config
- verifying CLI and MCP access
- installing the plugin
- connecting MCP with OAuth
- optionally installing and logging in to the HackMD CLI
- verifying MCP (and CLI, if installed)

### Rule: `hackmd-workflow`

Use this rule for HackMD-related work so Cursor prefers the HackMD CLI workflow, distinguishes personal notes from team notes, and keeps auth placeholders out of committed examples.
Use this rule for HackMD-related work so Cursor prefers MCP OAuth for chat-native notes, uses the CLI only for shell workflows, and never copies a CLI token into MCP config.

## Notes

- The plugin manifest references the local `logo.png` asset.
- The repo `.mcp.json` is a template with `${env:HMD_API_ACCESS_TOKEN}` interpolation and a pinned `mcp-remote` version.
- Keep tokens in the environment, not in committed or pasted config files.
- The repo `.mcp.json` is URL-only: `https://mcp.hackmd.io/`.
- The plugin keeps scope narrow so it can be extended safely later.
- The `hackmd-cli` skill adapts the upstream HackMD CLI guide for Cursor plugin packaging.

Upstream reference: [HackMD CLI skill](https://github.com/hackmdio/hackmd-cli/blob/develop/hackmd-cli/SKILL.md)
Setup guide: [HackMD MCP Server Setup](https://hackmd.io/@docs/mcp-server-setup)

Upstream CLI skill: [HackMD CLI skill](https://github.com/hackmdio/hackmd-cli/blob/develop/hackmd-cli/SKILL.md)
63 changes: 17 additions & 46 deletions commands/setup-hackmd.md
Original file line number Diff line number Diff line change
@@ -1,70 +1,41 @@
---
name: setup-hackmd
description: Guide HackMD plugin setup, including CLI install, auth configuration, safe local MCP setup, and basic verification.
description: Guide HackMD plugin setup, including OAuth MCP, optional CLI install, and basic verification.
---

# Setup HackMD

Help the user set up HackMD tooling in Cursor using this sequence:
Help the user set up HackMD tooling in Cursor using this sequence.

1. Confirm whether they need HackMD Cloud or HackMD EE setup.
1. Install the CLI if needed:
The MCP server (`mcp.hackmd.io`) authenticates with **OAuth 2.1**. The CLI continues to use interactive login or a personal API token. The two are independent — connecting MCP does not replace CLI credentials.

```bash
npm install -g @hackmd/hackmd-cli
```

1. Configure CLI auth with either:

```bash
hackmd-cli login
```

or:

```bash
export HMD_API_ACCESS_TOKEN=YOUR_TOKEN
```

1. If they use HackMD EE, also configure:

```bash
export HMD_API_ENDPOINT_URL=https://your.hackmd-ee.endpoint
```

1. Copy the `hackmd-mcp` entry from the plugin `.mcp.json` into the user's local Cursor MCP config at `~/.cursor/mcp.json`.
1. Use a local config shaped like this (no token in the file; Cursor resolves `${env:HMD_API_ACCESS_TOKEN}`):
1. Confirm they have a HackMD account at [hackmd.io](https://hackmd.io).
2. Confirm the plugin is installed (this repo, or synced to `~/.cursor/plugins/local/hackmd/`).
3. Merge the plugin `.mcp.json` into the user's Cursor MCP config at `~/.cursor/mcp.json` (or confirm Cursor already loaded the plugin's MCP entry):

```json
{
"mcpServers": {
"hackmd-mcp": {
"command": "npx",
"args": [
"mcp-remote@0.1.38",
"https://mcp.hackmd.io/",
"--header",
"Authorization:Bearer ${env:HMD_API_ACCESS_TOKEN}"
]
"hackmd": {
"url": "https://mcp.hackmd.io/"
}
}
}
```

1. Ensure `HMD_API_ACCESS_TOKEN` is set in the environment Cursor uses (same as CLI), not inside `mcp.json`. Prefer a shell profile or OS user environment so Cursor inherits the variable on launch; `${env:...}` in `mcp.json` only references that external value.
Do **not** add `mcp-remote`, `Authorization` headers, or API tokens to this MCP config. MCP does not use `HMD_API_ACCESS_TOKEN`.

1. Verify CLI access:
4. Fully quit and reopen Cursor (a window reload is not enough).
5. Ask Cursor to list HackMD notes (or call any HackMD MCP tool). Complete the browser OAuth prompt. Closing it leaves the client unauthorized.
6. Optional: install the CLI for shell workflows (not required for MCP):

```bash
npm install -g @hackmd/hackmd-cli
hackmd-cli login
hackmd-cli whoami
hackmd-cli notes
```

1. Verify the MCP setup by confirming Cursor can see the configured `hackmd-mcp` server from the user's local MCP configuration.
1. If the user is scripting or automating content:

- use `hackmd-cli notes` for personal notes
- use `hackmd-cli team-notes` for team content
- use JSON output for automation
`hackmd-cli login` is enough for most people. An API token is only for CLI/REST, never for MCP.

1. Never paste real secrets into docs, examples, commits, screenshots, or tracked plugin files.
7. Verify MCP: the `hackmd` server appears in Cursor's MCP list, and a tool call succeeds after OAuth.
8. Never paste real secrets into docs, examples, commits, screenshots, or tracked plugin files.
17 changes: 9 additions & 8 deletions rules/hackmd-workflow.mdc
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
---
description: Prefer HackMD CLI and safe auth handling for HackMD-related note workflows.
description: Prefer HackMD MCP OAuth for chat-native note work; keep CLI credentials off the MCP path.
alwaysApply: false
---

# HackMD workflow

When helping with HackMD tasks:

1. Prefer the `hackmd-cli` skill for creating, updating, exporting, and automating notes.
2. Distinguish personal notes (`hackmd-cli notes`) from team notes (`hackmd-cli team-notes --teamPath=...`).
3. Recommend `hackmd-cli login` or environment variables instead of embedding secrets directly in commands.
4. Keep token examples as placeholders in docs and configuration samples.
5. When scripting or inspection is needed, prefer machine-readable output such as `--output=json`.
6. **Verify login before API-backed CLI work** (listing or mutating notes, teams, history, export): run `hackmd-cli whoami`. If it errors or shows no user, have the user run `hackmd-cli login` or set `HMD_API_ACCESS_TOKEN` (and `HMD_API_ENDPOINT_URL` for HackMD EE), then re-run `whoami`.
7. **Optional `whoami` output tuning** (same table-style flags as other list commands): `--output=json|yaml|csv` for parsing; `-x` / `--extended` for extra columns; `--columns=...`, `--filter=...`, `--sort=...`, `--no-header`, `--no-truncate` as needed.
1. Prefer HackMD MCP (`https://mcp.hackmd.io/`) for reading and writing notes inside Cursor. Auth is OAuth in the browser — do not ask the user for an API token to connect MCP, and do not add `mcp-remote` or `Authorization: Bearer` to MCP config.
2. Prefer the `hackmd-cli` skill only for shell scripting, export, or EE endpoint work that MCP does not cover.
3. Distinguish personal notes from team notes (MCP team tools, or `hackmd-cli team-notes --teamPath=...`).
4. CLI credentials (`hackmd-cli login` or `HMD_API_ACCESS_TOKEN`) are independent of MCP OAuth. Do not copy a CLI token into `.mcp.json`.
5. Keep any CLI token examples as placeholders. Never commit real secrets.
6. When scripting the CLI, prefer machine-readable output such as `--output=json`.
7. **Verify MCP before chat-native note work:** the `hackmd` server should be present and OAuth completed. If tools return unauthorized, re-run the browser OAuth flow — do not fall back to pasting an API token into MCP config.
8. **Verify CLI before API-backed CLI work:** run `hackmd-cli whoami`. If it errors, have the user run `hackmd-cli login` (or set `HMD_API_ACCESS_TOKEN` and, for HackMD EE, `HMD_API_ENDPOINT_URL`), then re-run `whoami`.
2 changes: 1 addition & 1 deletion skills/hackmd-cli/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: Use HackMD CLI to create, read, update, delete, export, and automat

# HackMD CLI

Use this skill when a user wants to manage HackMD content programmatically from Cursor.
Use this skill when a user wants to manage HackMD content from the **CLI** (shell, scripts, export). Chat-native read/write in Cursor should use HackMD MCP at `https://mcp.hackmd.io/` with **OAuth** — not this token, and not `mcp-remote`.

## What This Skill Covers

Expand Down