Skip to content

Instantly share code, notes, and snippets.

@nisanthchunduru
Last active July 14, 2026 07:54
Show Gist options
  • Select an option

  • Save nisanthchunduru/e9a462230c682d4bfee7e9b5c61b1b1e to your computer and use it in GitHub Desktop.

Select an option

Save nisanthchunduru/e9a462230c682d4bfee7e9b5c61b1b1e to your computer and use it in GitHub Desktop.
Codex Slack Proxy MCP server
# ~/.codex/config.toml
# ...
```
[mcp_servers.slack-mcp]
command = "node"
args = ["/Users/nisanth/repos/CodexSlackMCPProxyServer/src/index.js"]
```
# ...
#!/usr/bin/env node
import { spawn } from "node:child_process";
import { homedir } from "node:os";
import { join } from "node:path";
import { transformJsonRpcLine } from "./transform.js";
const command =
process.env.SLACK_MCP_COMMAND ?? join(homedir(), ".toolbox", "bin", "aim");
const args = ["mcp", "start-server", "slack-mcp"];
const debug = process.env.CODEX_SLACK_MCP_DEBUG === "1";
const child = spawn(command, args, {
env: process.env,
stdio: ["pipe", "pipe", "pipe"],
});
let forwardedSignal;
process.stdin.pipe(child.stdin);
child.stderr.pipe(process.stderr);
let stdoutBuffer = "";
function writeLine(line, newline = "") {
const transformed = transformJsonRpcLine(line);
if (debug && transformed.stripped > 0) {
process.stderr.write(
`[codex-slack-mcp-server] stripped ${transformed.stripped} content annotation(s)\n`,
);
}
process.stdout.write(transformed.line + newline);
}
child.stdout.setEncoding("utf8");
child.stdout.on("data", (chunk) => {
stdoutBuffer += chunk;
let newlineIndex;
while ((newlineIndex = stdoutBuffer.indexOf("\n")) !== -1) {
const rawLine = stdoutBuffer.slice(0, newlineIndex);
stdoutBuffer = stdoutBuffer.slice(newlineIndex + 1);
const hasCarriageReturn = rawLine.endsWith("\r");
const line = hasCarriageReturn ? rawLine.slice(0, -1) : rawLine;
writeLine(line, hasCarriageReturn ? "\r\n" : "\n");
}
});
child.stdout.on("end", () => {
if (stdoutBuffer) {
writeLine(stdoutBuffer);
stdoutBuffer = "";
}
});
child.on("error", (error) => {
process.stderr.write(
`[codex-slack-mcp-server] failed to start Slack MCP: ${error.message}\n`,
);
process.exitCode = 1;
});
child.on("exit", (code, signal) => {
if (forwardedSignal) {
process.removeAllListeners(forwardedSignal);
process.kill(process.pid, forwardedSignal);
return;
}
if (signal) {
process.removeAllListeners(signal);
process.kill(process.pid, signal);
return;
}
process.exitCode = code ?? 1;
});
for (const signal of ["SIGINT", "SIGTERM"]) {
process.on(signal, () => {
if (!child.killed) {
forwardedSignal = signal;
child.kill(signal);
}
});
}
export function stripContentAnnotations(message) {
const content = message?.result?.content;
if (!Array.isArray(content)) {
return 0;
}
let stripped = 0;
for (const item of content) {
if (
item &&
typeof item === "object" &&
Object.prototype.hasOwnProperty.call(item, "annotations")
) {
delete item.annotations;
stripped += 1;
}
}
return stripped;
}
export function transformJsonRpcLine(line) {
if (!line.trim()) {
return { line, stripped: 0 };
}
try {
const message = JSON.parse(line);
const stripped = stripContentAnnotations(message);
return {
line: stripped > 0 ? JSON.stringify(message) : line,
stripped,
};
} catch {
return { line, stripped: 0 };
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment