{"_id":"@dalcontak/blogger-mcp-server","_rev":"4-7181d9542c5620560d952014fd833532","name":"@dalcontak/blogger-mcp-server","dist-tags":{"latest":"1.0.3"},"versions":{"1.0.0":{"name":"@dalcontak/blogger-mcp-server","version":"1.0.0","keywords":["mcp","blogger","api","claude","ai"],"author":"","license":"MIT","_id":"@dalcontak/blogger-mcp-server@1.0.0","maintainers":[{"name":"dalcontk","email":"dalcont112@yahoo.es"}],"dist":{"shasum":"5e8df0a30d36b97c16a7746e13d86e6faed4bbe6","tarball":"https://registry.npmjs.org/@dalcontak/blogger-mcp-server/-/blogger-mcp-server-1.0.0.tgz","fileCount":36,"integrity":"sha512-/y9lpaQbuaZ9p0bERr3EWWeFsrWRy/gXirz/B00tyRr8YzgKdJTy2vPxvk388OzPBcTPmPrzL6FVcrYLzijKTg==","signatures":[{"sig":"MEYCIQD2TONUBUrM1BNYPYfqoP6awAZhFrL0y3pInMsiXUZkKgIhALTyfd8zOFjGHVydXvb27bSlGF0cDobQSCdXoBifucCy","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":171561},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"e4265f43b486d564543a93217e818afd6f4a2878","private":false,"scripts":{"dev":"ts-node src/index.ts","lint":"eslint src/**/*.ts","test":"jest --forceExit","build":"tsc","start":"node dist/index.js"},"_npmUser":{"name":"dalcontk","email":"dalcont112@yahoo.es"},"_npmVersion":"11.9.0","description":"MCP Server for Blogger API","directories":{},"_nodeVersion":"25.6.1","dependencies":{"zod":"^3.22.4","express":"^4.21.0","socket.io":"^4.7.2","googleapis":"^171.4.0","@modelcontextprotocol/sdk":"^1.8.0"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^30.2.0","eslint":"^8.56.0","ts-jest":"^29.4.6","ts-node":"^10.9.2","typescript":"^5.3.3","@types/jest":"^30.0.0","@types/node":"^20.11.0","@types/express":"^5.0.1","@typescript-eslint/parser":"^6.19.0","@typescript-eslint/eslint-plugin":"^6.19.0"},"_npmOperationalInternal":{"tmp":"tmp/blogger-mcp-server_1.0.0_1771204153033_0.05912012832975533","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@dalcontak/blogger-mcp-server","version":"1.0.1","keywords":["mcp","blogger","api","claude","ai"],"author":"","license":"MIT","_id":"@dalcontak/blogger-mcp-server@1.0.1","maintainers":[{"name":"dalcontk","email":"dalcont112@yahoo.es"}],"homepage":"https://github.com/dalcontak/blogger-mcp-server#readme","bugs":{"url":"https://github.com/dalcontak/blogger-mcp-server/issues"},"dist":{"shasum":"7d3f6546f6fd8a3609fe7ff5b6f89ecf811f0496","tarball":"https://registry.npmjs.org/@dalcontak/blogger-mcp-server/-/blogger-mcp-server-1.0.1.tgz","fileCount":34,"integrity":"sha512-xH+jmmd8OaqMfy0qLFrXy92Xhl8lG72ukf6VHNQ3MulS+RX6EynCI5DWgBnAj9KFTv0fpV4zjYW12eDrG7apVw==","signatures":[{"sig":"MEUCIDZbP5FgoeGxXhyff6YptbYtuI2+A42USjiaYNHUlZZLAiEA0chegzRdmbH9alNFeWsM+S8z1hZviqa01XHsqynzl7o=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@dalcontak%2fblogger-mcp-server@1.0.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":164502},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"a41c2fe4bcf17182be197ad8a53db723f54f0c79","private":false,"scripts":{"dev":"ts-node src/index.ts","lint":"eslint src/**/*.ts","test":"jest --forceExit","build":"tsc","start":"node dist/index.js"},"_npmUser":{"name":"dalcontk","email":"dalcont112@yahoo.es"},"repository":{"url":"git+https://github.com/dalcontak/blogger-mcp-server.git","type":"git"},"_npmVersion":"10.8.2","description":"MCP Server for Blogger API","directories":{},"_nodeVersion":"20.20.0","dependencies":{"zod":"^3.22.4","express":"^4.21.0","socket.io":"^4.7.2","googleapis":"^171.4.0","@modelcontextprotocol/sdk":"^1.8.0"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^30.2.0","eslint":"^8.56.0","ts-jest":"^29.4.6","ts-node":"^10.9.2","typescript":"^5.3.3","@types/jest":"^30.0.0","@types/node":"^20.11.0","@types/express":"^5.0.1","@typescript-eslint/parser":"^6.19.0","@typescript-eslint/eslint-plugin":"^6.19.0"},"_npmOperationalInternal":{"tmp":"tmp/blogger-mcp-server_1.0.1_1772967480430_0.9061021724786018","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@dalcontak/blogger-mcp-server","version":"1.0.2","keywords":["mcp","blogger","api","claude","ai"],"author":"","license":"MIT","_id":"@dalcontak/blogger-mcp-server@1.0.2","maintainers":[{"name":"dalcontk","email":"dalcont112@yahoo.es"}],"homepage":"https://github.com/dalcontak/blogger-mcp-server#readme","bugs":{"url":"https://github.com/dalcontak/blogger-mcp-server/issues"},"dist":{"shasum":"5bca3390585e68b3d6615ad63781f383cdcbef85","tarball":"https://registry.npmjs.org/@dalcontak/blogger-mcp-server/-/blogger-mcp-server-1.0.2.tgz","fileCount":34,"integrity":"sha512-dXOFJ6nR9nmL6+VWbKIWVn48QczGd92tdU+qLSVYUBnN5CzuUihQ9VkD4T37d6+kRwC26KmCBvjXovctnE/IJg==","signatures":[{"sig":"MEUCIQDeAHyW/tK4lINmUHmSffvWbce6BxLtiBNXESk4TO1cBQIgclhBorf4NSTegdlJAM90dDLesuvmxoi1gvSKgogvpPI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@dalcontak%2fblogger-mcp-server@1.0.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":128675},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"f821abc0a703045b61730ad6324aff546c232375","private":false,"scripts":{"dev":"ts-node src/index.ts","lint":"eslint src/**/*.ts","test":"jest --forceExit","build":"tsc","start":"node dist/index.js"},"_npmUser":{"name":"dalcontk","email":"dalcont112@yahoo.es"},"repository":{"url":"git+https://github.com/dalcontak/blogger-mcp-server.git","type":"git"},"_npmVersion":"10.8.2","description":"MCP Server for Blogger API","directories":{},"_nodeVersion":"20.20.1","dependencies":{"zod":"^3.22.4","express":"^4.21.0","socket.io":"^4.7.2","googleapis":"^171.4.0","@modelcontextprotocol/sdk":"^1.8.0"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^30.2.0","eslint":"^8.56.0","ts-jest":"^29.4.6","ts-node":"^10.9.2","typescript":"^5.3.3","@types/jest":"^30.0.0","@types/node":"^20.11.0","@types/express":"^5.0.1","@typescript-eslint/parser":"^6.19.0","@typescript-eslint/eslint-plugin":"^6.19.0"},"_npmOperationalInternal":{"tmp":"tmp/blogger-mcp-server_1.0.2_1774750736758_0.5956994257835482","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"@dalcontak/blogger-mcp-server","version":"1.0.3","private":false,"description":"MCP Server for Blogger API","repository":{"type":"git","url":"git+https://github.com/dalcontak/blogger-mcp-server.git"},"main":"dist/index.js","types":"dist/index.d.ts","scripts":{"build":"tsc","start":"node dist/index.js","dev":"ts-node src/index.ts","test":"jest --forceExit","lint":"eslint src/**/*.ts"},"keywords":["mcp","blogger","api","claude","ai"],"author":"","license":"MIT","dependencies":{"@modelcontextprotocol/sdk":"^1.8.0","express":"^4.21.0","googleapis":"^171.4.0","socket.io":"^4.7.2","zod":"^3.22.4"},"devDependencies":{"@types/express":"^5.0.1","@types/jest":"^30.0.0","@types/node":"^20.11.0","@typescript-eslint/eslint-plugin":"^6.19.0","@typescript-eslint/parser":"^6.19.0","eslint":"^8.56.0","jest":"^30.2.0","ts-jest":"^29.4.6","ts-node":"^10.9.2","typescript":"^5.3.3"},"bin":{"blogger-mcp-server":"dist/index.js"},"_id":"@dalcontak/blogger-mcp-server@1.0.3","gitHead":"fa07e02bc089e8e50c4dfcab70661b04d0da38f8","bugs":{"url":"https://github.com/dalcontak/blogger-mcp-server/issues"},"homepage":"https://github.com/dalcontak/blogger-mcp-server#readme","_nodeVersion":"20.20.1","_npmVersion":"10.8.2","dist":{"integrity":"sha512-/l+KU3ldbbiGbJCd6pvN0cRixkEVLA8RNepYVqJcUg138c4PgjAyYS9nUhD52/+z4CEjqAbQuJTtIDeT43FXlg==","shasum":"37a5a1751cba22a9547e6d1a2d4bd789621f9632","tarball":"https://registry.npmjs.org/@dalcontak/blogger-mcp-server/-/blogger-mcp-server-1.0.3.tgz","fileCount":34,"unpackedSize":130003,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@dalcontak%2fblogger-mcp-server@1.0.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDzxGVrbkLTovjt4EPhiAjGhUfguHQQ1aiHj9/hUHqvBgIgFRM3KlH9fLXlR9+q6YLzPi0lv2WehwjqtAWR9GzXa2E="}]},"_npmUser":{"name":"dalcontk","email":"dalcont112@yahoo.es"},"directories":{},"maintainers":[{"name":"dalcontk","email":"dalcont112@yahoo.es"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/blogger-mcp-server_1.0.3_1774752135018_0.794227947156908"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-16T01:09:12.934Z","modified":"2026-03-29T02:42:15.518Z","1.0.0":"2026-02-16T01:09:13.176Z","1.0.1":"2026-03-08T10:58:00.656Z","1.0.2":"2026-03-29T02:18:56.889Z","1.0.3":"2026-03-29T02:42:15.149Z"},"bugs":{"url":"https://github.com/dalcontak/blogger-mcp-server/issues"},"license":"MIT","homepage":"https://github.com/dalcontak/blogger-mcp-server#readme","keywords":["mcp","blogger","api","claude","ai"],"repository":{"type":"git","url":"git+https://github.com/dalcontak/blogger-mcp-server.git"},"description":"MCP Server for Blogger API","maintainers":[{"name":"dalcontk","email":"dalcont112@yahoo.es"}],"readme":"# Blogger MCP Server\n\nMCP (Model Context Protocol) server for Google's Blogger API. Allows AI models like Claude to interact with Blogger blogs.\n\n## Features\n\n- **List and retrieve blogs** — Get blog details by ID or URL\n- **Posts management** — List, search, retrieve, create, update, delete posts\n- **Labels management** — List and retrieve labels\n- **Dual authentication**:\n  - **API Key** (read-only) — Access public blogs\n  - **OAuth2** (full access) — Create, update, delete posts, list your blogs\n- **Native search** — Uses Blogger's `posts/search` endpoint (not client-side filtering)\n- **Blog discovery** — `get_blog_by_url` tool to find blog ID from URL\n- **Optional Web UI** — Express + Socket.IO dashboard (enable with `UI_PORT`)\n\n> **Note:** The Blogger API does not allow creating new blogs. Blogs must be created manually via the Blogger web interface.\n\n## Installation\n\n### From npm\n\n```bash\nnpm install -g @dalcontak/blogger-mcp-server\n```\n\n### From source\n\n```bash\ngit clone https://github.com/dalcontak/blogger-mcp-server.git\ncd blogger-mcp-server\nnpm install\nnpm run build\n```\n\n## Authentication\n\n### Option 1: API Key (Read-only)\n\nAccess public blogs only. Useful if you only need to read data.\n\n1. Go to [Google Cloud Console](https://console.cloud.google.com/)\n2. Create/select a project, then enable the **Blogger API v3**.\n3. Create an **API Key** under Credentials.\n4. Set the environment variable: `export BLOGGER_API_KEY=your_api_key_here`\n\n### Option 2: OAuth2 (Full Access)\n\nRequired to create, update, delete posts, and list your own blogs. \n\n**Need a step-by-step visual guide?**  \n🔗 [**Read the complete tutorial on setting up OAuth2 for Blogger MCP here**](https://dalcontk.blogspot.com/2026/03/guia-paso-paso-como-configurar.html)  \n*(Note: This guide is written in Spanish. Feel free to use Google Translate if you need it in another language).*\n\n**Step 1: Configure OAuth Consent**\n1. In [Google Cloud Console](https://console.cloud.google.com/), go to **Google Auth Platform** > **Overview**.\n2. Under **Audience**, add your Google account as a Test User.\n3. Under **Data Access** (Scopes), add: `https://www.googleapis.com/auth/blogger`\n\n**Step 2: Create Web Credentials**\n1. Go to **Credentials** > **Create Credentials** > **OAuth client ID**.\n2. Application type: Select **Web application** *(do not use Desktop app)*.\n3. Name: Your app name.\n4. Authorized redirect URIs: Add exactly `https://developers.google.com/oauthplayground`\n5. Click Create and copy your **Client ID** and **Client Secret**.\n\n**Step 3: Get a Refresh Token**\n1. Go to the [Google OAuth 2.0 Playground](https://developers.google.com/oauthplayground/).\n2. Click the **Gear icon** (top right) ⚙️ > check **Use your own OAuth credentials**.\n3. Paste your **Client ID** and **Client Secret**, then close the settings panel.\n4. In Step 1 (left panel), scroll to **Blogger API v3**, select `https://www.googleapis.com/auth/blogger`, and click **Authorize APIs**.\n5. Log in with your test Google account and grant permissions.\n6. In Step 2, click **Exchange authorization code for tokens**.\n7. Copy the generated **Refresh token**.\n\n**Step 4: Set Environment Variables**\nConfigure your MCP client (like Claude Desktop or OpenCode) with:\n\n```json\n\"env\": {\n  \"GOOGLE_CLIENT_ID\": \"your_client_id_here\",\n  \"GOOGLE_CLIENT_SECRET\": \"your_client_secret_here\",\n  \"GOOGLE_REFRESH_TOKEN\": \"1//your_refresh_token_here\"\n}\n```\n\n> **Note:** If both API Key and OAuth2 are configured, OAuth2 is used.\n\n## Usage\n\n### Local Development\n\n```bash\n# Using npm package\nnpm start\n\n# Or from source (after build)\nnode dist/index.js\n\n# Development mode with ts-node\nnpm run dev\n```\n\n### With MCP Client (Claude Desktop)\n\nCreate or edit your Claude Desktop config file:\n\n**Linux:** `~/.config/Claude/claude_desktop_config.json`  \n**macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`  \n**Windows:** `%APPDATA%\\Claude\\claude_desktop_config.json`\n\n```json\n{\n  \"mcpServers\": {\n    \"blogger\": {\n      \"command\": \"node\",\n      \"args\": [\"./dist/index.js\"],\n      \"env\": {\n        \"BLOGGER_API_KEY\": \"your_api_key_here\"\n      }\n    }\n  }\n}\n```\n\nReplace `/home/dalcon/dev/ai/blogger-mcp-server/dist/index.js` with your actual path, and set your API key or OAuth2 credentials.\n\n### Example Commands\n\n```json\n// List all your blogs (requires OAuth2)\n{\"tool\": \"list_blogs\", \"params\": {}}\n\n// Get blog details by ID\n{\"tool\": \"get_blog\", \"params\": {\"blogId\": \"123456789\"}}\n\n// Find blog ID from URL (useful when you don't know the ID)\n{\"tool\": \"get_blog_by_url\", \"params\": {\"url\": \"https://yourblog.blogspot.com\"}}\n\n// List posts\n{\"tool\": \"list_posts\", \"params\": {\"blogId\": \"123456789\", \"maxResults\": 10}}\n\n// Search posts\n{\"tool\": \"search_posts\", \"params\": {\"blogId\": \"123456789\", \"query\": \"technology\"}}\n\n// Create a new post (requires OAuth2)\n{\"tool\": \"create_post\", \"params\": {\"blogId\": \"123456789\", \"title\": \"My Post\", \"content\": \"Content here\", \"labels\": [\"tech\", \"nodejs\"]}}\n\n// Update a post (requires OAuth2)\n{\"tool\": \"update_post\", \"params\": {\"blogId\": \"123456789\", \"postId\": \"789012\", \"title\": \"Updated Title\"}}\n\n// Delete a post (requires OAuth2)\n{\"tool\": \"delete_post\", \"params\": {\"blogId\": \"123456789\", \"postId\": \"789012\"}}\n\n// List labels\n{\"tool\": \"list_labels\", \"params\": {\"blogId\": \"123456789\"}}\n\n// Get label details\n{\"tool\": \"get_label\", \"params\": {\"blogId\": \"123456789\", \"labelName\": \"technology\"}}\n```\n\n## Available Tools\n\n| Tool | Description | Auth Required |\n|-------|-------------|---------------|\n| `list_blogs` | Lists all your blogs | OAuth2 |\n| `get_blog` | Retrieves blog details by ID | None |\n| `get_blog_by_url` | Finds blog ID from URL | None |\n| `list_posts` | Lists posts from a blog | None |\n| `search_posts` | Searches posts (uses native API) | None |\n| `get_post` | Retrieves post details | None |\n| `create_post` | Creates a new post | OAuth2 |\n| `update_post` | Updates an existing post | OAuth2 |\n| `delete_post` | Deletes a post | OAuth2 |\n| `list_labels` | Lists all labels from a blog | None |\n| `get_label` | Retrieves label details | None |\n\n## Environment Variables\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `BLOGGER_API_KEY` | (optional) | Google Blogger API key (read-only) |\n| `GOOGLE_CLIENT_ID` | (optional) | OAuth2 client ID (for full access) |\n| `GOOGLE_CLIENT_SECRET` | (optional) | OAuth2 client secret |\n| `GOOGLE_REFRESH_TOKEN` | (optional) | OAuth2 refresh token |\n| `MCP_MODE` | `stdio` | Transport: `stdio` or `http` |\n| `MCP_HTTP_HOST` | `0.0.0.0` | HTTP host (HTTP mode) |\n| `MCP_HTTP_PORT` | `3000` | HTTP port (HTTP mode) |\n| `BLOGGER_MAX_RESULTS` | `10` | Max results per query |\n| `BLOGGER_API_TIMEOUT` | `30000` | API timeout (ms) |\n| `LOG_LEVEL` | `info` | Logging level |\n| `UI_PORT` | (disabled) | Web UI port (set to enable) |\n\n**At least one auth method is required** — Either API key OR OAuth2 credentials.\n\n## Project Structure\n\n```\nsrc/\n  index.ts            # Entry point, main() function, HTTP mode routing\n  server.ts           # MCP server tool registration (initMCPServer)\n  bloggerService.ts   # Google Blogger API wrapper (BloggerService class)\n  config.ts           # Environment-based configuration object\n  types.ts            # Shared interfaces and type definitions\n  ui-manager.ts       # Express + Socket.IO web dashboard\n  *.test.ts           # Unit tests (Jest) alongside source files\n  .github/workflows/ # GitHub Actions CI/CD\npublic/               # Static web UI assets (HTML/JS/CSS)\ndist/                 # Compiled output\n```\n\n## Development\n\n```bash\n# Install dependencies\nnpm install\n\n# Run development (stdio mode, auto-compiles with ts-node)\nnpm run dev\n\n# Run in HTTP mode (useful for manual testing with curl)\nMCP_MODE=http BLOGGER_API_KEY=your_key npm run dev\n\n# Run tests\nnpm test\n\n# Build for production\nnpm run build\n```\n\n## Deployment\n\n### Vercel\n\nThe project includes `vercel.json` for Vercel deployment:\n\n1. Install Vercel CLI: `npm install -g vercel`\n2. Login: `vercel login`\n3. Deploy: `vercel`\n\n### Docker\n\nBuild and run:\n\n```bash\ndocker build -t blogger-mcp-server .\ndocker run -p 3000:3000 -e BLOGGER_API_KEY=your_key blogger-mcp-server\n```\n\n### Other Platforms\n\nThe server can be deployed to any Node.js-compatible platform (Heroku, AWS Lambda, Google Cloud Run, etc.).\n\n## Release Process\n\nFor publishing new versions to npm, see [RELEASE.md](./RELEASE.md).\n\n## Contributing\n\nContributions are welcome! Feel free to open an issue or pull request.\n\n## License\n\nMIT\n\n## Acknowledgments\n\n- Built with [TypeScript](https://www.typescriptlang.org/)\n- Uses [googleapis](https://github.com/googleapis/google-api-nodejs-client) for Google APIs\n- MCP SDK by [Model Context Protocol](https://modelcontextprotocol.io/)\n","readmeFilename":"README.md"}