@agentiqus/slack-mcp-client 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 ADDED
@@ -0,0 +1,49 @@
1
+ # @agentiqus/slack-mcp-client
2
+
3
+ A thin stdio MCP server that connects AI tools (Cursor, Claude Desktop) to Slack through the [MCP Orchestrator](https://github.com/faruk-agentiqus/slack-mcp-orchestrator).
4
+
5
+ ## Usage
6
+
7
+ This package is not used directly. The MCP Orchestrator Slack app generates a configuration JSON for you.
8
+
9
+ 1. Install the MCP Orchestrator app in your Slack workspace
10
+ 2. Open the app's Home tab, set your permissions, and click **Generate MCP Config**
11
+ 3. Paste the generated JSON into your AI tool's MCP config file
12
+
13
+ ### Cursor
14
+
15
+ Paste into `~/.cursor/mcp.json`:
16
+
17
+ ```json
18
+ {
19
+ "mcpServers": {
20
+ "slack": {
21
+ "command": "npx",
22
+ "args": ["-y", "@agentiqus/slack-mcp-client"],
23
+ "env": {
24
+ "MCP_TOKEN": "<your-token>",
25
+ "MCP_API_URL": "https://slack-mcp-orchestrator.fly.dev/api/mcp"
26
+ }
27
+ }
28
+ }
29
+ }
30
+ ```
31
+
32
+ ### Claude Desktop
33
+
34
+ Paste into your Claude Desktop config file.
35
+
36
+ ## Environment Variables
37
+
38
+ | Variable | Description |
39
+ | ------------- | ----------------------------------------------------- |
40
+ | `MCP_TOKEN` | Per-user JWT issued by the MCP Orchestrator Slack app |
41
+ | `MCP_API_URL` | Base URL of the MCP Orchestrator API |
42
+
43
+ ## How It Works
44
+
45
+ This package runs as a local stdio process. It receives MCP tool calls from your AI tool, forwards them to the MCP Orchestrator API with your JWT, and returns the results. All permission enforcement happens server-side. Your Slack bot token never leaves the server.
46
+
47
+ ## License
48
+
49
+ MIT
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @agentiqus/slack-mcp-client
4
+ *
5
+ * A thin stdio MCP server that forwards all tool calls to the
6
+ * MCP Orchestrator HTTP API. It holds no business logic — just
7
+ * authentication forwarding and protocol bridging.
8
+ *
9
+ * Required env vars:
10
+ * MCP_TOKEN - Per-user JWT issued by the orchestrator
11
+ * MCP_API_URL - Base URL of the orchestrator API (e.g. https://host/api/mcp)
12
+ */
13
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,99 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @agentiqus/slack-mcp-client
4
+ *
5
+ * A thin stdio MCP server that forwards all tool calls to the
6
+ * MCP Orchestrator HTTP API. It holds no business logic — just
7
+ * authentication forwarding and protocol bridging.
8
+ *
9
+ * Required env vars:
10
+ * MCP_TOKEN - Per-user JWT issued by the orchestrator
11
+ * MCP_API_URL - Base URL of the orchestrator API (e.g. https://host/api/mcp)
12
+ */
13
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
14
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
15
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
16
+ // ---------------------------------------------------------------------------
17
+ // Configuration
18
+ // ---------------------------------------------------------------------------
19
+ const MCP_TOKEN = process.env.MCP_TOKEN;
20
+ const MCP_API_URL = process.env.MCP_API_URL;
21
+ if (!MCP_TOKEN) {
22
+ process.stderr.write('ERROR: MCP_TOKEN environment variable is required.\n');
23
+ process.exit(1);
24
+ }
25
+ if (!MCP_API_URL) {
26
+ process.stderr.write('ERROR: MCP_API_URL environment variable is required.\n');
27
+ process.exit(1);
28
+ }
29
+ // ---------------------------------------------------------------------------
30
+ // HTTP helpers
31
+ // ---------------------------------------------------------------------------
32
+ async function apiRequest(path, body) {
33
+ const url = `${MCP_API_URL}${path}`;
34
+ const response = await fetch(url, {
35
+ method: 'POST',
36
+ headers: {
37
+ 'Content-Type': 'application/json',
38
+ Authorization: `Bearer ${MCP_TOKEN}`,
39
+ },
40
+ body: JSON.stringify(body),
41
+ });
42
+ if (!response.ok) {
43
+ const text = await response.text();
44
+ let message;
45
+ try {
46
+ const json = JSON.parse(text);
47
+ message = json.error ?? text;
48
+ }
49
+ catch {
50
+ message = text;
51
+ }
52
+ if (response.status === 401) {
53
+ throw new Error(`Authentication failed: ${message}. Regenerate your MCP config in Slack.`);
54
+ }
55
+ if (response.status === 403) {
56
+ throw new Error(`Permission denied: ${message}`);
57
+ }
58
+ throw new Error(`API error (${response.status}): ${message}`);
59
+ }
60
+ return response.json();
61
+ }
62
+ // ---------------------------------------------------------------------------
63
+ // MCP Server
64
+ // ---------------------------------------------------------------------------
65
+ const server = new Server({ name: '@agentiqus/slack-mcp-client', version: '0.1.0' }, { capabilities: { tools: {} } });
66
+ // --- tools/list ---------------------------------------------------------------
67
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
68
+ const result = (await apiRequest('/tools/list', {}));
69
+ return { tools: result.tools };
70
+ });
71
+ // --- tools/call ---------------------------------------------------------------
72
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
73
+ try {
74
+ const result = (await apiRequest('/tools/call', {
75
+ name: request.params.name,
76
+ arguments: request.params.arguments ?? {},
77
+ }));
78
+ return { content: result.content };
79
+ }
80
+ catch (err) {
81
+ const message = err instanceof Error ? err.message : 'Unknown error';
82
+ return {
83
+ content: [{ type: 'text', text: `Error: ${message}` }],
84
+ isError: true,
85
+ };
86
+ }
87
+ });
88
+ // ---------------------------------------------------------------------------
89
+ // Start
90
+ // ---------------------------------------------------------------------------
91
+ async function main() {
92
+ const transport = new StdioServerTransport();
93
+ await server.connect(transport);
94
+ process.stderr.write('Slack MCP client connected via stdio.\n');
95
+ }
96
+ main().catch((err) => {
97
+ process.stderr.write(`Fatal: ${err}\n`);
98
+ process.exit(1);
99
+ });
package/index.ts ADDED
@@ -0,0 +1,136 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * @agentiqus/slack-mcp-client
5
+ *
6
+ * A thin stdio MCP server that forwards all tool calls to the
7
+ * MCP Orchestrator HTTP API. It holds no business logic — just
8
+ * authentication forwarding and protocol bridging.
9
+ *
10
+ * Required env vars:
11
+ * MCP_TOKEN - Per-user JWT issued by the orchestrator
12
+ * MCP_API_URL - Base URL of the orchestrator API (e.g. https://host/api/mcp)
13
+ */
14
+
15
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
16
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
17
+ import {
18
+ CallToolRequestSchema,
19
+ ListToolsRequestSchema,
20
+ } from '@modelcontextprotocol/sdk/types.js';
21
+
22
+ // ---------------------------------------------------------------------------
23
+ // Configuration
24
+ // ---------------------------------------------------------------------------
25
+
26
+ const MCP_TOKEN = process.env.MCP_TOKEN;
27
+ const MCP_API_URL = process.env.MCP_API_URL;
28
+
29
+ if (!MCP_TOKEN) {
30
+ process.stderr.write('ERROR: MCP_TOKEN environment variable is required.\n');
31
+ process.exit(1);
32
+ }
33
+ if (!MCP_API_URL) {
34
+ process.stderr.write(
35
+ 'ERROR: MCP_API_URL environment variable is required.\n'
36
+ );
37
+ process.exit(1);
38
+ }
39
+
40
+ // ---------------------------------------------------------------------------
41
+ // HTTP helpers
42
+ // ---------------------------------------------------------------------------
43
+
44
+ async function apiRequest(
45
+ path: string,
46
+ body: Record<string, unknown>
47
+ ): Promise<unknown> {
48
+ const url = `${MCP_API_URL}${path}`;
49
+ const response = await fetch(url, {
50
+ method: 'POST',
51
+ headers: {
52
+ 'Content-Type': 'application/json',
53
+ Authorization: `Bearer ${MCP_TOKEN}`,
54
+ },
55
+ body: JSON.stringify(body),
56
+ });
57
+
58
+ if (!response.ok) {
59
+ const text = await response.text();
60
+ let message: string;
61
+ try {
62
+ const json = JSON.parse(text);
63
+ message = json.error ?? text;
64
+ } catch {
65
+ message = text;
66
+ }
67
+
68
+ if (response.status === 401) {
69
+ throw new Error(
70
+ `Authentication failed: ${message}. Regenerate your MCP config in Slack.`
71
+ );
72
+ }
73
+ if (response.status === 403) {
74
+ throw new Error(`Permission denied: ${message}`);
75
+ }
76
+ throw new Error(`API error (${response.status}): ${message}`);
77
+ }
78
+
79
+ return response.json();
80
+ }
81
+
82
+ // ---------------------------------------------------------------------------
83
+ // MCP Server
84
+ // ---------------------------------------------------------------------------
85
+
86
+ const server = new Server(
87
+ { name: '@agentiqus/slack-mcp-client', version: '0.1.0' },
88
+ { capabilities: { tools: {} } }
89
+ );
90
+
91
+ // --- tools/list ---------------------------------------------------------------
92
+
93
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
94
+ const result = (await apiRequest('/tools/list', {})) as {
95
+ tools: Array<{
96
+ name: string;
97
+ description: string;
98
+ inputSchema: Record<string, unknown>;
99
+ }>;
100
+ };
101
+ return { tools: result.tools };
102
+ });
103
+
104
+ // --- tools/call ---------------------------------------------------------------
105
+
106
+ server.setRequestHandler(CallToolRequestSchema, async request => {
107
+ try {
108
+ const result = (await apiRequest('/tools/call', {
109
+ name: request.params.name,
110
+ arguments: request.params.arguments ?? {},
111
+ })) as { content: Array<{ type: string; text: string }> };
112
+
113
+ return { content: result.content };
114
+ } catch (err) {
115
+ const message = err instanceof Error ? err.message : 'Unknown error';
116
+ return {
117
+ content: [{ type: 'text', text: `Error: ${message}` }],
118
+ isError: true,
119
+ };
120
+ }
121
+ });
122
+
123
+ // ---------------------------------------------------------------------------
124
+ // Start
125
+ // ---------------------------------------------------------------------------
126
+
127
+ async function main(): Promise<void> {
128
+ const transport = new StdioServerTransport();
129
+ await server.connect(transport);
130
+ process.stderr.write('Slack MCP client connected via stdio.\n');
131
+ }
132
+
133
+ main().catch(err => {
134
+ process.stderr.write(`Fatal: ${err}\n`);
135
+ process.exit(1);
136
+ });
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@agentiqus/slack-mcp-client",
3
+ "version": "0.1.0",
4
+ "description": "Thin stdio MCP server that proxies Slack operations through the MCP Orchestrator API",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "slack-mcp-client": "dist/index.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "start": "node dist/index.js"
13
+ },
14
+ "keywords": [
15
+ "mcp",
16
+ "slack",
17
+ "model-context-protocol",
18
+ "ai-tools",
19
+ "cursor",
20
+ "claude"
21
+ ],
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "https://github.com/faruk-agentiqus/slack-mcp-orchestrator.git",
25
+ "directory": "packages/slack-mcp-client"
26
+ },
27
+ "homepage": "https://github.com/faruk-agentiqus/slack-mcp-orchestrator#readme",
28
+ "dependencies": {
29
+ "@modelcontextprotocol/sdk": "^1.26.0",
30
+ "zod": "^3.25.0"
31
+ },
32
+ "devDependencies": {
33
+ "typescript": "^5.9.3"
34
+ },
35
+ "engines": {
36
+ "node": ">=18"
37
+ },
38
+ "license": "MIT"
39
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "esnext",
4
+ "module": "nodenext",
5
+ "outDir": "./dist",
6
+ "strict": true,
7
+ "declaration": true
8
+ },
9
+ "include": [
10
+ "index.ts"
11
+ ]
12
+ }