@dalcontak/blogger-mcp-server 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/publish.yml +3 -0
- package/AGENTS.md +2 -2
- package/README.md +201 -100
- package/RELEASE.md +64 -32
- package/dist/bloggerService.d.ts +7 -100
- package/dist/bloggerService.js +17 -146
- package/dist/config.d.ts +3 -0
- package/dist/config.js +12 -12
- package/dist/index.js +80 -154
- package/dist/server.d.ts +0 -11
- package/dist/server.js +59 -339
- package/dist/types.d.ts +15 -44
- package/dist/ui-manager.js +8 -16
- package/package.json +5 -1
- package/src/bloggerService.test.ts +5 -1
- package/src/bloggerService.ts +26 -161
- package/src/config.test.ts +34 -20
- package/src/config.ts +17 -16
- package/src/index.ts +115 -194
- package/src/server.test.ts +128 -0
- package/src/server.ts +63 -332
- package/src/types.ts +12 -60
- package/src/ui-manager.ts +17 -26
- package/Dockerfile +0 -64
- package/dist/mcp-sdk-mock.d.ts +0 -57
- package/dist/mcp-sdk-mock.js +0 -227
package/AGENTS.md
CHANGED
|
@@ -6,7 +6,7 @@ MCP (Model Context Protocol) server for Google's Blogger API. Allows AI models t
|
|
|
6
6
|
interact with Blogger blogs via stdio or HTTP transport. Includes an optional web dashboard
|
|
7
7
|
(Express + Socket.IO) on a separate port when `UI_PORT` is set. Written in TypeScript, targeting Node.js 20.
|
|
8
8
|
|
|
9
|
-
Package: `@
|
|
9
|
+
Package: `@dalcontak/blogger-mcp-server` (v1.0.4)
|
|
10
10
|
|
|
11
11
|
## Build / Run / Test Commands
|
|
12
12
|
|
|
@@ -47,6 +47,7 @@ src/
|
|
|
47
47
|
config.ts # Environment-based configuration object
|
|
48
48
|
types.ts # Shared interfaces and type definitions
|
|
49
49
|
ui-manager.ts # Express + Socket.IO web dashboard
|
|
50
|
+
*.test.ts # Unit tests (Jest) alongside source files
|
|
50
51
|
public/ # Static web UI assets (HTML/JS/CSS)
|
|
51
52
|
dist/ # Compiled output (committed to repo)
|
|
52
53
|
```
|
|
@@ -146,7 +147,6 @@ dist/ # Compiled output (committed to repo)
|
|
|
146
147
|
## Known Issues / Gotchas
|
|
147
148
|
|
|
148
149
|
- `dist/` directory is committed to the repo -- rebuild before committing if you change source
|
|
149
|
-
- README.md has an unresolved merge conflict marker at line 171
|
|
150
150
|
- HTTP mode in `index.ts` has a manual tool-routing switch that duplicates `server.ts` logic
|
|
151
151
|
|
|
152
152
|
## Deployment
|
package/README.md
CHANGED
|
@@ -1,169 +1,270 @@
|
|
|
1
|
-
#
|
|
2
|
-
=======
|
|
3
|
-
# Serveur MCP pour Blogger
|
|
1
|
+
# Blogger MCP Server
|
|
4
2
|
|
|
5
|
-
|
|
3
|
+
MCP (Model Context Protocol) server for Google's Blogger API. Allows AI models like Claude to interact with Blogger blogs.
|
|
6
4
|
|
|
7
|
-
##
|
|
5
|
+
## Features
|
|
8
6
|
|
|
9
|
-
|
|
7
|
+
- **List and retrieve blogs** — Get blog details by ID or URL
|
|
8
|
+
- **Posts management** — List, search, retrieve, create, update, delete posts
|
|
9
|
+
- **Labels management** — List and retrieve labels
|
|
10
|
+
- **Dual authentication**:
|
|
11
|
+
- **API Key** (read-only) — Access public blogs
|
|
12
|
+
- **OAuth2** (full access) — Create, update, delete posts, list your blogs
|
|
13
|
+
- **Native search** — Uses Blogger's `posts/search` endpoint (not client-side filtering)
|
|
14
|
+
- **Blog discovery** — `get_blog_by_url` tool to find blog ID from URL
|
|
15
|
+
- **Optional Web UI** — Express + Socket.IO dashboard (enable with `UI_PORT`)
|
|
10
16
|
|
|
11
|
-
|
|
12
|
-
* Lister, rechercher, récupérer, créer, mettre à jour et supprimer des posts
|
|
13
|
-
* Lister et récupérer des labels
|
|
14
|
-
|
|
15
|
-
> **Note importante** : L'API Blogger de Google ne permet pas de créer de nouveaux blogs via API. Cette limitation est documentée par Google. Les blogs doivent être créés manuellement via l'interface web de Blogger.
|
|
16
|
-
|
|
17
|
-
## Prérequis
|
|
18
|
-
|
|
19
|
-
* Node.js (version 16 ou supérieure)
|
|
20
|
-
* Une clé API Blogger de Google
|
|
17
|
+
> **Note:** The Blogger API does not allow creating new blogs. Blogs must be created manually via the Blogger web interface.
|
|
21
18
|
|
|
22
19
|
## Installation
|
|
23
20
|
|
|
24
|
-
###
|
|
21
|
+
### From npm
|
|
25
22
|
|
|
26
23
|
```bash
|
|
27
|
-
npm install -g @
|
|
24
|
+
npm install -g @dalcontak/blogger-mcp-server
|
|
28
25
|
```
|
|
29
26
|
|
|
30
|
-
###
|
|
27
|
+
### From source
|
|
31
28
|
|
|
32
29
|
```bash
|
|
33
|
-
git clone https://github.com/
|
|
30
|
+
git clone https://github.com/dalcontak/blogger-mcp-server.git
|
|
34
31
|
cd blogger-mcp-server
|
|
35
32
|
npm install
|
|
36
33
|
npm run build
|
|
37
34
|
```
|
|
38
|
-
if error install :
|
|
39
35
|
|
|
40
|
-
|
|
41
|
-
|
|
36
|
+
## Authentication
|
|
37
|
+
|
|
38
|
+
### Option 1: API Key (Read-only)
|
|
39
|
+
|
|
40
|
+
Access public blogs only. Useful if you only need to read data.
|
|
41
|
+
|
|
42
|
+
1. Go to [Google Cloud Console](https://console.cloud.google.com/)
|
|
43
|
+
2. Create/select a project, then enable the **Blogger API v3**.
|
|
44
|
+
3. Create an **API Key** under Credentials.
|
|
45
|
+
4. Set the environment variable: `export BLOGGER_API_KEY=your_api_key_here`
|
|
46
|
+
|
|
47
|
+
### Option 2: OAuth2 (Full Access)
|
|
48
|
+
|
|
49
|
+
Required to create, update, delete posts, and list your own blogs.
|
|
50
|
+
|
|
51
|
+
**Need a step-by-step visual guide?**
|
|
52
|
+
🔗 [**Read the complete tutorial on setting up OAuth2 for Blogger MCP here**](https://dalcontk.blogspot.com/2026/03/guia-paso-paso-como-configurar.html)
|
|
53
|
+
*(Note: This guide is written in Spanish. Feel free to use Google Translate if you need it in another language).*
|
|
54
|
+
|
|
55
|
+
**Step 1: Configure OAuth Consent**
|
|
56
|
+
1. In [Google Cloud Console](https://console.cloud.google.com/), go to **Google Auth Platform** > **Overview**.
|
|
57
|
+
2. Under **Audience**, add your Google account as a Test User.
|
|
58
|
+
3. Under **Data Access** (Scopes), add: `https://www.googleapis.com/auth/blogger`
|
|
59
|
+
|
|
60
|
+
**Step 2: Create Web Credentials**
|
|
61
|
+
1. Go to **Credentials** > **Create Credentials** > **OAuth client ID**.
|
|
62
|
+
2. Application type: Select **Web application** *(do not use Desktop app)*.
|
|
63
|
+
3. Name: Your app name.
|
|
64
|
+
4. Authorized redirect URIs: Add exactly `https://developers.google.com/oauthplayground`
|
|
65
|
+
5. Click Create and copy your **Client ID** and **Client Secret**.
|
|
66
|
+
|
|
67
|
+
**Step 3: Get a Refresh Token**
|
|
68
|
+
1. Go to the [Google OAuth 2.0 Playground](https://developers.google.com/oauthplayground/).
|
|
69
|
+
2. Click the **Gear icon** (top right) ⚙️ > check **Use your own OAuth credentials**.
|
|
70
|
+
3. Paste your **Client ID** and **Client Secret**, then close the settings panel.
|
|
71
|
+
4. In Step 1 (left panel), scroll to **Blogger API v3**, select `https://www.googleapis.com/auth/blogger`, and click **Authorize APIs**.
|
|
72
|
+
5. Log in with your test Google account and grant permissions.
|
|
73
|
+
6. In Step 2, click **Exchange authorization code for tokens**.
|
|
74
|
+
7. Copy the generated **Refresh token**.
|
|
75
|
+
|
|
76
|
+
**Step 4: Set Environment Variables**
|
|
77
|
+
Configure your MCP client (like Claude Desktop or OpenCode) with:
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
"env": {
|
|
81
|
+
"GOOGLE_CLIENT_ID": "your_client_id_here",
|
|
82
|
+
"GOOGLE_CLIENT_SECRET": "your_client_secret_here",
|
|
83
|
+
"GOOGLE_REFRESH_TOKEN": "1//your_refresh_token_here"
|
|
84
|
+
}
|
|
42
85
|
```
|
|
43
|
-
## Configuration
|
|
44
86
|
|
|
45
|
-
|
|
87
|
+
> **Note:** If both API Key and OAuth2 are configured, OAuth2 is used.
|
|
88
|
+
|
|
89
|
+
## Usage
|
|
90
|
+
|
|
91
|
+
### Local Development
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
# Using npm package
|
|
95
|
+
npm start
|
|
96
|
+
|
|
97
|
+
# Or from source (after build)
|
|
98
|
+
node dist/index.js
|
|
46
99
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
4. Créez une clé API
|
|
51
|
-
5. Notez cette clé pour l'utiliser dans la configuration
|
|
100
|
+
# Development mode with ts-node
|
|
101
|
+
npm run dev
|
|
102
|
+
```
|
|
52
103
|
|
|
53
|
-
###
|
|
104
|
+
### With MCP Client (Claude Desktop)
|
|
54
105
|
|
|
55
|
-
|
|
106
|
+
Create or edit your Claude Desktop config file:
|
|
107
|
+
|
|
108
|
+
**Linux:** `~/.config/Claude/claude_desktop_config.json`
|
|
109
|
+
**macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
110
|
+
**Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
|
|
56
111
|
|
|
57
112
|
```json
|
|
58
113
|
{
|
|
59
114
|
"mcpServers": {
|
|
60
115
|
"blogger": {
|
|
61
|
-
"command": "
|
|
62
|
-
"args": [
|
|
63
|
-
"-y",
|
|
64
|
-
"@mcproadev/blogger-mcp-server"
|
|
65
|
-
],
|
|
116
|
+
"command": "node",
|
|
117
|
+
"args": ["./dist/index.js"],
|
|
66
118
|
"env": {
|
|
67
|
-
"BLOGGER_API_KEY": "
|
|
119
|
+
"BLOGGER_API_KEY": "your_api_key_here"
|
|
68
120
|
}
|
|
69
121
|
}
|
|
70
122
|
}
|
|
71
123
|
}
|
|
72
124
|
```
|
|
73
125
|
|
|
74
|
-
|
|
126
|
+
Replace `/home/dalcon/dev/ai/blogger-mcp-server/dist/index.js` with your actual path, and set your API key or OAuth2 credentials.
|
|
127
|
+
|
|
128
|
+
### Example Commands
|
|
75
129
|
|
|
76
|
-
|
|
130
|
+
```json
|
|
131
|
+
// List all your blogs (requires OAuth2)
|
|
132
|
+
{"tool": "list_blogs", "params": {}}
|
|
77
133
|
|
|
78
|
-
|
|
134
|
+
// Get blog details by ID
|
|
135
|
+
{"tool": "get_blog", "params": {"blogId": "123456789"}}
|
|
79
136
|
|
|
80
|
-
|
|
137
|
+
// Find blog ID from URL (useful when you don't know the ID)
|
|
138
|
+
{"tool": "get_blog_by_url", "params": {"url": "https://yourblog.blogspot.com"}}
|
|
81
139
|
|
|
82
|
-
|
|
140
|
+
// List posts
|
|
141
|
+
{"tool": "list_posts", "params": {"blogId": "123456789", "maxResults": 10}}
|
|
83
142
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
./start-dev.sh
|
|
87
|
-
```
|
|
143
|
+
// Search posts
|
|
144
|
+
{"tool": "search_posts", "params": {"blogId": "123456789", "query": "technology"}}
|
|
88
145
|
|
|
89
|
-
|
|
146
|
+
// Create a new post (requires OAuth2)
|
|
147
|
+
{"tool": "create_post", "params": {"blogId": "123456789", "title": "My Post", "content": "Content here", "labels": ["tech", "nodejs"]}}
|
|
90
148
|
|
|
91
|
-
|
|
149
|
+
// Update a post (requires OAuth2)
|
|
150
|
+
{"tool": "update_post", "params": {"blogId": "123456789", "postId": "789012", "title": "Updated Title"}}
|
|
92
151
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
152
|
+
// Delete a post (requires OAuth2)
|
|
153
|
+
{"tool": "delete_post", "params": {"blogId": "123456789", "postId": "789012"}}
|
|
154
|
+
|
|
155
|
+
// List labels
|
|
156
|
+
{"tool": "list_labels", "params": {"blogId": "123456789"}}
|
|
157
|
+
|
|
158
|
+
// Get label details
|
|
159
|
+
{"tool": "get_label", "params": {"blogId": "123456789", "labelName": "technology"}}
|
|
97
160
|
```
|
|
98
161
|
|
|
99
|
-
|
|
162
|
+
## Available Tools
|
|
163
|
+
|
|
164
|
+
| Tool | Description | Auth Required |
|
|
165
|
+
|-------|-------------|---------------|
|
|
166
|
+
| `list_blogs` | Lists all your blogs | OAuth2 |
|
|
167
|
+
| `get_blog` | Retrieves blog details by ID | None |
|
|
168
|
+
| `get_blog_by_url` | Finds blog ID from URL | None |
|
|
169
|
+
| `list_posts` | Lists posts from a blog | None |
|
|
170
|
+
| `search_posts` | Searches posts (uses native API) | None |
|
|
171
|
+
| `get_post` | Retrieves post details | None |
|
|
172
|
+
| `create_post` | Creates a new post | OAuth2 |
|
|
173
|
+
| `update_post` | Updates an existing post | OAuth2 |
|
|
174
|
+
| `delete_post` | Deletes a post | OAuth2 |
|
|
175
|
+
| `list_labels` | Lists all labels from a blog | None |
|
|
176
|
+
| `get_label` | Retrieves label details | None |
|
|
177
|
+
|
|
178
|
+
## Environment Variables
|
|
179
|
+
|
|
180
|
+
| Variable | Default | Description |
|
|
181
|
+
|----------|---------|-------------|
|
|
182
|
+
| `BLOGGER_API_KEY` | (optional) | Google Blogger API key (read-only) |
|
|
183
|
+
| `GOOGLE_CLIENT_ID` | (optional) | OAuth2 client ID (for full access) |
|
|
184
|
+
| `GOOGLE_CLIENT_SECRET` | (optional) | OAuth2 client secret |
|
|
185
|
+
| `GOOGLE_REFRESH_TOKEN` | (optional) | OAuth2 refresh token |
|
|
186
|
+
| `MCP_MODE` | `stdio` | Transport: `stdio` or `http` |
|
|
187
|
+
| `MCP_HTTP_HOST` | `0.0.0.0` | HTTP host (HTTP mode) |
|
|
188
|
+
| `MCP_HTTP_PORT` | `3000` | HTTP port (HTTP mode) |
|
|
189
|
+
| `BLOGGER_MAX_RESULTS` | `10` | Max results per query |
|
|
190
|
+
| `BLOGGER_API_TIMEOUT` | `30000` | API timeout (ms) |
|
|
191
|
+
| `LOG_LEVEL` | `info` | Logging level |
|
|
192
|
+
| `UI_PORT` | (disabled) | Web UI port (set to enable) |
|
|
193
|
+
|
|
194
|
+
**At least one auth method is required** — Either API key OR OAuth2 credentials.
|
|
195
|
+
|
|
196
|
+
## Project Structure
|
|
100
197
|
|
|
101
|
-
|
|
198
|
+
```
|
|
199
|
+
src/
|
|
200
|
+
index.ts # Entry point, main() function, HTTP mode routing
|
|
201
|
+
server.ts # MCP server tool registration (initMCPServer)
|
|
202
|
+
bloggerService.ts # Google Blogger API wrapper (BloggerService class)
|
|
203
|
+
config.ts # Environment-based configuration object
|
|
204
|
+
types.ts # Shared interfaces and type definitions
|
|
205
|
+
ui-manager.ts # Express + Socket.IO web dashboard
|
|
206
|
+
*.test.ts # Unit tests (Jest) alongside source files
|
|
207
|
+
.github/workflows/ # GitHub Actions CI/CD
|
|
208
|
+
public/ # Static web UI assets (HTML/JS/CSS)
|
|
209
|
+
dist/ # Compiled output
|
|
210
|
+
```
|
|
102
211
|
|
|
103
|
-
|
|
212
|
+
## Development
|
|
104
213
|
|
|
105
|
-
|
|
214
|
+
```bash
|
|
215
|
+
# Install dependencies
|
|
216
|
+
npm install
|
|
106
217
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
* "Recherche des posts contenant le mot 'technologie' dans mon blog"
|
|
110
|
-
* "Mets à jour le post avec l'ID 789012 pour changer son titre en 'Nouveau titre'"
|
|
218
|
+
# Run development (stdio mode, auto-compiles with ts-node)
|
|
219
|
+
npm run dev
|
|
111
220
|
|
|
112
|
-
|
|
221
|
+
# Run in HTTP mode (useful for manual testing with curl)
|
|
222
|
+
MCP_MODE=http BLOGGER_API_KEY=your_key npm run dev
|
|
113
223
|
|
|
114
|
-
|
|
224
|
+
# Run tests
|
|
225
|
+
npm test
|
|
115
226
|
|
|
116
|
-
|
|
227
|
+
# Build for production
|
|
228
|
+
npm run build
|
|
229
|
+
```
|
|
117
230
|
|
|
118
|
-
|
|
119
|
-
2. Installez l'outil CLI Vercel : `npm install -g vercel`
|
|
120
|
-
3. Connectez-vous à votre compte Vercel : `vercel login`
|
|
121
|
-
4. Configurez votre variable d'environnement secrète : `vercel secrets add blogger_api_key "VOTRE_CLE_API_ICI"`
|
|
122
|
-
5. Déployez le projet : `vercel`
|
|
231
|
+
## Deployment
|
|
123
232
|
|
|
124
|
-
###
|
|
233
|
+
### Vercel
|
|
125
234
|
|
|
126
|
-
|
|
235
|
+
The project includes `vercel.json` for Vercel deployment:
|
|
127
236
|
|
|
128
|
-
1.
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
```
|
|
237
|
+
1. Install Vercel CLI: `npm install -g vercel`
|
|
238
|
+
2. Login: `vercel login`
|
|
239
|
+
3. Deploy: `vercel`
|
|
132
240
|
|
|
133
|
-
|
|
134
|
-
```bash
|
|
135
|
-
docker run -p 3000:3000 -e BLOGGER_API_KEY=votre_cle_api blogger-mcp-server
|
|
136
|
-
```
|
|
241
|
+
### Docker
|
|
137
242
|
|
|
138
|
-
|
|
243
|
+
Build and run:
|
|
139
244
|
|
|
140
|
-
|
|
245
|
+
```bash
|
|
246
|
+
docker build -t blogger-mcp-server .
|
|
247
|
+
docker run -p 3000:3000 -e BLOGGER_API_KEY=your_key blogger-mcp-server
|
|
248
|
+
```
|
|
141
249
|
|
|
142
|
-
|
|
143
|
-
2. **AWS Lambda** : Utilisez un adaptateur comme Serverless Framework
|
|
144
|
-
3. **Google Cloud Run** : Utilisez le Dockerfile inclus
|
|
250
|
+
### Other Platforms
|
|
145
251
|
|
|
146
|
-
|
|
252
|
+
The server can be deployed to any Node.js-compatible platform (Heroku, AWS Lambda, Google Cloud Run, etc.).
|
|
147
253
|
|
|
148
|
-
|
|
254
|
+
## Release Process
|
|
149
255
|
|
|
150
|
-
|
|
151
|
-
* `server.ts` : Configuration du serveur MCP
|
|
152
|
-
* `bloggerService.ts` : Service d'interaction avec l'API Blogger
|
|
153
|
-
* `config.ts` : Configuration du serveur
|
|
154
|
-
* `types.ts` : Définition des types et interfaces
|
|
256
|
+
For publishing new versions to npm, see [RELEASE.md](./RELEASE.md).
|
|
155
257
|
|
|
156
|
-
##
|
|
258
|
+
## Contributing
|
|
157
259
|
|
|
158
|
-
|
|
159
|
-
* **Recherche de posts** : La recherche utilise l'endpoint natif `posts/search?q=` de l'API Blogger v3.
|
|
160
|
-
* **Gestion des labels** : L'API Blogger ne fournit pas d'endpoints directs pour la gestion des labels. Cette fonctionnalité est implémentée en extrayant les labels des posts.
|
|
161
|
-
* **Authentification** : Le serveur supporte l'authentification par clé API (lecture seule, blogs publics) et OAuth2 (accès complet en lecture/écriture). OAuth2 est requis pour `list_blogs`, `create_post`, `update_post`, `delete_post`.
|
|
260
|
+
Contributions are welcome! Feel free to open an issue or pull request.
|
|
162
261
|
|
|
163
|
-
##
|
|
262
|
+
## License
|
|
164
263
|
|
|
165
|
-
|
|
264
|
+
MIT
|
|
166
265
|
|
|
167
|
-
##
|
|
266
|
+
## Acknowledgments
|
|
168
267
|
|
|
169
|
-
|
|
268
|
+
- Built with [TypeScript](https://www.typescriptlang.org/)
|
|
269
|
+
- Uses [googleapis](https://github.com/googleapis/google-api-nodejs-client) for Google APIs
|
|
270
|
+
- MCP SDK by [Model Context Protocol](https://modelcontextprotocol.io/)
|
package/RELEASE.md
CHANGED
|
@@ -4,28 +4,55 @@ This document explains how to create releases and publish to npm.
|
|
|
4
4
|
|
|
5
5
|
## Prerequisites
|
|
6
6
|
|
|
7
|
-
### Setup Trusted Publishing (
|
|
7
|
+
### Setup GitHub Actions Token + Trusted Publishing (Provenance)
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
We use a **hybrid approach** combining a classic automation token for authentication with OIDC (OpenID Connect) for cryptographic provenance signing.
|
|
10
10
|
|
|
11
|
-
#### Step 1:
|
|
11
|
+
#### Step 1: Create Fine-grained Automation Token
|
|
12
|
+
|
|
13
|
+
1. Log in to npm: `npm login`
|
|
14
|
+
2. Generate an automation token (90-day lifetime):
|
|
15
|
+
```bash
|
|
16
|
+
npm token create --name="github-actions" --scopes="dalcontak" --packages-and-scopes-permission="read-write" --bypass-2fa=true
|
|
17
|
+
```
|
|
18
|
+
3. Copy the token (starts with `npm_`)
|
|
19
|
+
|
|
20
|
+
#### Step 2: Add Token to GitHub Secrets
|
|
21
|
+
|
|
22
|
+
1. Go to your repository: https://github.com/dalcontak/blogger-mcp-server
|
|
23
|
+
2. Navigate to **Settings** > **Secrets and variables** > **Actions**
|
|
24
|
+
3. Click **"New repository secret"**
|
|
25
|
+
4. Name: `NPM_TOKEN`
|
|
26
|
+
5. Value: Paste the token from Step 1
|
|
27
|
+
6. Click **"Add secret"**
|
|
28
|
+
|
|
29
|
+
#### Step 3: Configure npm Package Settings for Automation Tokens
|
|
30
|
+
|
|
31
|
+
1. Go to https://www.npmjs.com/package/@dalcontak/blogger-mcp-server
|
|
32
|
+
2. Click on **"Settings"** tab
|
|
33
|
+
3. In **Publishing access**, change to: **"Require two-factor authentication or a token"** (or similar option that allows automation tokens)
|
|
34
|
+
4. Save the change
|
|
35
|
+
|
|
36
|
+
⚠️ **Important:** If set to "Require 2FA" (without "or a token"), automation tokens will be rejected with error 403.
|
|
37
|
+
|
|
38
|
+
#### Step 4: Configure GitHub Actions as Trusted Publisher (for Provenance)
|
|
39
|
+
|
|
40
|
+
This enables cryptographic signing of published packages (npm provenance).
|
|
12
41
|
|
|
13
|
-
The correct navigation is:
|
|
14
42
|
1. Go to https://www.npmjs.com/package/@dalcontak/blogger-mcp-server
|
|
15
43
|
2. Click on **"Settings"** tab
|
|
16
44
|
3. Find the **"Trusted Publishers"** section
|
|
17
|
-
4. Click on **"
|
|
45
|
+
4. Click on **"Set up connection"**
|
|
18
46
|
5. Fill in:
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
47
|
+
- **Organization or user**: `dalcontak`
|
|
48
|
+
- **Repository**: `dalcontak/blogger-mcp-server`
|
|
49
|
+
- **Workflow filename**: `publish.yml`
|
|
22
50
|
6. Click **"Set up connection"**
|
|
23
51
|
|
|
24
|
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
|
|
28
|
-
That's it! No token needed — OIDC generates short-lived, job-specific credentials automatically.
|
|
52
|
+
That's it! The workflow will now:
|
|
53
|
+
- Authenticate with your `NPM_TOKEN` secret
|
|
54
|
+
- Sign packages with GitHub Actions provenance
|
|
55
|
+
- Publish to npm securely
|
|
29
56
|
|
|
30
57
|
## Version Naming
|
|
31
58
|
|
|
@@ -76,7 +103,7 @@ GitHub Actions will automatically:
|
|
|
76
103
|
3. ✅ Install dependencies
|
|
77
104
|
4. ✅ Run tests (npm test)
|
|
78
105
|
5. ✅ Build (npm run build)
|
|
79
|
-
6. ✅ Publish to npm using
|
|
106
|
+
6. ✅ Publish to npm using `NPM_TOKEN` + provenance signing
|
|
80
107
|
|
|
81
108
|
The workflow triggers on any push to branches matching `release/**`.
|
|
82
109
|
|
|
@@ -97,29 +124,34 @@ npm install @dalcontak/blogger-mcp-server
|
|
|
97
124
|
- The branch name **must** contain version after "release-" (e.g., `release-1.1.7`)
|
|
98
125
|
- Version format: **3 digits separated by dots** (X.Y.Z)
|
|
99
126
|
- Only pushes to `release/**` branches trigger the build/publish workflow
|
|
100
|
-
- **
|
|
101
|
-
-
|
|
127
|
+
- **NPM_TOKEN secret is required** in GitHub Actions for authentication (automation token)
|
|
128
|
+
- Token lifetime is 90 days maximum — remember to recreate and update secret before expiration
|
|
129
|
+
- Requires Node.js >= 20 (used in workflow)
|
|
102
130
|
|
|
103
131
|
## Troubleshooting
|
|
104
132
|
|
|
105
|
-
### Error: "
|
|
133
|
+
### Error: "Two-factor authentication is required but an automation token was specified"
|
|
134
|
+
|
|
135
|
+
**Solution:** Make sure npm package settings allow automation tokens:
|
|
136
|
+
1. Go to https://www.npmjs.com/package/@dalcontak/blogger-mcp-server > Settings
|
|
137
|
+
2. Change **Publishing access** to: "Require two-factor authentication or a token"
|
|
138
|
+
3. Save and try the workflow again
|
|
139
|
+
|
|
140
|
+
### Error: "E403: You cannot publish over previously published versions"
|
|
106
141
|
|
|
107
|
-
|
|
108
|
-
1. GitHub Actions is configured as **Trusted Publisher** in npm settings
|
|
109
|
-
2. Workflow filename matches: `publish.yml`
|
|
110
|
-
3. Repository is correct: `dalcontak/blogger-mcp-server`
|
|
111
|
-
4. Workflow has `permissions: id-token: write`
|
|
142
|
+
**Solution:** This is normal. You cannot republish an existing version. Bump the version in `package.json` and create a new release branch.
|
|
112
143
|
|
|
113
|
-
### Error: "
|
|
144
|
+
### Error: "E404: Package not in this registry"
|
|
114
145
|
|
|
115
|
-
|
|
146
|
+
**Solution:** Make sure `NPM_TOKEN` is set as a GitHub secret and that the token has write permissions for `@dalcontak` scope.
|
|
116
147
|
|
|
117
|
-
## Comparison:
|
|
148
|
+
## Comparison: Token vs OIDC (Provenance)
|
|
118
149
|
|
|
119
|
-
| Aspect |
|
|
120
|
-
|
|
121
|
-
| **
|
|
122
|
-
| **
|
|
123
|
-
| **
|
|
124
|
-
| **
|
|
125
|
-
| **
|
|
150
|
+
| Aspect | Fine-grained Token | OIDC (Provenance) | Our Hybrid Approach |
|
|
151
|
+
|---------|--------------------|---------------------|-------------------|
|
|
152
|
+
| **Purpose** | Authentication (publish permission) | Cryptographic signing (supply chain security) | Both combined |
|
|
153
|
+
| **Status** | ⚠️ Limited to 90 days | ✅ Standard feature | ✅ Best practice |
|
|
154
|
+
| **Rotation** | Manual (recreate every 90 days) | Automatic (job-specific) | Token manual, OIDC automatic |
|
|
155
|
+
| **Security** | Stored in GitHub secrets | Job-specific, short-lived | Multi-layer security |
|
|
156
|
+
| **GitHub Secret** | Required (NPM_TOKEN) | ❌ Not needed | Required (NPM_TOKEN) |
|
|
157
|
+
| **Setup** | Create via CLI, add to secret | Configure in npmjs.com | Both steps required |
|