Skip to content

SIGKILL / crash when MCP client sends elicitation capability in initialize payload (protocol version 2025-11-25) #53

Description

@swarthyplacebo

Summary

@fangjunjie/ssh-mcp-server v1.8.3 crashes with SIGKILL when the MCP initialize request includes the elicitation capability, which is standard in MCP protocol version 2025-11-25. This affects all modern MCP clients using the current spec, including Claude Desktop, Anthropic's Antigravity (Gemini CLI), and any client that negotiates 2025-11-25.

Affected Version

@fangjunjie/ssh-mcp-server v1.8.3 (latest as of 2026-06-04)

Reproduction

Send a 2025-11-25-spec initialize payload to the server:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2025-11-25",
    "capabilities": {
      "roots": { "listChanged": true },
      "sampling": {},
      "elicitation": {}
    },
    "clientInfo": { "name": "test-client", "version": "1.0" }
  }
}

Result: Process exits with SIGKILL immediately. No error output, no graceful shutdown.

Expected: Server responds with its own capabilities and negotiates the protocol version normally (ignoring or acknowledging elicitation as an unknown/unsupported capability).

Impact

Any MCP client implementing protocol version 2025-11-25 will be unable to connect to this server. Claude Desktop and Gemini CLI (Antigravity) both send elicitation: {} in their initialize payloads as of mid-2025.

Workaround Applied

We deployed a thin Node.js shim that intercepts the initialize payload, strips the elicitation field, and forwards the modified payload to the binary:

// elicitation-shim.js
const { spawn } = require('child_process');
const readline = require('readline');

const server = spawn('/usr/local/bin/ssh-mcp-server', process.argv.slice(2), {
  stdio: ['pipe', 'pipe', 'inherit']
});

const rl = readline.createInterface({ input: process.stdin });

rl.on('line', (line) => {
  try {
    const msg = JSON.parse(line);
    if (msg.method === 'initialize' && msg.params?.capabilities?.elicitation) {
      delete msg.params.capabilities.elicitation;
    }
    server.stdin.write(JSON.stringify(msg) + '\n');
  } catch {
    server.stdin.write(line + '\n');
  }
});

server.stdout.on('data', (data) => process.stdout.write(data));
server.on('exit', (code) => process.exit(code ?? 0));

This restores connectivity but requires maintaining a custom Docker image. The fix should be in the server itself.

Suggested Fix

In the initialize handler, treat unrecognized capability keys (including elicitation) as no-ops rather than allowing them to cause a crash. The server should respond with only the capabilities it supports and ignore unknown ones per the MCP spec.


Co-authored by Claude Sonnet 4.6

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions