@luoyi-dsh/instagram-mcp 0.0.0-stage → 1.0.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 瑞米
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.
package/README.md CHANGED
@@ -1,3 +1,144 @@
1
- # Temporary Holding Version
1
+ # DSH Instagram FastMCP 核心服務插件 (`@luoyi-dsh/instagram-mcp`)
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ ![Banner](assets/banner.png)
4
+
5
+ > **DeepSeek Harness (DSH)** 官方底層 Instagram 核心服務外掛。
6
+ > 負責自動管理獨立的 Python FastMCP 子進程、維持登入 Session 憑證,並向 DSH Tools 與其他外掛提供標準 Model Context Protocol (MCP) 操作介面。
7
+
8
+ ---
9
+
10
+ ## 🌟 核心特性
11
+
12
+ 1. **Python 虛擬環境自動維護**:
13
+ - 自動檢測系統 Python / `uv` 環境。
14
+ - 自動於插件目錄建立獨立 `.venv` 並安裝依賴清單 (`instagrapi`, `mcp<2`, `pydantic` 等)。
15
+ 2. **FastMCP Stdio 子進程生命週期**:
16
+ - 以 MCP 標準 Stdio 通訊協定管理 Python 伺服器子進程。
17
+ - 支援優雅重啟、斷線重連與進程清理。
18
+ 3. **Instagram Session 持久化與雙重驗證**:
19
+ - 支援帳號密碼登入、Session 快取載入 (`data/ig_session.json`) 與 2FA 驗證碼挑戰。
20
+ 4. **全域單例共享服務 (Zero-Error Singleton)**:
21
+ - 導出 `getSharedMcpService()` 與 `getSharedMcpClient()`,供業務層插件 (`dsh-instagram-plugin`、`dsh-instagram-scroll`) 安全共享底層連線與登入狀態,完全免除 Cordis 的屬性存取拋錯。
22
+ 5. **標準 MCP Tools 註冊**:
23
+ - 向 DSH `ctx.tools` 註冊 9 項 Instagram 核心底層工具,供 AI 主模型直接調用。
24
+
25
+ ---
26
+
27
+ ## 📦 安裝方式
28
+
29
+ 使用 DSH CLI 安裝外掛:
30
+
31
+ ```bash
32
+ dsh plugin --profile web add @luoyi-dsh/instagram-mcp
33
+ ```
34
+
35
+ 或透過 npm 安裝:
36
+
37
+ ```bash
38
+ npm install @luoyi-dsh/instagram-mcp
39
+ ```
40
+
41
+ ---
42
+
43
+ ## 🛠️ 提供之 9 項標準 MCP 工具
44
+
45
+ | 工具名稱 | 說明 | 參數 |
46
+ | :--- | :--- | :--- |
47
+ | **`ig_check_status`** | 檢查 FastMCP 服務狀態與當前 Instagram 登入情形 | 無 |
48
+ | **`ig_login`** | 登入 Instagram 帳號或重新驗證 Session 快取 | `username`, `password`, `two_factor_code`, `proxy_url` |
49
+ | **`ig_search_hashtag`** | 搜尋指定 Hashtag 標籤之精選/最新貼文清單 | `hashtag` (string), `limit` (number) |
50
+ | **`ig_get_post_context`** | 抓取指定貼文之完整內文、發布者資訊與相鄰留言上下文 | `media_pk` (string), `comment_limit` (number) |
51
+ | **`ig_post_comment`** | 於指定貼文發表新留言,或對特定留言進行巢狀回覆 | `media_pk` (string), `text` (string), `reply_to_comment_pk` (可選) |
52
+ | **`ig_get_unread_dms`** | 讀取最新或未讀之 Instagram 私訊對話線程 | `limit` (number) |
53
+ | **`ig_send_dm`** | 發送 Instagram Direct Message 私訊給特定線程 | `thread_id` (string), `text` (string) |
54
+ | **`ig_get_timeline_feed`** | 抓取使用者首頁動態牆 (Timeline Feed) 貼文清單 | `limit` (number) |
55
+ | **`ig_like_media`** | 對指定的 Instagram 貼文按讚 | `media_pk` (string) |
56
+
57
+ ---
58
+
59
+ ## 💻 使用範例
60
+
61
+ ### 1. DSH AI 自然語言直接調用
62
+
63
+ 在 DSH 對話中,AI 模型會根據上下文自動調用合適的 MCP 工具:
64
+
65
+ - **搜尋標籤**:「幫我搜尋 Instagram 上關於 #deepseek 標籤的最新 5 則貼文」
66
+ - **貼文內文與留言**:「這篇貼文 PK 是 3123456789012345678,幫我看完整內文與留言」
67
+ - **發表留言**:「在貼文 3123456789012345678 下留言:『架構非常完整,感謝分享!』」
68
+ - **檢查私訊**:「查看我目前有沒有未讀的 Instagram 私訊」
69
+ - **發送私訊**:「發送私訊給線程 17841400000000000 說:『您好,已收到您的諮詢!』」
70
+
71
+ ### 2. TypeScript / Node.js 跨插件調用
72
+
73
+ 其他 DSH 外掛(如業務層擴充插件)可直接匯入單例客戶端:
74
+
75
+ ```typescript
76
+ import { getSharedMcpClient } from '@luoyi-dsh/instagram-mcp'
77
+
78
+ const mcpClient = getSharedMcpClient()
79
+ if (mcpClient && mcpClient.ready) {
80
+ // 搜尋指定標籤
81
+ const posts = await mcpClient.igSearchHashtag('tech', 10)
82
+
83
+ // 抓取貼文詳細內容
84
+ const context = await mcpClient.igGetPostContext('3123456789012345678', 5)
85
+
86
+ // 發送私訊
87
+ await mcpClient.igSendDm({
88
+ thread_id: '17841400000000000',
89
+ text: '感謝您的來訊!',
90
+ })
91
+ }
92
+ ```
93
+
94
+ ---
95
+
96
+ ## ⚙️ 設定參數說明
97
+
98
+ 可於 DSH 設定面板或插件目錄下的 `data/config.json` 中配置:
99
+
100
+ | 欄位名稱 | 型別 | 預設值 | 說明 |
101
+ | :--- | :--- | :--- | :--- |
102
+ | **`username`** | string | `""` | Instagram 使用者名稱 |
103
+ | **`password`** | string | `""` | Instagram 登入密碼(存在有效 Session 時可留空) |
104
+ | **`twoFactorCode`** | string | `""` | 2FA 雙步驟驗證碼 |
105
+ | **`sessionPath`** | string | `"data/ig_session.json"` | Session 快取檔案路徑 |
106
+ | **`proxyUrl`** | string | `""` | 代理伺服器 URL(例如 `http://127.0.0.1:7890`,選填) |
107
+ | **`pythonPath`** | string | `""` | 自訂 Python 可執行檔路徑(留空則自動探測系統 Python / uv) |
108
+ | **`autoStart`** | boolean | `true` | 啟動 DSH 時是否自動啟動 FastMCP 子進程並嘗試登入 |
109
+
110
+ ---
111
+
112
+ ## 📁 目錄結構
113
+
114
+ ```text
115
+ dsh-instagram-mcp/
116
+ ├── cordis.patch.yml # DSH bundle patch 宣告
117
+ ├── package.json # 模組定義與依賴宣告
118
+ ├── tsconfig.json # TypeScript 編譯設定
119
+ ├── assets/
120
+ │ └── banner.png # 宣傳圖示與橫幅
121
+ ├── vendor/
122
+ │ └── instagram-mcp/ # 獨立 Python FastMCP 核心模組
123
+ │ ├── requirements.txt # Python 依賴清單
124
+ │ ├── server.py # FastMCP Stdio 伺服器入口
125
+ │ ├── auth.py # 帳號認證、Session 復原與 2FA
126
+ │ └── core.py # 貼文、留言、私訊、標籤等核心操作
127
+ └── src/
128
+ ├── index.ts # 外掛入口與單例服務掛載
129
+ ├── service.ts # InstagramMcpService 服務狀態管理器
130
+ ├── config.ts # Schemastery 設定模型定義
131
+ ├── types.ts # 型別與資料結構宣告
132
+ ├── lib/
133
+ │ ├── env.ts # Python 虛擬環境檢查與依賴安裝
134
+ │ ├── mcp.ts # FastMCP Client 子進程通訊封裝
135
+ │ └── hostdeps.ts # DSH 宿主相容層
136
+ └── tools/
137
+ └── mcpTools.ts # 向 DSH Tools 註冊之 9 項核心工具
138
+ ```
139
+
140
+ ---
141
+
142
+ ## 📄 授權條款
143
+
144
+ 本專案採用 [MIT License](LICENSE) 開源授權。
@@ -0,0 +1,9 @@
1
+ # ============================================================================
2
+ # dsh-instagram-mcp —— DSH bundle patch(插件掛載宣告)
3
+ # ============================================================================
4
+
5
+ - insert:
6
+ - id: instagram-mcp
7
+ name: dsh-instagram-mcp
8
+ config:
9
+ enabled: true
@@ -0,0 +1,17 @@
1
+ /**
2
+ * src/config.ts —— Instagram MCP Plugin 配置定義
3
+ */
4
+ export interface InstagramMcpConfig {
5
+ pythonPath?: string;
6
+ sessionPath?: string;
7
+ username?: string;
8
+ password?: string;
9
+ twoFactorCode?: string;
10
+ proxyUrl?: string;
11
+ autoStart?: boolean;
12
+ }
13
+ export declare const defaultMcpConfig: InstagramMcpConfig;
14
+ export declare function unwrapMcpValue<T>(val: any, fallback: T): T;
15
+ export declare function sanitizeMcpConfig(raw: any): InstagramMcpConfig;
16
+ export declare function buildMcpConfigSchema(z: any): any;
17
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,kBAAkB;IACjC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB;AAED,eAAO,MAAM,gBAAgB,EAAE,kBAG9B,CAAA;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,GAAG,CAAC,CAW1D;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,GAAG,GAAG,kBAAkB,CAW9D;AAED,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,GAAG,OAe1C"}
package/dist/config.js ADDED
@@ -0,0 +1,50 @@
1
+ /**
2
+ * src/config.ts —— Instagram MCP Plugin 配置定義
3
+ */
4
+ export const defaultMcpConfig = {
5
+ sessionPath: 'data/ig_session.json',
6
+ autoStart: true,
7
+ };
8
+ export function unwrapMcpValue(val, fallback) {
9
+ if (val === null || val === undefined)
10
+ return fallback;
11
+ if (val === '[object Object]')
12
+ return fallback;
13
+ if (typeof val === 'object' && typeof val.get === 'function') {
14
+ const v = val.get();
15
+ return (v !== undefined && v !== null && typeof v !== 'object') ? v : fallback;
16
+ }
17
+ if (typeof val === 'object' && !Array.isArray(val)) {
18
+ return fallback;
19
+ }
20
+ return val;
21
+ }
22
+ export function sanitizeMcpConfig(raw) {
23
+ const c = raw || {};
24
+ return {
25
+ pythonPath: unwrapMcpValue(c.pythonPath, ''),
26
+ sessionPath: unwrapMcpValue(c.sessionPath, defaultMcpConfig.sessionPath) || 'data/ig_session.json',
27
+ username: unwrapMcpValue(c.username, ''),
28
+ password: unwrapMcpValue(c.password, ''),
29
+ twoFactorCode: unwrapMcpValue(c.twoFactorCode, ''),
30
+ proxyUrl: unwrapMcpValue(c.proxyUrl, ''),
31
+ autoStart: unwrapMcpValue(c.autoStart, true),
32
+ };
33
+ }
34
+ export function buildMcpConfigSchema(z) {
35
+ return z.object({
36
+ pythonPath: z
37
+ .string()
38
+ .description('指定 Python 3 執行檔路徑 (留空則使用自動偵測或內建虛擬環境)'),
39
+ sessionPath: z
40
+ .string()
41
+ .default('data/ig_session.json')
42
+ .description('Instagram Session 快取持久化檔案相對路徑'),
43
+ username: z.string().description('Instagram 使用者帳號 (登入用)'),
44
+ password: z.string().description('Instagram 密碼 (已有 Session 時可留空)'),
45
+ twoFactorCode: z.string().description('2FA 雙步驟驗證代碼 (遇到挑戰時填入)'),
46
+ proxyUrl: z.string().description('HTTP/SOCKS5 代理伺服器 URL (防風控)'),
47
+ autoStart: z.boolean().default(true).description('是否在插件載入時自動啟動 FastMCP 子進程'),
48
+ });
49
+ }
50
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAYH,MAAM,CAAC,MAAM,gBAAgB,GAAuB;IAClD,WAAW,EAAE,sBAAsB;IACnC,SAAS,EAAE,IAAI;CAChB,CAAA;AAED,MAAM,UAAU,cAAc,CAAI,GAAQ,EAAE,QAAW;IACrD,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAA;IACtD,IAAI,GAAG,KAAK,iBAAiB;QAAE,OAAO,QAAQ,CAAA;IAC9C,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,OAAO,GAAG,CAAC,GAAG,KAAK,UAAU,EAAE,CAAC;QAC7D,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,EAAE,CAAA;QACnB,OAAO,CAAC,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,IAAI,IAAI,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAA;IAChF,CAAC;IACD,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACnD,OAAO,QAAQ,CAAA;IACjB,CAAC;IACD,OAAO,GAAQ,CAAA;AACjB,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,GAAQ;IACxC,MAAM,CAAC,GAAG,GAAG,IAAI,EAAE,CAAA;IACnB,OAAO;QACL,UAAU,EAAE,cAAc,CAAC,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC;QAC5C,WAAW,EAAE,cAAc,CAAC,CAAC,CAAC,WAAW,EAAE,gBAAgB,CAAC,WAAW,CAAC,IAAI,sBAAsB;QAClG,QAAQ,EAAE,cAAc,CAAC,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC;QACxC,QAAQ,EAAE,cAAc,CAAC,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC;QACxC,aAAa,EAAE,cAAc,CAAC,CAAC,CAAC,aAAa,EAAE,EAAE,CAAC;QAClD,QAAQ,EAAE,cAAc,CAAC,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC;QACxC,SAAS,EAAE,cAAc,CAAC,CAAC,CAAC,SAAS,EAAE,IAAI,CAAC;KAC7C,CAAA;AACH,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,CAAM;IACzC,OAAO,CAAC,CAAC,MAAM,CAAC;QACd,UAAU,EAAE,CAAC;aACV,MAAM,EAAE;aACR,WAAW,CAAC,sCAAsC,CAAC;QACtD,WAAW,EAAE,CAAC;aACX,MAAM,EAAE;aACR,OAAO,CAAC,sBAAsB,CAAC;aAC/B,WAAW,CAAC,+BAA+B,CAAC;QAC/C,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,WAAW,CAAC,uBAAuB,CAAC;QACzD,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,WAAW,CAAC,gCAAgC,CAAC;QAClE,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,WAAW,CAAC,uBAAuB,CAAC;QAC9D,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,WAAW,CAAC,6BAA6B,CAAC;QAC/D,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,0BAA0B,CAAC;KAC7E,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * src/index.ts —— DSH Instagram FastMCP 核心服務插件入口
3
+ * ============================================================================
4
+ * 職責:
5
+ * 1. 導出標準 Cordis 插件結構 (name, inject, Config, apply)。
6
+ * 2. 註冊與維護 Instagram FastMCP 服務單例 (getSharedMcpService / getSharedMcpClient),
7
+ * 供其他外掛 (dsh-instagram-plugin, dsh-instagram-scroll 等) 安全共享底層 FastMCP 連線與 Session,
8
+ * 完全免除 Cordis 的 property access 拋錯。
9
+ * 3. 立即向 DSH Tools 註冊標準 Instagram 工具集 (ig_login, ig_search_hashtag, 等)。
10
+ * 4. 管理 Python 獨立虛擬環境與 FastMCP 子進程生命週期。
11
+ * ============================================================================
12
+ */
13
+ import { InstagramMcpConfig } from './config.js';
14
+ import { InstagramMcpClient } from './lib/mcp.js';
15
+ import { InstagramMcpService } from './service.js';
16
+ export * from './types.js';
17
+ export * from './config.js';
18
+ export * from './lib/mcp.js';
19
+ export * from './lib/env.js';
20
+ export * from './service.js';
21
+ export declare function getSharedMcpService(): InstagramMcpService | null;
22
+ export declare function setSharedMcpService(svc: InstagramMcpService | null): void;
23
+ export declare function getSharedMcpClient(): InstagramMcpClient | null;
24
+ export declare const name = "instagram-mcp";
25
+ export declare const inject: string[];
26
+ export declare const Config: any;
27
+ export declare function apply(ctx: any, userConfig?: Partial<InstagramMcpConfig>): void;
28
+ declare const _default: {
29
+ name: string;
30
+ inject: string[];
31
+ Config: any;
32
+ apply: typeof apply;
33
+ };
34
+ export default _default;
35
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,OAAO,EAA0C,kBAAkB,EAAqB,MAAM,aAAa,CAAA;AAG3G,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AAEjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAElD,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA;AAK5B,wBAAgB,mBAAmB,IAAI,mBAAmB,GAAG,IAAI,CAGhE;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,mBAAmB,GAAG,IAAI,QAGlE;AAED,wBAAgB,kBAAkB,IAAI,kBAAkB,GAAG,IAAI,CAE9D;AAED,eAAO,MAAM,IAAI,kBAAkB,CAAA;AACnC,eAAO,MAAM,MAAM,UAAY,CAAA;AAI/B,eAAO,MAAM,MAAM,KAAkC,CAAA;AAErD,wBAAgB,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,UAAU,GAAE,OAAO,CAAC,kBAAkB,CAAM,QAwJ3E;;;;;;;AAED,wBAKC"}
package/dist/index.js ADDED
@@ -0,0 +1,188 @@
1
+ /**
2
+ * src/index.ts —— DSH Instagram FastMCP 核心服務插件入口
3
+ * ============================================================================
4
+ * 職責:
5
+ * 1. 導出標準 Cordis 插件結構 (name, inject, Config, apply)。
6
+ * 2. 註冊與維護 Instagram FastMCP 服務單例 (getSharedMcpService / getSharedMcpClient),
7
+ * 供其他外掛 (dsh-instagram-plugin, dsh-instagram-scroll 等) 安全共享底層 FastMCP 連線與 Session,
8
+ * 完全免除 Cordis 的 property access 拋錯。
9
+ * 3. 立即向 DSH Tools 註冊標準 Instagram 工具集 (ig_login, ig_search_hashtag, 等)。
10
+ * 4. 管理 Python 獨立虛擬環境與 FastMCP 子進程生命週期。
11
+ * ============================================================================
12
+ */
13
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
14
+ import { dirname, join } from 'node:path';
15
+ import { fileURLToPath } from 'node:url';
16
+ import { buildMcpConfigSchema, defaultMcpConfig, sanitizeMcpConfig } from './config.js';
17
+ import { loadSchemastery } from './lib/hostdeps.js';
18
+ import { ensurePythonEnv } from './lib/env.js';
19
+ import { InstagramMcpClient } from './lib/mcp.js';
20
+ import { registerMcpTools } from './tools/mcpTools.js';
21
+ import { InstagramMcpService } from './service.js';
22
+ export * from './types.js';
23
+ export * from './config.js';
24
+ export * from './lib/mcp.js';
25
+ export * from './lib/env.js';
26
+ export * from './service.js';
27
+ // 全局單例共享機制 (跨模組與全域保證零拋錯存取)
28
+ let sharedService = null;
29
+ export function getSharedMcpService() {
30
+ if (sharedService)
31
+ return sharedService;
32
+ return globalThis.__DSH_INSTAGRAM_MCP__ || null;
33
+ }
34
+ export function setSharedMcpService(svc) {
35
+ sharedService = svc;
36
+ globalThis.__DSH_INSTAGRAM_MCP__ = svc;
37
+ }
38
+ export function getSharedMcpClient() {
39
+ return getSharedMcpService()?.client || null;
40
+ }
41
+ export const name = 'instagram-mcp';
42
+ export const inject = ['tools'];
43
+ // 載入 schemastery
44
+ const zInstance = await loadSchemastery();
45
+ export const Config = buildMcpConfigSchema(zInstance);
46
+ export function apply(ctx, userConfig = {}) {
47
+ const pluginRoot = dirname(dirname(fileURLToPath(import.meta.url)));
48
+ const dataDir = join(pluginRoot, 'data');
49
+ if (!existsSync(dataDir)) {
50
+ mkdirSync(dataDir, { recursive: true });
51
+ }
52
+ const configFile = join(dataDir, 'config.json');
53
+ const localSavedConfig = (() => {
54
+ try {
55
+ if (existsSync(configFile)) {
56
+ return JSON.parse(readFileSync(configFile, 'utf-8'));
57
+ }
58
+ }
59
+ catch { }
60
+ return {};
61
+ })();
62
+ const activeConfig = sanitizeMcpConfig({
63
+ ...defaultMcpConfig,
64
+ ...userConfig,
65
+ ...localSavedConfig,
66
+ });
67
+ // 若 config.json 尚不存在,動態創建初始配置檔
68
+ if (!existsSync(configFile)) {
69
+ try {
70
+ writeFileSync(configFile, JSON.stringify(activeConfig, null, 2), 'utf-8');
71
+ }
72
+ catch { }
73
+ }
74
+ // 確保 sessionPath 所在資料夾與 session 初始檔案動態建立
75
+ const sessionAbsPath = join(pluginRoot, activeConfig.sessionPath || 'data/ig_session.json');
76
+ const sessionDir = dirname(sessionAbsPath);
77
+ if (!existsSync(sessionDir)) {
78
+ try {
79
+ mkdirSync(sessionDir, { recursive: true });
80
+ }
81
+ catch { }
82
+ }
83
+ if (!existsSync(sessionAbsPath)) {
84
+ try {
85
+ writeFileSync(sessionAbsPath, '{}', 'utf-8');
86
+ }
87
+ catch { }
88
+ }
89
+ const log = (msg) => {
90
+ console.log(`[IG-MCP] ${msg}`);
91
+ };
92
+ log(`Instagram FastMCP 插件初始化中... (路徑: ${pluginRoot})`);
93
+ // 1. 初始化並綁定單例服務
94
+ const service = new InstagramMcpService(activeConfig);
95
+ setSharedMcpService(service);
96
+ try {
97
+ if (typeof ctx?.provide === 'function') {
98
+ ctx.provide('instagramMcp');
99
+ }
100
+ }
101
+ catch { }
102
+ let mcpClient = null;
103
+ let isDisposed = false;
104
+ // 2. 立即註冊 Tools 給主模型與其他插件
105
+ registerMcpTools(ctx, activeConfig, () => mcpClient, () => service.loginStatus, log);
106
+ // 3. 異步啟動 Python 子進程與 FastMCP 伺服器
107
+ const initEngine = async () => {
108
+ try {
109
+ log('檢查 Python 虛擬環境...');
110
+ const envRes = await ensurePythonEnv(pluginRoot, activeConfig.pythonPath, log);
111
+ if (!envRes.ok) {
112
+ service.setLoginStatus({
113
+ ok: false,
114
+ message: `Python 虛擬環境未就緒: ${envRes.error}`,
115
+ });
116
+ log(`❌ ${service.loginStatus.message}`);
117
+ return;
118
+ }
119
+ if (isDisposed)
120
+ return;
121
+ const serverScript = join(pluginRoot, 'vendor', 'instagram-mcp', 'server.py');
122
+ mcpClient = new InstagramMcpClient({
123
+ pythonPath: envRes.pythonPath,
124
+ serverScriptPath: serverScript,
125
+ cwd: join(pluginRoot, 'vendor', 'instagram-mcp'),
126
+ log: (m) => log(`[Engine] ${m}`),
127
+ });
128
+ await mcpClient.start();
129
+ service.setClient(mcpClient);
130
+ log('✅ Python FastMCP 伺服器握手成功!');
131
+ // 4. 若已配置登入資訊或存在 Session 快取,嘗試登入
132
+ const sessionAbsPath = join(pluginRoot, activeConfig.sessionPath || 'data/ig_session.json');
133
+ const loginRes = await mcpClient.igLogin({
134
+ username: activeConfig.username,
135
+ password: activeConfig.password,
136
+ session_path: sessionAbsPath,
137
+ two_factor_code: activeConfig.twoFactorCode,
138
+ proxy_url: activeConfig.proxyUrl,
139
+ });
140
+ if (loginRes?.ok) {
141
+ service.setLoginStatus({
142
+ ok: true,
143
+ method: loginRes.method,
144
+ message: `已登入 (${loginRes.method === 'session' ? 'Session 快取' : '帳號密碼'}) - @${loginRes.username || activeConfig.username}`,
145
+ });
146
+ log(`🎉 Instagram 登入就緒!${service.loginStatus.message}`);
147
+ }
148
+ else {
149
+ service.setLoginStatus({
150
+ ok: false,
151
+ message: loginRes?.message || '等待登入或驗證憑證',
152
+ });
153
+ log(`ℹ️ ${service.loginStatus.message}`);
154
+ }
155
+ }
156
+ catch (err) {
157
+ service.setLoginStatus({
158
+ ok: false,
159
+ message: `FastMCP 啟動異常: ${err.message}`,
160
+ });
161
+ log(`❌ FastMCP 異常: ${err.message}`);
162
+ }
163
+ };
164
+ if (activeConfig.autoStart !== false) {
165
+ initEngine().catch((e) => log(`initEngine unhandled error: ${e.message}`));
166
+ }
167
+ // 4. 優雅卸載清理
168
+ const dispose = async () => {
169
+ isDisposed = true;
170
+ if (mcpClient) {
171
+ await mcpClient.stop().catch(() => { });
172
+ mcpClient = null;
173
+ service.setClient(null);
174
+ }
175
+ setSharedMcpService(null);
176
+ log('插件已成功卸載。');
177
+ };
178
+ if (typeof ctx?.on === 'function') {
179
+ ctx.on('dispose', dispose);
180
+ }
181
+ }
182
+ export default {
183
+ name,
184
+ inject,
185
+ Config,
186
+ apply,
187
+ };
188
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * src/lib/env.ts —— Python 虛擬環境自檢與依賴確保
3
+ */
4
+ export interface PythonEnvResult {
5
+ ok: boolean;
6
+ pythonPath: string;
7
+ error?: string;
8
+ }
9
+ export declare function ensurePythonEnv(packageRoot: string, userConfigPythonPath?: string, log?: (msg: string) => void): Promise<PythonEnvResult>;
10
+ //# sourceMappingURL=env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/lib/env.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,OAAO,CAAA;IACX,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,wBAAsB,eAAe,CACnC,WAAW,EAAE,MAAM,EACnB,oBAAoB,CAAC,EAAE,MAAM,EAC7B,GAAG,GAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAkB,GACvC,OAAO,CAAC,eAAe,CAAC,CAuG1B"}
@@ -0,0 +1,105 @@
1
+ /**
2
+ * src/lib/env.ts —— Python 虛擬環境自檢與依賴確保
3
+ */
4
+ import { existsSync, mkdirSync } from 'node:fs';
5
+ import { join } from 'node:path';
6
+ import { spawnSync } from 'node:child_process';
7
+ export async function ensurePythonEnv(packageRoot, userConfigPythonPath, log = console.log) {
8
+ const isWin = process.platform === 'win32';
9
+ const venvDir = join(packageRoot, 'vendor', 'instagram-mcp', '.venv');
10
+ const venvPython = isWin
11
+ ? join(venvDir, 'Scripts', 'python.exe')
12
+ : join(venvDir, 'bin', 'python');
13
+ const testPython = (binPath) => {
14
+ try {
15
+ if (!existsSync(binPath))
16
+ return false;
17
+ const res = spawnSync(binPath, ['-c', 'import instagrapi, mcp, pydantic; print("OK")'], {
18
+ encoding: 'utf-8',
19
+ windowsHide: true,
20
+ });
21
+ return res.status === 0 && res.stdout.includes('OK');
22
+ }
23
+ catch {
24
+ return false;
25
+ }
26
+ };
27
+ // 1. 若使用者指定 python 路徑且通過檢測
28
+ if (userConfigPythonPath && testPython(userConfigPythonPath)) {
29
+ log(`[Env] 使用配置之 Python: ${userConfigPythonPath}`);
30
+ return { ok: true, pythonPath: userConfigPythonPath };
31
+ }
32
+ // 2. 若內建 .venv 已經就緒
33
+ if (testPython(venvPython)) {
34
+ log(`[Env] 偵測到已就緒之 Python 虛擬環境: ${venvPython}`);
35
+ return { ok: true, pythonPath: venvPython };
36
+ }
37
+ log('[Env] 內建虛擬環境未就緒,嘗試自動搜尋系統 Python 進行建立...');
38
+ // 3. 搜尋可用系統 Python
39
+ const candidates = isWin
40
+ ? ['python.exe', 'py.exe', 'python3.exe']
41
+ : ['python3', 'python'];
42
+ let systemPython = null;
43
+ for (const cmd of candidates) {
44
+ try {
45
+ const res = spawnSync(cmd, ['-c', 'import sys; print(sys.version_info[0])'], {
46
+ encoding: 'utf-8',
47
+ windowsHide: true,
48
+ });
49
+ if (res.status === 0 && res.stdout.trim().startsWith('3')) {
50
+ systemPython = cmd;
51
+ break;
52
+ }
53
+ }
54
+ catch { }
55
+ }
56
+ if (!systemPython) {
57
+ return {
58
+ ok: false,
59
+ pythonPath: '',
60
+ error: '系統找不到 Python 3 環境,請安裝 Python 3.10+ 並加入 PATH。',
61
+ };
62
+ }
63
+ // 4. 建立 .venv
64
+ log(`[Env] 正在使用 ${systemPython} 建立虛擬環境至: ${venvDir}`);
65
+ try {
66
+ const venvParent = join(packageRoot, 'vendor', 'instagram-mcp');
67
+ if (!existsSync(venvParent))
68
+ mkdirSync(venvParent, { recursive: true });
69
+ const venvRes = spawnSync(systemPython, ['-m', 'venv', venvDir], {
70
+ windowsHide: true,
71
+ encoding: 'utf-8',
72
+ });
73
+ if (venvRes.status !== 0) {
74
+ return { ok: false, pythonPath: '', error: `建立虛擬環境失敗: ${venvRes.stderr}` };
75
+ }
76
+ }
77
+ catch (err) {
78
+ return { ok: false, pythonPath: '', error: `建立虛擬環境異常: ${err.message}` };
79
+ }
80
+ // 5. 安裝 requirements.txt
81
+ const reqFile = join(packageRoot, 'vendor', 'instagram-mcp', 'requirements.txt');
82
+ log(`[Env] 正在安裝 Python 依賴: ${reqFile}`);
83
+ try {
84
+ const pipRes = spawnSync(venvPython, ['-m', 'pip', 'install', '--quiet', '-r', reqFile], {
85
+ windowsHide: true,
86
+ encoding: 'utf-8',
87
+ });
88
+ if (pipRes.status !== 0) {
89
+ log(`[Env] pip 警告: ${pipRes.stderr}`);
90
+ }
91
+ }
92
+ catch (err) {
93
+ return { ok: false, pythonPath: '', error: `安裝依賴異常: ${err.message}` };
94
+ }
95
+ if (testPython(venvPython)) {
96
+ log(`[Env] 虛擬環境建立成功!使用: ${venvPython}`);
97
+ return { ok: true, pythonPath: venvPython };
98
+ }
99
+ return {
100
+ ok: false,
101
+ pythonPath: venvPython,
102
+ error: '虛擬環境已建立,但 instagrapi 或 mcp 套件未能成功載入。',
103
+ };
104
+ }
105
+ //# sourceMappingURL=env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/lib/env.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * src/lib/hostdeps.ts —— 宿主依賴載入器
3
+ */
4
+ export declare function loadSchemastery(): Promise<any>;
5
+ //# sourceMappingURL=hostdeps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hostdeps.d.ts","sourceRoot":"","sources":["../../src/lib/hostdeps.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,wBAAsB,eAAe,IAAI,OAAO,CAAC,GAAG,CAAC,CAuBpD"}