证据快照复核于 2026-09-03GitHub 数据核对日期: 2026-08-21
来源已审查独立 Skill开发工具终端 Profile

mobius-mcp-stdio-invocation

通过 JSON-RPC 在 Shell 脚本或 CI 中直接调用任何 stdio MCP 服务的工具。

快速了解

它能做什么

通过 JSON-RPC 在 Shell 脚本或 CI 中直接调用任何 stdio MCP 服务的工具。

本站提供的是中文说明,不代表该项目或 Plugin 自身提供中文界面;语言支持请以上游文档为准。

能力
开发工具集成自动化终端 UI

选择前先看

该技能提供可直接改造的 Python 客户端模式:启动 stdio MCP 服务、发送 initialize 与 initialized 消息、列出可用工具、调用工具并读取响应。还包含 uvx、npx 启动示例,以及 MiniMax MCP 的完整示例。

适合谁

需要在 Shell、CI 运行器、工作节点或未预加载 MCP 工具的会话中访问 MCP 工具的开发者。

常见任务

  • 在将 stdio MCP 服务加入运行环境前先进行测试。
  • 从 CI 任务或 Shell 脚本调用 MCP 工具。
  • 列出 MCP 服务的工具 schema 并调用选定工具。
  • 排查 JSON-RPC 握手、超时、环境变量和响应解析问题。

权限与数据

会启动本地子进程,并通过标准输入和标准输出交换 JSON-RPC 消息。

权限
  • 需要执行所选 MCP 服务启动器及其软件包的权限。
  • 仅在目标服务需要时读写相应位置,例如配置的输出目录。
数据处理
  • 工具参数和服务响应会经过本地脚本的标准输入/输出流。
  • 环境变量可能包含服务专用凭据。
外部服务
  • 所选 MCP 服务可能会连接其自身的外部服务;MiniMax 示例使用具备网页搜索能力的服务。
凭据
  • 通用客户端模式本身不要求凭据。
  • 具体 MCP 服务可能需要凭据;MiniMax 示例需要 MINIMAX_API_KEY。

局限

  • 仅适用于 stdio 传输;HTTP/SSE MCP 服务需要不同的客户端方案。
  • 使用 OAuth 或动态注册的服务可能需要本技能未涵盖的令牌刷新处理。
  • 文档中的纯 Shell 示例明确不如 Python 客户端稳健。
  • 根据所提供的许可证,商业使用仓库软件需要另行取得商业许可证。

DSHub 已核对

  • 固定 GitHub 提交中的技能文档已被采集。
  • 文档包含作者声明已端到端验证的 MiniMax MCP 示例。

DSHub 未核对

  • DSHub 未执行该客户端、安装软件包或验证任何目标 MCP 服务。
  • 未独立验证其与特定 MCP 服务、凭据和传输方式的兼容性。

固定版本安装

主要操作

这个独立 Skill没有 DSH Plugin 安装操作,请根据源码文档使用真实交付方式。

访问源码项目

维护者原文

Skill 使用说明

查看 commit 1eb8750 对应的 SKILL.md
维护者编写的上游内容原文于 2026/8/30skills/mobius-mcp-stdio-invocation/SKILL.md 获取,正文和仓库相对媒体固定到 commit 1eb8750d2d90,内容哈希为 a73c4b1bea77。以下是未经 DSHub 翻译的上游原文,语言可能与当前页面不同;第三方托管的 badge 可能独立更新。

name: mobius-mcp-stdio-invocation description: Invoke any MCP (Model Context Protocol) server directly from the CLI via stdio JSON-RPC, with no Claude Code / harness dependency. Use when you need to call MCP tools (web search, image understanding, file ops, custom tools) from a shell script, CI job, or a session that doesn't have the MCP auto-loaded. Covers: installing uv/uvx (or npx), spawning the server, the JSON-RPC 2.0 handshake, tools/list discovery, tools/call invocation, and result parsing — with the MiniMax minimax-coding-plan-mcp package as a verified worked example.

MCP stdio invocation from the CLI

MCP servers speak JSON-RPC 2.0 over stdio — the server's stdin is the request stream, stdout is the response stream, stderr is for human logs. Any process that can spawn a subprocess and read/write its stdio can be an MCP client. You do not need Claude Code, Cursor, or any harness to use them.

This SKILL is the recipe for "I want to call MCP tool X, from a shell, right now."

When to use

  • Your session has no mcp__* tools registered (e.g. a CI runner, a worker session, an ad-hoc bash turn).
  • You want to script MCP tool calls in a pipeline.
  • The MCP server supports stdio transport (most do; SSE/HTTP transports are a separate path).
  • You want to verify an MCP works before registering it with claude mcp add.

If the server is already loaded into your harness as mcp__server__tool, just call it directly — don't reinvent the stdio pipe.

Protocol summary (MCP 2024-11-05)

Three-step handshake, then arbitrary tools/list / tools/call:

1.  request  initialize          → response with serverInfo + capabilities
2.  notify    notifications/initialized  (no response, just a fire-and-forget)
3.  request  tools/list          → response with tool schemas
    request  tools/call          → response with content blocks

All frames are single-line JSON. One request → one response, matched by id. Notifications (no id) get no reply. Use select() or non-blocking reads to avoid deadlock when the server logs to stderr.

Frame shapes

// request
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{...}}

// notification
{"jsonrpc":"2.0","method":"notifications/initialized","params":{}}

// success response
{"jsonrpc":"2.0","id":1,"result":{...}}

// error response
{"jsonrpc":"2.0","id":1,"error":{"code":-32601,"message":"Method not found"}}

tools/call result is result.content — an array of content blocks. Text blocks are stringified JSON that you must re-parse:

{"result":{"content":[{"type":"text","text":"{\n  \"organic\": [...]\n}"}]}}

Install the launcher

MCP servers are usually published as a Python or Node package with a command entry point.

Ecosystem Install Spawn command
PyPI (uvx) curl -LsSf https://astral.sh/uv/install.sh | sh (one-time) uvx --from <pkg> <entrypoint> -y
npm (npx) comes with Node npx -y <pkg>

uvx and npx both (1) create an ephemeral venv/cache, (2) install the package on first run, (3) execute the entrypoint, (4) clean up on exit. The -y flag auto-confirms any "install?" prompt.

After installing uvx, verify with which uvx → expect a path like /home/<user>/.local/bin/uvx.

Generic Python harness

Drop this into a script and point it at any stdio MCP server. Replace COMMAND, ENV, and the tool name you want to call.

# mcp_invoke.py — minimal MCP stdio client
import json, os, subprocess, sys, time, select

COMMAND = ["uvx", "--from", "<PACKAGE>", "<ENTRYPOINT>", "-y"]  # e.g. uvx --from minimax-coding-plan-mcp minimax-coding-plan-mcp -y
ENV_OVERRIDES = {  # MCP-specific env vars; the server reads these
    # "API_KEY_ENV_NAME": "sk-...",
    # "BASE_URL_ENV_NAME": "https://...",
}

def call_tool(name, arguments, *, timeout=60):
    env = os.environ.copy()
    env.update(ENV_OVERRIDES)

    proc = subprocess.Popen(
        COMMAND,
        stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
        env=env, text=True, bufsize=1,
    )

    def send(req):
        proc.stdin.write(json.dumps(req) + "\n"); proc.stdin.flush()
    def recv(timeout_s=timeout):
        end = time.time() + timeout_s
        while time.time() < end:
            r,_,_ = select.select([proc.stdout], [], [], 0.5)
            if r:
                line = proc.stdout.readline()
                if line: return json.loads(line)
        raise TimeoutError("no MCP response")

    try:
        send({"jsonrpc":"2.0","id":1,"method":"initialize","params":{
            "protocolVersion":"2024-11-05",
            "capabilities":{},
            "clientInfo":{"name":"mcp-invoke","version":"0.1.0"},
        }})
        recv()                                # initialize result

        send({"jsonrpc":"2.0","method":"notifications/initialized","params":{}})

        send({"jsonrpc":"2.0","id":2,"method":"tools/call","params":{
            "name": name, "arguments": arguments,
        }})
        return recv()
    finally:
        proc.terminate()
        try: proc.wait(timeout=5)
        except subprocess.TimeoutExpired: proc.kill()

if __name__ == "__main__":
    result = call_tool("<tool_name>", {"<arg>": "<value>"})
    print(json.dumps(result, ensure_ascii=False, indent=2))

Discovery variant: list tools first

If you don't know the tool names, swap the tools/call for tools/list:

send({"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}})
tools_resp = recv()
for t in tools_resp["result"]["tools"]:
    print(t["name"], "—", t.get("description","")[:80])

Then drive tools/call based on what you see.

Worked example: MiniMax Token Plan MCP

Verified end-to-end on 2026-06-10 in an imac-test session that had no MCP auto-loaded.

Field Value
Package minimax-coding-plan-mcp (PyPI)
Server Minimax v1.27.2, protocol 2024-11-05
Env vars MINIMAX_API_KEY (required), MINIMAX_API_HOST (default https://api.minimaxi.com), MINIMAX_MCP_BASE_PATH (local output dir, must exist + writable), MINIMAX_API_RESOURCE_MODE (url / local)
Tools web_search(query), understand_image(prompt, image_url)

Spawn command:

MINIMAX_API_KEY="sk-cp-..." \
MINIMAX_API_HOST="https://api.minimaxi.com" \
MINIMAX_MCP_BASE_PATH="/tmp/mcp-out" \
MINIMAX_API_RESOURCE_MODE="url" \
uvx --from minimax-coding-plan-mcp minimax-coding-plan-mcp -y

Call shape (web_search):

{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{
  "name":"web_search",
  "arguments":{"query":"<3-5 keywords, include date for time-sensitive>"}
}}

Response shape (web_search result is a stringified JSON inside content[0].text):

{
  "result": {
    "content": [
      {"type": "text", "text": "{\"organic\":[{\"title\":...,\"link\":...,\"snippet\":...,\"date\":...}],\"related_searches\":[...],\"base_resp\":{...}}"}
    ]
  }
}

So: r["result"]["content"][0]["text"]json.loads(...)organic[].

Real latency observation: web_search for a current-events query round-trips in 5–15 s (it's a search backend call, not local compute).

Recipe: register for future sessions (optional)

Once you've verified the server works over stdio, you can pin it to user-level Claude Code so future sessions auto-load it. The update-config skill (or claude mcp add on the CLI) writes ~/.claude.json:

claude mcp add -s user MiniMax \
  --env MINIMAX_API_KEY=sk-cp-... \
  --env MINIMAX_API_HOST=https://api.minimaxi.com \
  -- uvx minimax-coding-plan-mcp -y

After this, new sessions get mcp__MiniMax__web_search and mcp__MiniMax__understand_image tools. The current session won't pick it up — MCPs are loaded at Claude Code startup.

Common pitfalls

  • No response, then timeout — server is waiting for the initialized notification and you didn't send it. Always send the notification between initialize and any other request.
  • Method not found (-32601) — wrong protocol version in initialize. 2024-11-05 is the current default; some older servers want 2024-10-07 or 2025-03-26. Check the server's docs.
  • Response looks like a dict, not a list — you got a result object; the actual tool output is result.content[0].text (always a string, often JSON inside).
  • Stderr is silent — many MCP servers log useful info (retry counts, rate limits) to stderr. Tee it: stderr=subprocess.PIPE and read on timeout.
  • Env var not picked up — servers usually read env only at startup. Set them before spawning. Mutating os.environ after Popen is too late.
  • uvx not found — install with the one-liner above; it lands in ~/.local/bin/uvx, which is not on every shell's default PATH. Prefix export PATH="$HOME/.local/bin:$PATH".
  • Server hangs after first call — JSON-RPC needs newline-delimited frames. text=True, bufsize=1 and a "\n" after every json.dumps(req) are mandatory.
  • Output files cluttering the repoMINIMAX_MCP_BASE_PATH defaults to ./.trash for the MiniMax MCP; point it at /tmp/... or your .imac/scratch/ to keep the project clean.
  • Auth key leakage in logs — many MCP servers log the env var name (not the value) on startup. Fine, but don't set -x the parent shell if the value is sensitive.

Pattern: shell-only quick call

If you don't want a Python script, you can drive the JSON-RPC stream straight from bash with jq + heredocs. Less robust (no error handling) but useful for one-offs:

KEY="sk-cp-..."
{
  echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"cli","version":"0"}}}'
  echo '{"jsonrpc":"2.0","method":"notifications/initialized","params":{}}'
  echo '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"web_search","arguments":{"query":"today news"}}}'
  sleep 20
} | MINIMAX_API_KEY="$KEY" MINIMAX_API_HOST="https://api.minimaxi.com" \
  MINIMAX_MCP_BASE_PATH="/tmp/mcp-out" \
  uvx --from minimax-coding-plan-mcp minimax-coding-plan-mcp -y \
  2>/dev/null | head -1

The first line of stdout is the initialize response; you'll need a longer-lived pipe (e.g. coproc or a temp file per request) to map request ids to responses properly. Use the Python harness for anything non-trivial.

Generalizing beyond MiniMax

The exact same recipe works for any stdio MCP server. Substitutions:

What you change Where
COMMAND list ["uvx", "--from", "<pkg>", "<entry>", "-y"] or ["npx", "-y", "<pkg>"]
ENV_OVERRIDES whatever env vars the server's docs list (auth keys, base URLs, output paths)
name in tools/call the tool name from tools/list
arguments in tools/call the JSON schema from tools/list

If tools/list returns nested argument schemas (objects, enums, arrays), feed them straight into the arguments dict — the harness serializes them for you.

When not to use this

  • The MCP server is HTTP/SSE transport, not stdio. The handshake is different; you'll need an HTTP client.
  • The server requires OAuth / dynamic client registration. Stdio servers usually take a static API key; OAuth servers (e.g. some Google/Microsoft ones) need a token-refresh loop.
  • The tool produces binary outputs (audio, video, images). Stdio JSON-RPC can carry base64, but it's clumsy — for big media, prefer the underlying HTTP API directly.
  • You're already in a session where the MCP is auto-loaded. Just use the registered mcp__server__tool — no subprocess needed.

有意识地管理

安装与管理

前置条件与目标 Profile

目标 终端 Profile

交付方式 Skill 文件 — https://raw.githubusercontent.com/nutshellai-tech/mobius/1eb8750d2d9012e1f50a18f7c60c2ad040c04889/skills/mobius-mcp-stdio-invocation/SKILL.md

兼容性与访问范围

Works with stdio-transport MCP servers; no harness is required Not declared in supplied evidence

检查兼容性证据

风险事实

license

Commercial use requires a separate license

证据
凭据

Some MCP servers may require API keys supplied as environment variables

证据
证据与编辑审查Manifest、Bundle patch、分发与新鲜度

不可变证据

审查状态与源码活动

人工已批准

在核对来源内容和不可变发布记录后,已由人工批准发布。AI 参与了内容草稿生成,最终发布决定由人工完成。

人工审查于 2026/9/4 UTC 11:38GitHub 事实核对日期: 2026/9/3 UTC 15:47

自当前证据基线以来,没有记录到重要源码变化。

下一步

比较生态 Artifact 类型

订阅重要变化: mobius-mcp-stdio-invocation