@zyzy-org/blog-mcp-server 1.0.0

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/.env.example ADDED
@@ -0,0 +1,14 @@
1
+ # Blog MCP Server 配置模板
2
+ # 复制此文件为 .env 并填入你的实际配置
3
+
4
+ # 博客配置
5
+ BLOG_URL=https://your-blog.com
6
+ BLOG_LOCAL_URL=http://localhost:3000
7
+
8
+ # MCP 认证配置
9
+ MCP_SECRET=your-mcp-secret-here
10
+ MCP_CLIENT_ID=your-client-id
11
+ MCP_SIGNATURE_SECRET=your-signature-secret
12
+
13
+ # 环境配置
14
+ NODE_ENV=production
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 ziyouzhiyi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,67 @@
1
+ # 项目结构
2
+
3
+ ```
4
+ yy-blog-generate-post-mcp-server/
5
+ ├── src/ # TypeScript 源代码
6
+ │ ├── index.ts # 主入口文件
7
+ │ ├── types.ts # 类型定义
8
+ │ ├── config.ts # 配置解析
9
+ │ ├── blog-client.ts # 博客 API 客户端
10
+ │ ├── mcp-server.ts # MCP 服务器实现
11
+ │ └── tools.ts # MCP 工具定义
12
+ ├── dist/ # 编译后的 JavaScript 文件
13
+ ├── package.json # 项目配置和依赖
14
+ ├── tsconfig.json # TypeScript 配置
15
+ ├── README.md # 项目说明文档
16
+ ├── LICENSE # MIT 许可证
17
+ ├── PUBLISH.md # 发布指南
18
+ ├── example-config.md # 配置示例
19
+ ├── test-mcp.js # 测试脚本
20
+ └── .gitignore # Git 忽略文件
21
+ ```
22
+
23
+ ## 核心文件说明
24
+
25
+ ### src/index.ts
26
+ 主入口文件,负责启动 MCP 服务器。
27
+
28
+ ### src/config.ts
29
+ 解析命令行参数,验证必需配置。
30
+
31
+ ### src/blog-client.ts
32
+ 博客 API 客户端,处理与你的博客后端的通信。
33
+
34
+ ### src/mcp-server.ts
35
+ MCP 协议服务器实现,处理 AI 助手的请求。
36
+
37
+ ### src/tools.ts
38
+ 定义可用的 MCP 工具(create_blog_post, create_multiple_blog_posts)。
39
+
40
+ ### src/types.ts
41
+ TypeScript 类型定义,确保类型安全。
42
+
43
+ ## 构建和运行
44
+
45
+ ```bash
46
+ # 安装依赖
47
+ npm install
48
+
49
+ # 构建项目
50
+ npm run build
51
+
52
+ # 测试配置
53
+ npm test
54
+
55
+ # 启动服务器
56
+ npm start
57
+ ```
58
+
59
+ ## 发布和使用
60
+
61
+ ```bash
62
+ # 发布到 npm
63
+ npm run publish-package
64
+
65
+ # 在 Cursor 中使用
66
+ npx -y @zyzy-org/blog-mcp-server@latest
67
+ ```
@@ -0,0 +1,70 @@
1
+ # 发布指南
2
+
3
+ ## 🚀 发布到 npm
4
+
5
+ ### 1. 准备发布
6
+
7
+ 确保你已经完成了以下步骤:
8
+
9
+ ```bash
10
+ # 构建项目
11
+ npm run build
12
+
13
+ # 测试配置
14
+ npm test
15
+ ```
16
+
17
+ ### 2. 登录 npm
18
+
19
+ ```bash
20
+ # 确保使用官方 npm 源
21
+ npm config set registry https://registry.npmjs.org/
22
+
23
+ # 登录到 npm
24
+ npm login
25
+ ```
26
+
27
+ ### 3. 发布包
28
+
29
+ ```bash
30
+ # 发布包
31
+ npm run publish-package
32
+ ```
33
+
34
+ ## 📦 包信息
35
+
36
+ - **包名**: `@zyzy-org/blog-mcp-server`
37
+ - **版本**: 1.0.0
38
+ - **访问权限**: public
39
+ - **描述**: 私人博客 MCP 服务器
40
+
41
+ ## 🔒 安全注意事项
42
+
43
+ - ✅ `.env` 文件不会被发布(已在 `.gitignore` 中)
44
+ - ✅ 敏感信息只存储在本地环境变量中
45
+ - ✅ 包中只包含必要的源代码和文档
46
+
47
+ ## 🎯 发布后使用
48
+
49
+ 发布成功后,你可以在 Cursor 中使用:
50
+
51
+ ```bash
52
+ npx -y @zyzy-org/blog-mcp-server@latest
53
+ ```
54
+
55
+ ## 🚨 故障排除
56
+
57
+ ### npm 认证问题
58
+ 如果遇到认证问题,请检查:
59
+ 1. 是否使用了正确的 npm 源
60
+ 2. 是否已正确登录
61
+ 3. 是否有发布权限
62
+
63
+ ### 版本更新
64
+ 更新版本时:
65
+ ```bash
66
+ npm version patch # 小版本更新
67
+ npm version minor # 次版本更新
68
+ npm version major # 主版本更新
69
+ npm run publish-package
70
+ ```
package/README.md ADDED
@@ -0,0 +1,147 @@
1
+ # Blog MCP Server
2
+
3
+ > 自动在你的技术博客中创建文章的 MCP 服务器
4
+
5
+ 这个 MCP (Model Context Protocol) 服务器允许 AI 助手(如 Cursor、Claude 等)直接在你的技术博客中创建文章,无需手动编辑。
6
+
7
+ ## 🎯 项目目标
8
+
9
+ 参考 [Supabase MCP](https://github.com/supabase-community/supabase-mcp) 的项目结构,创建一个完整的、可发布的 MCP 服务包,让 AI 助手能够直接在你的博客中创建文章。
10
+
11
+ ## ✨ 功能特性
12
+
13
+ - 🚀 **自动创建文章**: AI 可以直接创建完整的博客文章
14
+ - 📝 **Markdown 支持**: 支持完整的 Markdown 格式
15
+ - 🏷️ **标签管理**: 自动创建和管理文章标签
16
+ - 🔒 **安全认证**: 支持签名验证和客户端白名单
17
+ - 📦 **批量操作**: 支持批量创建多篇文章
18
+ - ⚡ **实时发布**: 文章创建后立即可见
19
+ - 🔧 **TypeScript**: 完整的类型安全支持
20
+ - 📦 **npm 包**: 可直接通过 npx 安装使用
21
+
22
+ ## 🚀 快速开始
23
+
24
+ ### 1. 配置环境变量
25
+
26
+ 复制 `.env.example` 为 `.env` 并填入你的配置:
27
+
28
+ ```bash
29
+ cp .env.example .env
30
+ # 编辑 .env 文件,填入你的实际配置
31
+ ```
32
+
33
+ ### 2. 在 Cursor 中配置
34
+
35
+ 在你的 Cursor 设置中添加以下 MCP 服务器:
36
+
37
+ #### 生产环境
38
+ ```bash
39
+ npx -y @zyzy-org/blog-mcp-server@latest
40
+ ```
41
+
42
+ #### 本地开发
43
+ ```bash
44
+ npx -y @zyzy-org/blog-mcp-server@latest --local
45
+ ```
46
+
47
+ ## ⚙️ 配置参数
48
+
49
+ ### 环境变量配置(推荐)
50
+ 在 `.env` 文件中配置:
51
+
52
+ - `BLOG_URL`: 你的博客 API 地址(必需)
53
+ - `MCP_SECRET`: MCP 共享密钥(必需)
54
+ - `MCP_CLIENT_ID`: 客户端标识(可选,默认为 'blog-mcp-client')
55
+ - `MCP_SIGNATURE_SECRET`: 签名密钥(可选,用于额外安全验证)
56
+ - `BLOG_LOCAL_URL`: 本地开发地址(可选)
57
+
58
+ ### 命令行参数(可选)
59
+ - `--blog-url`: 覆盖环境变量中的博客地址
60
+ - `--secret`: 覆盖环境变量中的密钥
61
+ - `--client-id`: 覆盖环境变量中的客户端ID
62
+ - `--signature-secret`: 覆盖环境变量中的签名密钥
63
+ - `--local`: 使用本地开发环境
64
+
65
+ ## 🛠️ 可用工具
66
+
67
+ ### create_blog_post
68
+ 创建单篇博客文章
69
+
70
+ **参数:**
71
+ - `title` (string): 文章标题
72
+ - `content` (string): 文章内容(Markdown 格式)
73
+ - `tags` (array): 文章标签
74
+ - `author` (string): 作者名称
75
+ - `readTime` (number): 预计阅读时间(分钟)
76
+ - `date` (string): 发布日期(ISO 8601 格式)
77
+ - `github_url` (string): 相关的 GitHub 链接
78
+ - `slug` (string): 自定义文章 slug
79
+
80
+ ### create_multiple_blog_posts
81
+ 批量创建多篇博客文章
82
+
83
+ **参数:**
84
+ - `articles` (array): 要创建的文章数组
85
+
86
+ ## 🔒 安全特性
87
+
88
+ - 使用共享密钥进行基础认证
89
+ - 支持时间戳验证防止重放攻击
90
+ - 可选的签名验证提供额外安全层
91
+ - 支持客户端白名单限制访问
92
+ - 完整的错误处理和日志记录
93
+
94
+ ## 🧪 测试
95
+
96
+ ```bash
97
+ # 构建项目
98
+ npm run build
99
+
100
+ # 启动 MCP 服务器
101
+ npm start
102
+
103
+ # 或者直接运行
104
+ node dist/index.js
105
+ ```
106
+
107
+ ## 🛠️ 开发
108
+
109
+ ```bash
110
+ # 安装依赖
111
+ npm install
112
+
113
+ # 构建
114
+ npm run build
115
+
116
+ # 开发模式
117
+ npm run dev
118
+
119
+ # 本地测试
120
+ npm run test
121
+ ```
122
+
123
+ ## 📁 项目结构
124
+
125
+ ```
126
+ src/
127
+ ├── index.ts # 主入口文件
128
+ ├── types.ts # 类型定义
129
+ ├── config.ts # 配置解析
130
+ ├── blog-client.ts # 博客 API 客户端
131
+ ├── mcp-server.ts # MCP 服务器实现
132
+ └── tools.ts # MCP 工具定义
133
+ ```
134
+
135
+ ## 📚 相关文档
136
+
137
+ - [USAGE.md](./USAGE.md) - 详细使用指南
138
+ - [PROJECT_STRUCTURE.md](./PROJECT_STRUCTURE.md) - 项目结构说明
139
+ - [example-config.md](./example-config.md) - 配置示例
140
+
141
+ ## 🤝 贡献
142
+
143
+ 欢迎提交 Issue 和 Pull Request!
144
+
145
+ ## 📄 许可证
146
+
147
+ MIT License - 详见 [LICENSE](./LICENSE) 文件
package/SETUP.md ADDED
@@ -0,0 +1,96 @@
1
+ # 私人 MCP 服务器设置指南
2
+
3
+ ## 🎯 项目说明
4
+
5
+ 这是一个专为你的博客定制的私人 MCP 服务器,所有敏感信息都存储在 `.env` 文件中,确保安全性。
6
+
7
+ ## 🚀 快速设置
8
+
9
+ ### 1. 环境配置
10
+
11
+ 项目已经为你配置好了 `.env` 文件,包含所有必要的密钥:
12
+
13
+ ```bash
14
+ # 博客配置
15
+ BLOG_URL=https://zyzy.info
16
+ BLOG_LOCAL_URL=http://localhost:3000
17
+
18
+ # MCP 认证配置
19
+ MCP_SECRET=660649959a92f12949618a919413e83c8aad09afbb39bcc172725583037e6beb
20
+ MCP_CLIENT_ID=my-mcp-client
21
+ MCP_SIGNATURE_SECRET=c20f0c7bd9128d05c53ffc7743f483c21169f1562542c30ea6e6bf127b488e5f
22
+ ```
23
+
24
+ ### 2. 在 Cursor 中配置
25
+
26
+ 在你的 Cursor 设置中添加以下 MCP 服务器:
27
+
28
+ #### 生产环境(推荐)
29
+ ```bash
30
+ npx -y @zyzy-org/blog-mcp-server@latest
31
+ ```
32
+
33
+ #### 本地开发
34
+ ```bash
35
+ npx -y @zyzy-org/blog-mcp-server@latest --local
36
+ ```
37
+
38
+ ## 🛠️ 使用方法
39
+
40
+ ### 创建单篇文章
41
+ ```
42
+ 请在我的博客中创建一篇关于 React 的文章,标题为"React Hooks 详解"
43
+ ```
44
+
45
+ ### 批量创建文章
46
+ ```
47
+ 请在我的博客中创建三篇关于 TypeScript 的文章:
48
+ 1. TypeScript 基础语法
49
+ 2. TypeScript 高级特性
50
+ 3. TypeScript 最佳实践
51
+ ```
52
+
53
+ ## 🔒 安全特性
54
+
55
+ - ✅ 所有敏感信息存储在 `.env` 文件中
56
+ - ✅ `.env` 文件已添加到 `.gitignore`
57
+ - ✅ 支持签名验证防止篡改
58
+ - ✅ 时间戳验证防止重放攻击
59
+ - ✅ 客户端白名单限制访问
60
+
61
+ ## 🧪 测试
62
+
63
+ ```bash
64
+ # 测试配置是否正确
65
+ npm test
66
+
67
+ # 构建项目
68
+ npm run build
69
+
70
+ # 启动服务器
71
+ npm start
72
+ ```
73
+
74
+ ## 📁 项目结构
75
+
76
+ ```
77
+ ├── src/ # TypeScript 源代码
78
+ ├── dist/ # 编译后的文件
79
+ ├── .env # 环境变量配置(包含敏感信息)
80
+ ├── .env.example # 环境变量模板
81
+ ├── package.json # 项目配置
82
+ ├── README.md # 项目说明
83
+ ├── USAGE.md # 使用指南
84
+ └── test-config.js # 配置测试脚本
85
+ ```
86
+
87
+ ## 🚨 重要提醒
88
+
89
+ 1. **不要提交 `.env` 文件** - 它包含敏感信息
90
+ 2. **这是私人服务** - 仅适用于你的博客
91
+ 3. **定期更新密钥** - 建议定期更换签名密钥
92
+ 4. **本地测试** - 建议先在本地环境测试
93
+
94
+ ## 🎉 完成
95
+
96
+ 配置完成后,你就可以在 Cursor 中直接使用 AI 助手创建博客文章了!
package/USAGE.md ADDED
@@ -0,0 +1,89 @@
1
+ # 使用指南
2
+
3
+ ## 快速开始
4
+
5
+ ### 1. 配置环境变量
6
+
7
+ 复制 `.env.example` 为 `.env` 并填入你的配置:
8
+
9
+ ```bash
10
+ cp .env.example .env
11
+ # 编辑 .env 文件,填入你的实际配置
12
+ ```
13
+
14
+ ### 2. 在 Cursor 中配置
15
+
16
+ 在你的 Cursor 设置中添加以下 MCP 服务器:
17
+
18
+ #### 生产环境配置
19
+ ```bash
20
+ npx -y @zyzy-org/blog-mcp-server@latest
21
+ ```
22
+
23
+ #### 本地开发配置
24
+ ```bash
25
+ npx -y @zyzy-org/blog-mcp-server@latest --local
26
+ ```
27
+
28
+ ## 可用工具
29
+
30
+ ### create_blog_post
31
+ 创建单篇博客文章
32
+
33
+ **示例用法:**
34
+ ```
35
+ 请在我的博客中创建一篇关于 TypeScript 的文章,标题为"TypeScript 最佳实践",包含以下内容:
36
+ - TypeScript 基础语法
37
+ - 类型系统详解
38
+ - 最佳实践建议
39
+ ```
40
+
41
+ ### create_multiple_blog_posts
42
+ 批量创建多篇博客文章
43
+
44
+ **示例用法:**
45
+ ```
46
+ 请在我的博客中创建三篇关于 React 的文章:
47
+ 1. React Hooks 详解
48
+ 2. React 性能优化
49
+ 3. React 状态管理
50
+ ```
51
+
52
+ ## 故障排除
53
+
54
+ ### 1. API 连接问题
55
+
56
+ 如果遇到 API 连接问题,请检查:
57
+
58
+ - 博客是否正在运行
59
+ - API 端点是否正确配置
60
+ - 认证密钥是否正确
61
+ - `.env` 文件配置是否正确
62
+
63
+ ### 2. 生产环境问题
64
+
65
+ 如果生产环境 API 返回登录页面,可能需要:
66
+
67
+ 1. 检查中间件配置
68
+ 2. 确保 API 路由正确部署
69
+ 3. 验证认证逻辑
70
+
71
+ ### 3. 本地测试
72
+
73
+ ```bash
74
+ # 构建项目
75
+ npm run build
76
+
77
+ # 启动 MCP 服务器
78
+ npm start
79
+
80
+ # 或者直接运行
81
+ node dist/index.js
82
+ ```
83
+
84
+ ## 安全注意事项
85
+
86
+ - 不要在公开代码中暴露密钥
87
+ - 定期轮换签名密钥
88
+ - 使用客户端白名单限制访问
89
+ - 监控 API 使用情况
@@ -0,0 +1,9 @@
1
+ import { BlogPostData, MCPConfig } from './types';
2
+ export declare class BlogClient {
3
+ private config;
4
+ constructor(config: MCPConfig);
5
+ private generateSignature;
6
+ createBlogPost(postData: BlogPostData): Promise<any>;
7
+ createMultipleBlogPosts(articles: BlogPostData[]): Promise<any[]>;
8
+ }
9
+ //# sourceMappingURL=blog-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blog-client.d.ts","sourceRoot":"","sources":["../src/blog-client.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAsB,SAAS,EAAE,MAAM,SAAS,CAAC;AAEtE,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAY;gBAEd,MAAM,EAAE,SAAS;IAI7B,OAAO,CAAC,iBAAiB;IAWnB,cAAc,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC;IA4BpD,uBAAuB,CAAC,QAAQ,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;CAexE"}
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.BlogClient = void 0;
7
+ // 使用原生 fetch API
8
+ const crypto_1 = __importDefault(require("crypto"));
9
+ class BlogClient {
10
+ constructor(config) {
11
+ this.config = config;
12
+ }
13
+ generateSignature(data) {
14
+ if (!this.config.signatureSecret) {
15
+ throw new Error('签名密钥未配置');
16
+ }
17
+ return crypto_1.default
18
+ .createHmac('sha256', this.config.signatureSecret)
19
+ .update(JSON.stringify({ ...data, signature: undefined }))
20
+ .digest('hex');
21
+ }
22
+ async createBlogPost(postData) {
23
+ const secureData = {
24
+ ...postData,
25
+ client_id: this.config.clientId,
26
+ timestamp: Date.now(),
27
+ };
28
+ if (this.config.signatureSecret) {
29
+ secureData.signature = this.generateSignature(secureData);
30
+ }
31
+ const response = await fetch(`${this.config.blogUrl}/api/mcp/posts`, {
32
+ method: 'POST',
33
+ headers: {
34
+ 'Content-Type': 'application/json',
35
+ 'x-mcp-secret': this.config.secret,
36
+ },
37
+ body: JSON.stringify(secureData)
38
+ });
39
+ if (!response.ok) {
40
+ const errorText = await response.text();
41
+ throw new Error(`HTTP ${response.status}: ${errorText}`);
42
+ }
43
+ return await response.json();
44
+ }
45
+ async createMultipleBlogPosts(articles) {
46
+ const results = [];
47
+ for (const article of articles) {
48
+ try {
49
+ const result = await this.createBlogPost(article);
50
+ results.push({ success: true, ...result });
51
+ }
52
+ catch (error) {
53
+ results.push({
54
+ success: false,
55
+ error: error instanceof Error ? error.message : String(error)
56
+ });
57
+ }
58
+ }
59
+ return results;
60
+ }
61
+ }
62
+ exports.BlogClient = BlogClient;
63
+ //# sourceMappingURL=blog-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blog-client.js","sourceRoot":"","sources":["../src/blog-client.ts"],"names":[],"mappings":";;;;;;AAAA,iBAAiB;AACjB,oDAA4B;AAG5B,MAAa,UAAU;IAGrB,YAAY,MAAiB;QAC3B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAEO,iBAAiB,CAAC,IAAwB;QAChD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC;QAC7B,CAAC;QAED,OAAO,gBAAM;aACV,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC;aACjD,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC;aACzD,MAAM,CAAC,KAAK,CAAC,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,QAAsB;QACzC,MAAM,UAAU,GAAuB;YACrC,GAAG,QAAQ;YACX,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ;YAC/B,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACtB,CAAC;QAEF,IAAI,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;YAChC,UAAU,CAAC,SAAS,GAAG,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;QAC5D,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,gBAAgB,EAAE;YACnE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC;SACjC,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,QAAQ,QAAQ,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC,CAAC;QAC3D,CAAC;QAED,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,uBAAuB,CAAC,QAAwB;QACpD,MAAM,OAAO,GAAG,EAAE,CAAC;QACnB,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;gBAClD,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;YAC7C,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,IAAI,CAAC;oBACX,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;iBAC9D,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;CACF;AA7DD,gCA6DC"}
@@ -0,0 +1,3 @@
1
+ import { MCPConfig } from './types';
2
+ export declare function parseConfig(): MCPConfig;
3
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAMpC,wBAAgB,WAAW,IAAI,SAAS,CAiDvC"}
package/dist/config.js ADDED
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.parseConfig = parseConfig;
7
+ const dotenv_1 = __importDefault(require("dotenv"));
8
+ // 加载环境变量
9
+ dotenv_1.default.config();
10
+ function parseConfig() {
11
+ const args = process.argv.slice(2);
12
+ // 从环境变量获取默认配置
13
+ const config = {
14
+ blogUrl: process.env.BLOG_URL,
15
+ secret: process.env.MCP_SECRET,
16
+ clientId: process.env.MCP_CLIENT_ID || 'blog-mcp-client',
17
+ signatureSecret: process.env.MCP_SIGNATURE_SECRET
18
+ };
19
+ // 命令行参数覆盖环境变量
20
+ for (let i = 0; i < args.length; i++) {
21
+ const arg = args[i];
22
+ if (arg.startsWith('--')) {
23
+ const key = arg.slice(2);
24
+ const value = args[i + 1];
25
+ switch (key) {
26
+ case 'blog-url':
27
+ config.blogUrl = value;
28
+ break;
29
+ case 'secret':
30
+ config.secret = value;
31
+ break;
32
+ case 'client-id':
33
+ config.clientId = value;
34
+ break;
35
+ case 'signature-secret':
36
+ config.signatureSecret = value;
37
+ break;
38
+ case 'local':
39
+ // 使用本地开发环境
40
+ config.blogUrl = process.env.BLOG_LOCAL_URL || 'http://localhost:3000';
41
+ break;
42
+ }
43
+ }
44
+ }
45
+ // 验证必需参数
46
+ if (!config.blogUrl) {
47
+ throw new Error('BLOG_URL 环境变量或 --blog-url 参数是必需的');
48
+ }
49
+ if (!config.secret) {
50
+ throw new Error('MCP_SECRET 环境变量或 --secret 参数是必需的');
51
+ }
52
+ return config;
53
+ }
54
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;;;AAMA,kCAiDC;AAtDD,oDAA4B;AAE5B,SAAS;AACT,gBAAM,CAAC,MAAM,EAAE,CAAC;AAEhB,SAAgB,WAAW;IACzB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAEnC,cAAc;IACd,MAAM,MAAM,GAAuB;QACjC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ;QAC7B,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU;QAC9B,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,iBAAiB;QACxD,eAAe,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB;KAClD,CAAC;IAEF,cAAc;IACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAEpB,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACzB,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAE1B,QAAQ,GAAG,EAAE,CAAC;gBACZ,KAAK,UAAU;oBACb,MAAM,CAAC,OAAO,GAAG,KAAK,CAAC;oBACvB,MAAM;gBACR,KAAK,QAAQ;oBACX,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC;oBACtB,MAAM;gBACR,KAAK,WAAW;oBACd,MAAM,CAAC,QAAQ,GAAG,KAAK,CAAC;oBACxB,MAAM;gBACR,KAAK,kBAAkB;oBACrB,MAAM,CAAC,eAAe,GAAG,KAAK,CAAC;oBAC/B,MAAM;gBACR,KAAK,OAAO;oBACV,WAAW;oBACX,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,uBAAuB,CAAC;oBACvE,MAAM;YACV,CAAC;QACH,CAAC;IACH,CAAC;IAED,SAAS;IACT,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACtD,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACtD,CAAC;IAED,OAAO,MAAmB,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const config_1 = require("./config");
5
+ const blog_client_1 = require("./blog-client");
6
+ const mcp_server_1 = require("./mcp-server");
7
+ async function main() {
8
+ try {
9
+ // 解析配置
10
+ const config = (0, config_1.parseConfig)();
11
+ // 创建博客客户端
12
+ const blogClient = new blog_client_1.BlogClient(config);
13
+ // 创建并启动 MCP 服务器
14
+ const server = new mcp_server_1.MCPServer(blogClient);
15
+ server.start();
16
+ }
17
+ catch (error) {
18
+ console.error('启动失败:', error instanceof Error ? error.message : String(error));
19
+ process.exit(1);
20
+ }
21
+ }
22
+ main();
23
+ //# sourceMappingURL=index.js.map