@ignission/slack-task-mcp 0.2.1 → 0.2.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ignission G.K.
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,112 +1,268 @@
1
- # slack-task-mcp
1
+ <p align="center">
2
+ <h1 align="center">🧠 Slack Task MCP</h1>
3
+ </p>
2
4
 
3
- Slack Task Management MCP Server for Claude Code / Claude Desktop
5
+ <p align="center">
6
+ <strong>メンションから着手までの摩擦をゼロに</strong>
7
+ </p>
4
8
 
5
- [![npm version](https://badge.fury.io/js/slack-task-mcp.svg)](https://www.npmjs.com/package/slack-task-mcp)
9
+ <p align="center">
10
+ <a href="https://www.npmjs.com/package/@ignission/slack-task-mcp"><img src="https://img.shields.io/npm/v/@ignission/slack-task-mcp" alt="npm version"></a>
11
+ <a href="https://opensource.org/licenses/ISC"><img src="https://img.shields.io/badge/License-ISC-blue.svg" alt="License: ISC"></a>
12
+ </p>
6
13
 
7
- [日本語](https://github.com/ignission/slack-task-mcp/blob/main/packages/core/README.ja.md)
14
+ <p align="center">
15
+ ADHDの特性を持つユーザーのために設計されたMCPサーバー
16
+ </p>
8
17
 
9
- ## Who is this for?
18
+ ---
10
19
 
11
- - You get overwhelmed when Slack mentions pile up
12
- - You freeze when complex requests come in, unsure what to ask
13
- - Writing replies takes too long
14
- - You break down tasks but lose focus midway
20
+ ## Why
15
21
 
16
- ## Installation
22
+ Slackのメンションがたまると、どこから手を付けていいか迷う。難しい依頼が来ると、何を聞けばいいかわからず固まる。返信を書くのに時間がかかる——そんな経験はありませんか?
17
23
 
18
- ```bash
19
- # Authenticate (first time only)
20
- npx slack-task-mcp auth
24
+ <p align="center">
25
+
26
+ | 😵 困りごと | ➡️ | 🎯 解決 |
27
+ |:---:|:---:|:---:|
28
+ | 「何求められてる?」が曖昧で固まる | → | 目的の明確化 |
29
+ | 「何聞けばいい?」がわからない | → | 不明点の洗い出し + 確認メッセージ案 |
30
+ | 「どう返せばいい?」で時間かかる | → | 返信メッセージの添削・構造化 |
31
+ | 「次何する?」で迷う | → | ネクストアクション提示 |
32
+
33
+ </p>
34
+
35
+ ---
36
+
37
+ ## Architecture
38
+
39
+ ```mermaid
40
+ graph TB
41
+ subgraph Client ["Claude Desktop / Claude Code"]
42
+ MCP["MCP Client"]
43
+ end
44
+
45
+ subgraph Core ["Slack Task MCP"]
46
+ Server["MCP Server<br/>(stdio transport)"]
47
+
48
+ subgraph Tools ["MCPツール"]
49
+ SlackTools["🔗 Slack連携<br/>get_slack_thread<br/>search_slack"]
50
+ TaskTools["📋 タスク管理<br/>save/list/search<br/>complete_step"]
51
+ AITools["🤖 AI支援<br/>analyze_request<br/>draft_reply"]
52
+ end
53
+
54
+ subgraph AgentSDK ["Agent SDK Layer"]
55
+ Analyze["analyze.js<br/>依頼分析"]
56
+ Draft["draft-reply.js<br/>返信添削"]
57
+ end
58
+ end
21
59
 
22
- # Check authentication status
23
- npx slack-task-mcp auth status
60
+ subgraph External ["外部サービス"]
61
+ SlackAPI["Slack API"]
62
+ ClaudeAPI["Claude API"]
63
+ end
64
+
65
+ MCP -->|MCP Protocol| Server
66
+ Server --> Tools
67
+ AITools --> AgentSDK
68
+ Analyze -->|query| ClaudeAPI
69
+ Draft -->|query| ClaudeAPI
70
+ SlackTools -->|User Token| SlackAPI
24
71
  ```
25
72
 
26
- ## Claude Desktop Configuration
73
+ **ポイント:**
74
+ - **MCP Server**: Slack APIとのやり取り、タスク管理を担当
75
+ - **Agent SDK Layer**: Claude APIを使った高度な分析・添削処理を担当
27
76
 
28
- ### macOS
77
+ ---
29
78
 
30
- `~/Library/Application Support/Claude/claude_desktop_config.json`:
79
+ ## Features
31
80
 
32
- ```json
33
- {
34
- "mcpServers": {
35
- "slack-task": {
36
- "command": "npx",
37
- "args": ["-y", "slack-task-mcp"]
38
- }
39
- }
40
- }
81
+ | ツール | 機能 | Agent SDK |
82
+ |--------|------|:---------:|
83
+ | `get_slack_thread` | SlackスレッドのURLからメッセージを取得 | - |
84
+ | `analyze_request` | 依頼を分析し、目的・不明点・確認案を生成 | ✅ |
85
+ | `draft_reply` | 返信を添削し、ロジカルに構造化 | ✅ |
86
+ | `save_task` | タスクを保存(5分以内のステップに分解) | - |
87
+ | `list_tasks` | アクティブなタスク一覧を表示 | - |
88
+ | `search_tasks` | キーワード・日付でタスクを検索 | - |
89
+ | `complete_step` | ステップを完了にする | - |
90
+ | `search_slack` | Slackメッセージをキーワードで検索 | - |
91
+
92
+ ---
93
+
94
+ ## Quick Start
95
+
96
+ ### 1. Slack認証
97
+
98
+ ```bash
99
+ npx @ignission/slack-task-mcp auth login
41
100
  ```
42
101
 
43
- ### Windows
102
+ ブラウザが開き、Slackの認証画面が表示されます。複数のワークスペースを認証する場合は、このコマンドを繰り返し実行してください。
103
+
104
+ ### 2. Claude Code / Claude Desktop の設定
44
105
 
45
- `%APPDATA%\Claude\claude_desktop_config.json`:
106
+ **Claude Code (ターミナル)**:
107
+
108
+ ```bash
109
+ claude mcp add slack-task -- npx -y @ignission/slack-task-mcp
110
+ ```
111
+
112
+ **Claude Desktop** (`~/.claude/claude_desktop_config.json`):
46
113
 
47
114
  ```json
48
115
  {
49
116
  "mcpServers": {
50
117
  "slack-task": {
51
- "command": "npx.cmd",
52
- "args": ["-y", "slack-task-mcp"]
118
+ "command": "npx",
119
+ "args": ["-y", "@ignission/slack-task-mcp"]
53
120
  }
54
121
  }
55
122
  }
56
123
  ```
57
124
 
58
- Restart Claude Desktop after configuration.
125
+ ### 3. 再起動
59
126
 
60
- ## Features
127
+ 設定を反映するためにClaude Code / Claude Desktopを再起動してください。
61
128
 
62
- | Tool | Description |
63
- |------|-------------|
64
- | `get_slack_thread` | Fetch messages from a Slack thread URL |
65
- | `analyze_request` | Analyze requests and generate purpose, questions, and confirmation messages |
66
- | `draft_reply` | Edit and structure replies logically |
67
- | `save_task` | Save tasks (broken into 5-minute steps) |
68
- | `list_tasks` | Display task list |
69
- | `search_tasks` | Search tasks by keyword or date |
70
- | `complete_step` | Mark a step as complete |
71
- | `search_slack` | Search Slack messages by keyword |
129
+ ---
72
130
 
73
131
  ## Usage
74
132
 
75
- ### Analyze a Slack thread
133
+ ### 基本ワークフロー
76
134
 
77
135
  ```
78
- Analyze this thread: https://xxx.slack.com/archives/C12345678/p1234567890
136
+ 1. get_slack_thread → スレッド取得(文脈DB化)
137
+ 2. analyze_request → 目的・不明点・確認案を生成
138
+ 3. draft_reply → 返信の下書きを添削・構造化
139
+ 4. save_task → タスクとして保存
140
+ 5. complete_step → 進捗管理
79
141
  ```
80
142
 
81
- ### Save as a task
143
+ ### 使用例
144
+
145
+ #### スレッドを取得・分析
82
146
 
83
147
  ```
84
- Break this down into 5-minute steps and save it
148
+ このSlackスレッドを分析して:
149
+ https://xxx.slack.com/archives/C12345678/p1234567890123456
85
150
  ```
86
151
 
87
- ### Edit a reply
152
+ #### タスクを保存
88
153
 
89
154
  ```
90
- Edit this reply: "The report is done. Please check it."
155
+ このタスクを5分以内のステップに分解して保存して
91
156
  ```
92
157
 
93
- ## CLI Commands
158
+ #### 返信を添削
94
159
 
95
- ```bash
96
- npx slack-task-mcp auth # Authenticate
97
- npx slack-task-mcp auth status # Check auth status
98
- npx slack-task-mcp auth logout # Logout
99
- npx slack-task-mcp --help # Help
160
+ ```
161
+ この返信を添削して「レポートできました。添付します。確認お願いします。」
162
+ ```
163
+
164
+ #### タスク一覧を確認
165
+
166
+ ```
167
+ タスク一覧を見せて
168
+ ```
169
+
170
+ #### ステップを完了
171
+
172
+ ```
173
+ ステップ1を完了にして
174
+ ```
175
+
176
+ ---
177
+
178
+ ## ADHDフレンドリー設計
179
+
180
+ - **5分以内で終わるステップに分解** — 小さな達成感を積み重ねる
181
+ - **最初のステップは最も簡単なものに** — 着手のハードルを下げる
182
+ - **途中で止めてもOKな区切りを明示** — 中断しても再開しやすい
183
+ - **Slackを文脈DBとして活用** — 「あの話どうなったっけ」をClaudeに聞ける
184
+
185
+ ---
186
+
187
+ ## Tech Stack
188
+
189
+ | 技術 | 用途 |
190
+ |------|------|
191
+ | **Node.js** (ES Modules) | ランタイム |
192
+ | **MCP Protocol** | Claude Code / Desktop との通信 |
193
+ | **Claude Agent SDK** | 依頼分析・返信添削の AI 処理 |
194
+ | **Slack Web API** | Slack連携(User Token使用) |
195
+ | **Zod** | スキーマバリデーション |
196
+ | **Cloudflare Workers** | OAuth認証サーバー |
197
+
198
+ ---
199
+
200
+ ## Project Structure
201
+
202
+ ```
203
+ slack-task-mcp/
204
+ ├── packages/
205
+ │ ├── core/ # MCPサーバー本体
206
+ │ │ └── src/
207
+ │ │ ├── index.js # サーバーエントリポイント
208
+ │ │ ├── cli.js # CLIコマンド
209
+ │ │ ├── auth.js # OAuth認証
210
+ │ │ └── agents/ # Agent SDK エージェント
211
+ │ │ ├── index.js # 共通設定
212
+ │ │ ├── analyze.js # 依頼分析
213
+ │ │ └── draft-reply.js # 返信添削
214
+ │ └── oauth-worker/ # Cloudflare Workers (OAuth)
215
+ │ └── src/index.js
216
+ ├── pnpm-workspace.yaml
217
+ └── package.json
100
218
  ```
101
219
 
220
+ ---
221
+
102
222
  ## Data Storage
103
223
 
224
+ XDG Base Directory Specification に準拠した場所にデータを保存します:
225
+
226
+ ```
227
+ ~/.local/share/slack-task-mcp/
228
+ ├── credentials/
229
+ │ ├── T01234567.json # ワークスペースごとの認証情報
230
+ │ └── T98765432.json
231
+ └── tasks.json # タスクデータ
104
232
  ```
105
- ~/.slack-task-mcp/
106
- ├── credentials.json # Authentication credentials
107
- └── tasks.json # Task data
233
+
234
+ 環境変数 `XDG_DATA_HOME` が設定されている場合は、そのパスが使用されます。
235
+
236
+ ---
237
+
238
+ ## Troubleshooting
239
+
240
+ ### Slack APIエラー
241
+
242
+ ```bash
243
+ npx @ignission/slack-task-mcp auth status # 認証状態を確認
244
+ npx @ignission/slack-task-mcp auth login # 新しいワークスペースを認証
245
+ npx @ignission/slack-task-mcp auth logout # 全ワークスペースからログアウト
246
+ npx @ignission/slack-task-mcp auth logout -w mycompany # 特定のワークスペースのみログアウト
108
247
  ```
109
248
 
249
+ ### MCPサーバーが認識されない
250
+
251
+ - 設定ファイルのパスが正しいか確認
252
+ - Claude Code / Claude Desktopを再起動したか確認
253
+
254
+ ### プライベートチャンネルが読めない
255
+
256
+ - あなたが参加しているチャンネルのみ読み取り可能です
257
+
258
+ ---
259
+
260
+ ## Contributing
261
+
262
+ Issue や PR は歓迎です!
263
+
264
+ ---
265
+
110
266
  ## License
111
267
 
112
- MIT
268
+ [ISC](LICENSE)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ignission/slack-task-mcp",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "MCP Server for Slack task management with Claude Code",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -30,11 +30,23 @@
30
30
  ],
31
31
  "author": "Ignission G.K.",
32
32
  "license": "MIT",
33
+ "packageManager": "pnpm@10.26.0",
34
+ "scripts": {
35
+ "lint": "biome lint .",
36
+ "format": "biome format --write .",
37
+ "check": "biome check --write .",
38
+ "test": "vitest",
39
+ "test:run": "vitest run"
40
+ },
33
41
  "dependencies": {
34
42
  "@anthropic-ai/claude-agent-sdk": "^0.1.76",
35
43
  "@modelcontextprotocol/sdk": "^1.25.1",
36
44
  "@slack/web-api": "^7.13.0",
37
45
  "open": "^10.1.0",
38
46
  "zod": "^4.2.1"
47
+ },
48
+ "devDependencies": {
49
+ "@biomejs/biome": "^2.3.11",
50
+ "vitest": "^4.0.16"
39
51
  }
40
52
  }
package/src/auth.js CHANGED
@@ -3,10 +3,12 @@
3
3
  /**
4
4
  * OAuth 認証モジュール
5
5
  *
6
- * Cloudflare Workers を使った OAuth 認証フロー
6
+ * ハイブリッド方式: Cloudflare Worker + ローカルサーバー
7
+ * - Worker: トークン交換(Client Secretを安全に保持)
8
+ * - ローカルサーバー: コールバック受け取り(KV不要で即時反映)
7
9
  */
8
10
 
9
- import crypto from "node:crypto";
11
+ import http from "node:http";
10
12
  import open from "open";
11
13
  import {
12
14
  listWorkspaces,
@@ -18,127 +20,224 @@ import {
18
20
 
19
21
  // 定数
20
22
  const AUTH_TIMEOUT = 5 * 60 * 1000; // 5分
21
- const POLL_INTERVAL = 2000; // 2秒
23
+ const DEFAULT_PORT = 8888;
24
+ const MAX_PORT_ATTEMPTS = 10;
22
25
 
23
26
  // OAuth Worker URL
24
27
  const OAUTH_WORKER_URL =
25
28
  process.env.OAUTH_WORKER_URL || "https://slack-task-mcp-oauth.ignission.workers.dev";
26
29
 
27
30
  /**
28
- * セッション ID を生成
31
+ * team_nameからドメインを推測(フォールバック用)
29
32
  */
30
- function generateSessionId() {
31
- return crypto.randomBytes(16).toString("hex");
33
+ function extractDomainFromTeamName(teamName) {
34
+ return teamName
35
+ .toLowerCase()
36
+ .replace(/[^a-z0-9-]/g, "-")
37
+ .replace(/-+/g, "-")
38
+ .replace(/^-|-$/g, "");
32
39
  }
33
40
 
34
41
  /**
35
- * Worker にポーリングしてトークンを取得
42
+ * 空いているポートを探す
36
43
  */
37
- async function pollForToken(sessionId) {
38
- const pollUrl = `${OAUTH_WORKER_URL}/poll?session_id=${sessionId}`;
39
-
40
- const response = await fetch(pollUrl);
41
- const data = await response.json();
42
-
43
- return data;
44
+ async function findAvailablePort(startPort) {
45
+ for (let port = startPort; port < startPort + MAX_PORT_ATTEMPTS; port++) {
46
+ const available = await new Promise((resolve) => {
47
+ const server = http.createServer();
48
+ server.once("error", () => resolve(false));
49
+ server.once("listening", () => {
50
+ server.close();
51
+ resolve(true);
52
+ });
53
+ server.listen(port, "127.0.0.1");
54
+ });
55
+ if (available) return port;
56
+ }
57
+ throw new Error(`ポート ${startPort}-${startPort + MAX_PORT_ATTEMPTS - 1} が全て使用中です`);
44
58
  }
45
59
 
46
60
  /**
47
- * OAuth 認証フローを実行
48
- * Cloudflare Workers を使用
61
+ * HTMLレスポンスを生成
49
62
  */
50
- export async function authenticate(options = {}) {
51
- const noBrowser = options.noBrowser || false;
52
-
53
- // セッション ID を生成
54
- const sessionId = generateSessionId();
55
-
56
- // Worker の認証 URL を生成
57
- const authUrl = `${OAUTH_WORKER_URL}/auth?session_id=${sessionId}`;
58
-
59
- console.log("🔐 Slack OAuth 認証を開始します...");
60
- console.log("");
61
-
62
- if (noBrowser) {
63
- console.log("以下の URL をブラウザで開いてください:");
64
- console.log("");
65
- console.log(authUrl);
66
- } else {
67
- console.log("ブラウザで Slack ログイン画面を開いています...");
68
- try {
69
- await open(authUrl);
70
- } catch (_err) {
71
- console.log("");
72
- console.log("ブラウザを自動で開けませんでした。以下の URL を手動で開いてください:");
73
- console.log("");
74
- console.log(authUrl);
63
+ function htmlResponse(title, message, isError = false) {
64
+ const icon = isError ? "❌" : "✅";
65
+ const color = isError ? "#dc3545" : "#28a745";
66
+ return `
67
+ <!DOCTYPE html>
68
+ <html>
69
+ <head>
70
+ <meta charset="utf-8">
71
+ <title>${title}</title>
72
+ <style>
73
+ body {
74
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
75
+ display: flex;
76
+ justify-content: center;
77
+ align-items: center;
78
+ min-height: 100vh;
79
+ margin: 0;
80
+ background: #f5f5f5;
75
81
  }
76
- }
77
-
78
- console.log("");
79
- console.log("認証が完了するまで待機中...");
82
+ .container {
83
+ text-align: center;
84
+ padding: 40px;
85
+ background: white;
86
+ border-radius: 12px;
87
+ box-shadow: 0 2px 10px rgba(0,0,0,0.1);
88
+ }
89
+ .icon { font-size: 48px; margin-bottom: 16px; }
90
+ h1 { color: ${color}; margin: 0 0 16px 0; }
91
+ p { color: #666; margin: 0; }
92
+ </style>
93
+ </head>
94
+ <body>
95
+ <div class="container">
96
+ <div class="icon">${icon}</div>
97
+ <h1>${title}</h1>
98
+ <p>${message}</p>
99
+ </div>
100
+ </body>
101
+ </html>`;
102
+ }
80
103
 
81
- // ポーリング開始
82
- const startTime = Date.now();
104
+ /**
105
+ * ハイブリッド方式でOAuth認証を実行
106
+ * 1. ローカルサーバーを起動
107
+ * 2. Worker経由でSlack認証
108
+ * 3. Workerがトークン交換後、ローカルサーバーにリダイレクト
109
+ */
110
+ async function startHybridOAuth(options = {}) {
111
+ const noBrowser = options.noBrowser || false;
83
112
 
84
- while (Date.now() - startTime < AUTH_TIMEOUT) {
85
- await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL));
113
+ // 空きポートを探す
114
+ const port = await findAvailablePort(DEFAULT_PORT);
86
115
 
87
- try {
88
- const result = await pollForToken(sessionId);
116
+ return new Promise((resolve) => {
117
+ let server;
118
+ let timeoutId;
89
119
 
90
- if (result.status === "success") {
91
- // credentials を保存(team_domain を追加)
120
+ const cleanup = () => {
121
+ clearTimeout(timeoutId);
122
+ if (server) {
123
+ server.close();
124
+ }
125
+ };
126
+
127
+ server = http.createServer(async (req, res) => {
128
+ const url = new URL(req.url, `http://localhost:${port}`);
129
+
130
+ if (url.pathname === "/callback") {
131
+ // Workerからリダイレクトされてきたトークン情報を取得
132
+ const accessToken = url.searchParams.get("access_token");
133
+ const error = url.searchParams.get("error");
134
+
135
+ if (error) {
136
+ res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
137
+ res.end(htmlResponse("認証キャンセル", "このウィンドウを閉じてください。", true));
138
+ console.error("");
139
+ console.error(`❌ 認証がキャンセルされました: ${error}`);
140
+ cleanup();
141
+ resolve(false);
142
+ return;
143
+ }
144
+
145
+ if (!accessToken) {
146
+ res.writeHead(400, { "Content-Type": "text/html; charset=utf-8" });
147
+ res.end(htmlResponse("エラー", "トークンが取得できませんでした。", true));
148
+ console.error("");
149
+ console.error("❌ トークンが取得できませんでした");
150
+ cleanup();
151
+ resolve(false);
152
+ return;
153
+ }
154
+
155
+ // credentials を保存
156
+ const teamName = url.searchParams.get("team_name") || "Unknown";
157
+ const teamDomain = url.searchParams.get("team_domain") || extractDomainFromTeamName(teamName);
92
158
  const credentials = {
93
- access_token: result.access_token,
94
- token_type: result.token_type,
95
- scope: result.scope,
96
- user_id: result.user_id,
97
- team_id: result.team_id,
98
- team_name: result.team_name,
99
- team_domain: result.team_domain || extractDomainFromTeamName(result.team_name),
100
- created_at: result.created_at,
159
+ access_token: accessToken,
160
+ token_type: url.searchParams.get("token_type") || "user",
161
+ scope: url.searchParams.get("scope") || "",
162
+ user_id: url.searchParams.get("user_id") || "",
163
+ team_id: url.searchParams.get("team_id") || "",
164
+ team_name: teamName,
165
+ team_domain: teamDomain,
166
+ created_at: new Date().toISOString(),
101
167
  };
102
168
 
103
- await saveCredentials(credentials);
169
+ try {
170
+ await saveCredentials(credentials);
171
+
172
+ res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
173
+ res.end(htmlResponse(
174
+ "認証が完了しました!",
175
+ `ワークスペース: ${credentials.team_name}<br>このウィンドウを閉じてください。`
176
+ ));
177
+
178
+ console.log("");
179
+ console.log("✅ 認証が完了しました!");
180
+ console.log(` ワークスペース: ${credentials.team_name}`);
181
+ console.log(` ドメイン: ${credentials.team_domain}.slack.com`);
182
+ console.log(` 保存先: ${getCredentialsDir()}/${credentials.team_id}.json`);
183
+
184
+ cleanup();
185
+ resolve(true);
186
+ } catch (err) {
187
+ res.writeHead(500, { "Content-Type": "text/html; charset=utf-8" });
188
+ res.end(htmlResponse("エラー", err.message, true));
189
+ console.error("");
190
+ console.error(`❌ 認証情報の保存に失敗: ${err.message}`);
191
+ cleanup();
192
+ resolve(false);
193
+ }
194
+ } else {
195
+ res.writeHead(404);
196
+ res.end("Not Found");
197
+ }
198
+ });
104
199
 
105
- console.log("");
106
- console.log("✅ 認証が完了しました!");
107
- console.log(` ワークスペース: ${credentials.team_name}`);
108
- console.log(` ドメイン: ${credentials.team_domain}.slack.com`);
109
- console.log(` 保存先: ${getCredentialsDir()}/${credentials.team_id}.json`);
200
+ server.listen(port, "127.0.0.1", () => {
201
+ // Worker の認証 URL を生成
202
+ const authUrl = `${OAUTH_WORKER_URL}/auth?port=${port}`;
110
203
 
111
- return true;
112
- }
204
+ console.log("🔐 Slack OAuth 認証を開始します...");
205
+ console.log("");
113
206
 
114
- if (result.status === "error") {
115
- console.error("");
116
- console.error(`❌ 認証エラー: ${result.error}`);
117
- return false;
207
+ if (noBrowser) {
208
+ console.log("以下の URL をブラウザで開いてください:");
209
+ console.log("");
210
+ console.log(authUrl);
211
+ } else {
212
+ console.log("ブラウザで Slack ログイン画面を開いています...");
213
+ open(authUrl).catch(() => {
214
+ console.log("");
215
+ console.log("ブラウザを自動で開けませんでした。以下の URL を手動で開いてください:");
216
+ console.log("");
217
+ console.log(authUrl);
218
+ });
118
219
  }
119
220
 
120
- // pending の場合は継続
121
- process.stdout.write(".");
122
- } catch (_err) {
123
- // ネットワークエラーは無視して継続
124
- process.stdout.write("x");
125
- }
126
- }
127
-
128
- console.error("");
129
- console.error("❌ 認証がタイムアウトしました(5分)");
130
- return false;
221
+ console.log("");
222
+ console.log("認証が完了するまで待機中...");
223
+ console.log(`(コールバック待機: http://localhost:${port})`);
224
+ });
225
+
226
+ // タイムアウト設定
227
+ timeoutId = setTimeout(() => {
228
+ console.error("");
229
+ console.error("❌ 認証がタイムアウトしました(5分)");
230
+ cleanup();
231
+ resolve(false);
232
+ }, AUTH_TIMEOUT);
233
+ });
131
234
  }
132
235
 
133
236
  /**
134
- * team_nameからドメインを推測(フォールバック用)
237
+ * OAuth 認証フローを実行
135
238
  */
136
- function extractDomainFromTeamName(teamName) {
137
- return teamName
138
- .toLowerCase()
139
- .replace(/[^a-z0-9-]/g, "-")
140
- .replace(/-+/g, "-")
141
- .replace(/^-|-$/g, "");
239
+ export async function authenticate(options = {}) {
240
+ return startHybridOAuth(options);
142
241
  }
143
242
 
144
243
  /**
@@ -15,7 +15,7 @@ export { _getCredentialsDir as getCredentialsDir };
15
15
  * 認証情報ディレクトリを初期化
16
16
  */
17
17
  async function ensureCredentialsDir() {
18
- const dir = __getCredentialsDir();
18
+ const dir = _getCredentialsDir();
19
19
  await fs.mkdir(dir, { recursive: true });
20
20
  return dir;
21
21
  }
package/README.ja.md DELETED
@@ -1,112 +0,0 @@
1
- # slack-task-mcp
2
-
3
- Slack タスク管理 MCP サーバー for Claude Code / Claude Desktop
4
-
5
- [![npm version](https://badge.fury.io/js/slack-task-mcp.svg)](https://www.npmjs.com/package/slack-task-mcp)
6
-
7
- [English](https://github.com/ignission/slack-task-mcp/blob/main/packages/core/README.md)
8
-
9
- ## こんな人向け
10
-
11
- - Slackのメンションがたまると、どこから手を付けていいか迷う
12
- - 難しい依頼が来ると、何を聞けばいいかわからず固まる
13
- - 返信を書くのに時間がかかる
14
- - タスクを分解しても、途中で集中が切れて諦めてしまう
15
-
16
- ## インストール
17
-
18
- ```bash
19
- # 認証(初回のみ)
20
- npx slack-task-mcp auth
21
-
22
- # 認証状態を確認
23
- npx slack-task-mcp auth status
24
- ```
25
-
26
- ## Claude Desktop 設定
27
-
28
- ### macOS
29
-
30
- `~/Library/Application Support/Claude/claude_desktop_config.json`:
31
-
32
- ```json
33
- {
34
- "mcpServers": {
35
- "slack-task": {
36
- "command": "npx",
37
- "args": ["-y", "slack-task-mcp"]
38
- }
39
- }
40
- }
41
- ```
42
-
43
- ### Windows
44
-
45
- `%APPDATA%\Claude\claude_desktop_config.json`:
46
-
47
- ```json
48
- {
49
- "mcpServers": {
50
- "slack-task": {
51
- "command": "npx.cmd",
52
- "args": ["-y", "slack-task-mcp"]
53
- }
54
- }
55
- }
56
- ```
57
-
58
- 設定後、Claude Desktopを再起動してください。
59
-
60
- ## 機能
61
-
62
- | ツール | 説明 |
63
- |--------|------|
64
- | `get_slack_thread` | SlackスレッドURLからメッセージを取得 |
65
- | `analyze_request` | 依頼を分析し、目的・不明点・確認案を生成 |
66
- | `draft_reply` | 返信を添削し、ロジカルに構造化 |
67
- | `save_task` | タスクを保存(5分以内のステップに分解) |
68
- | `list_tasks` | タスク一覧を表示 |
69
- | `search_tasks` | キーワード・日付でタスクを検索 |
70
- | `complete_step` | ステップを完了にする |
71
- | `search_slack` | Slackメッセージをキーワードで検索 |
72
-
73
- ## 使い方
74
-
75
- ### Slackスレッドを分析
76
-
77
- ```
78
- このスレッドを分析して: https://xxx.slack.com/archives/C12345678/p1234567890
79
- ```
80
-
81
- ### タスクとして保存
82
-
83
- ```
84
- 5分以内のステップに分解して保存して
85
- ```
86
-
87
- ### 返信を添削
88
-
89
- ```
90
- この返信を添削して「レポートできました。確認お願いします。」
91
- ```
92
-
93
- ## CLIコマンド
94
-
95
- ```bash
96
- npx slack-task-mcp auth # 認証
97
- npx slack-task-mcp auth status # 認証状態を確認
98
- npx slack-task-mcp auth logout # ログアウト
99
- npx slack-task-mcp --help # ヘルプ
100
- ```
101
-
102
- ## データ保存先
103
-
104
- ```
105
- ~/.slack-task-mcp/
106
- ├── credentials.json # 認証情報
107
- └── tasks.json # タスクデータ
108
- ```
109
-
110
- ## ライセンス
111
-
112
- MIT