afk-ask-mcp 0.1.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/README.md +44 -0
- package/dist/askQuestion.d.ts +1 -0
- package/dist/askQuestion.js +32 -0
- package/dist/discord.d.ts +3 -0
- package/dist/discord.js +33 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +12 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.js +18 -0
- package/package.json +40 -0
package/README.md
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# afk-ask-mcp
|
|
2
|
+
|
|
3
|
+
An MCP server that sends questions to users via Discord and waits for their replies.
|
|
4
|
+
|
|
5
|
+
## Environment Variables
|
|
6
|
+
|
|
7
|
+
| Variable | Description |
|
|
8
|
+
| -------------------------------- | ---------------------------- |
|
|
9
|
+
| `AFK_ASK_MCP_DISCORD_TOKEN` | Discord Bot token |
|
|
10
|
+
| `AFK_ASK_MCP_DISCORD_CHANNEL_ID` | Channel ID to send questions |
|
|
11
|
+
|
|
12
|
+
## Usage
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
claude mcp add afk-ask \
|
|
16
|
+
--env AFK_ASK_MCP_DISCORD_TOKEN=your-bot-token \
|
|
17
|
+
--env AFK_ASK_MCP_DISCORD_CHANNEL_ID=your-channel-id \
|
|
18
|
+
-- npx -y afk-ask-mcp
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Tool
|
|
22
|
+
|
|
23
|
+
### `afk_ask`
|
|
24
|
+
|
|
25
|
+
Sends a question to the configured Discord channel and waits for a reply.
|
|
26
|
+
|
|
27
|
+
**Parameters:**
|
|
28
|
+
|
|
29
|
+
- `question` (string): The question to ask the user
|
|
30
|
+
|
|
31
|
+
**Returns:** The content of the reply message
|
|
32
|
+
|
|
33
|
+
## Discord Bot Setup
|
|
34
|
+
|
|
35
|
+
1. Create a bot at [Discord Developer Portal](https://discord.com/developers/applications)
|
|
36
|
+
2. Enable **MESSAGE CONTENT INTENT** under Bot settings (Privileged Gateway Intents)
|
|
37
|
+
3. Invite the bot to your server with the following permissions:
|
|
38
|
+
- Send Messages
|
|
39
|
+
- Read Message History
|
|
40
|
+
- View Channel
|
|
41
|
+
|
|
42
|
+
## License
|
|
43
|
+
|
|
44
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function askQuestion(question: string): Promise<string>;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { getDiscordClient, getTargetChannel } from "./discord.js";
|
|
2
|
+
export async function askQuestion(question) {
|
|
3
|
+
const client = await getDiscordClient();
|
|
4
|
+
const channel = await getTargetChannel();
|
|
5
|
+
// 質問メッセージを送信
|
|
6
|
+
const sentMessage = await channel.send(question);
|
|
7
|
+
// リプライを待機
|
|
8
|
+
const answer = await waitForReply(client, sentMessage);
|
|
9
|
+
return answer;
|
|
10
|
+
}
|
|
11
|
+
function waitForReply(client, targetMessage) {
|
|
12
|
+
return new Promise((resolve) => {
|
|
13
|
+
const handler = (message) => {
|
|
14
|
+
// リプライかどうかを確認
|
|
15
|
+
if (!message.reference) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
// 送信したメッセージへのリプライかを確認
|
|
19
|
+
if (message.reference.messageId !== targetMessage.id) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
// Bot 自身のメッセージは無視
|
|
23
|
+
if (message.author.bot) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
// リスナーを解除して結果を返す
|
|
27
|
+
client.off("messageCreate", handler);
|
|
28
|
+
resolve(message.content);
|
|
29
|
+
};
|
|
30
|
+
client.on("messageCreate", handler);
|
|
31
|
+
});
|
|
32
|
+
}
|
package/dist/discord.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Client, GatewayIntentBits } from "discord.js";
|
|
2
|
+
let client = null;
|
|
3
|
+
function getEnvVar(name) {
|
|
4
|
+
const value = process.env[name];
|
|
5
|
+
if (!value) {
|
|
6
|
+
throw new Error(`環境変数 ${name} が設定されていません`);
|
|
7
|
+
}
|
|
8
|
+
return value;
|
|
9
|
+
}
|
|
10
|
+
export async function getDiscordClient() {
|
|
11
|
+
if (client) {
|
|
12
|
+
return client;
|
|
13
|
+
}
|
|
14
|
+
const token = getEnvVar("AFK_ASK_MCP_DISCORD_TOKEN");
|
|
15
|
+
client = new Client({
|
|
16
|
+
intents: [
|
|
17
|
+
GatewayIntentBits.Guilds,
|
|
18
|
+
GatewayIntentBits.GuildMessages,
|
|
19
|
+
GatewayIntentBits.MessageContent,
|
|
20
|
+
],
|
|
21
|
+
});
|
|
22
|
+
await client.login(token);
|
|
23
|
+
return client;
|
|
24
|
+
}
|
|
25
|
+
export async function getTargetChannel() {
|
|
26
|
+
const channelId = getEnvVar("AFK_ASK_MCP_DISCORD_CHANNEL_ID");
|
|
27
|
+
const discordClient = await getDiscordClient();
|
|
28
|
+
const channel = await discordClient.channels.fetch(channelId);
|
|
29
|
+
if (!channel || !channel.isTextBased()) {
|
|
30
|
+
throw new Error(`チャンネル ${channelId} が見つからないか、テキストチャンネルではありません`);
|
|
31
|
+
}
|
|
32
|
+
return channel;
|
|
33
|
+
}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
|
+
import { createServer } from "./server.js";
|
|
4
|
+
async function main() {
|
|
5
|
+
const server = createServer();
|
|
6
|
+
const transport = new StdioServerTransport();
|
|
7
|
+
await server.connect(transport);
|
|
8
|
+
}
|
|
9
|
+
main().catch((error) => {
|
|
10
|
+
console.error("Failed to start MCP server:", error);
|
|
11
|
+
process.exit(1);
|
|
12
|
+
});
|
package/dist/server.d.ts
ADDED
package/dist/server.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { askQuestion } from "./askQuestion.js";
|
|
4
|
+
export function createServer() {
|
|
5
|
+
const server = new McpServer({
|
|
6
|
+
name: "afk-ask-mcp",
|
|
7
|
+
version: "1.0.0",
|
|
8
|
+
});
|
|
9
|
+
server.tool("afk_ask", "ユーザーに質問を送信し、Discord 経由で応答を待つ", {
|
|
10
|
+
question: z.string().describe("ユーザーへの質問内容"),
|
|
11
|
+
}, async ({ question }) => {
|
|
12
|
+
const answer = await askQuestion(question);
|
|
13
|
+
return {
|
|
14
|
+
content: [{ type: "text", text: answer }],
|
|
15
|
+
};
|
|
16
|
+
});
|
|
17
|
+
return server;
|
|
18
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "afk-ask-mcp",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "MCP server for asking questions via Discord",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"afk-ask-mcp": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsc",
|
|
15
|
+
"dev": "tsx src/index.ts",
|
|
16
|
+
"fix": "prettier --write .",
|
|
17
|
+
"lint": "tsc --noEmit",
|
|
18
|
+
"prepublishOnly": "npm run build"
|
|
19
|
+
},
|
|
20
|
+
"keywords": [
|
|
21
|
+
"mcp",
|
|
22
|
+
"discord",
|
|
23
|
+
"model-context-protocol"
|
|
24
|
+
],
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
28
|
+
"discord.js": "^14.0.0",
|
|
29
|
+
"zod": "^3.25.0"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@types/node": "^22.0.0",
|
|
33
|
+
"prettier": "^3.7.4",
|
|
34
|
+
"tsx": "^4.0.0",
|
|
35
|
+
"typescript": "^5.0.0"
|
|
36
|
+
},
|
|
37
|
+
"engines": {
|
|
38
|
+
"node": ">=20"
|
|
39
|
+
}
|
|
40
|
+
}
|