Skip to main content
Glama
Prodius-AI

prodius-mcp

Official
by Prodius-AI

prodius-mcp

PyPI Python License: MIT

Let your AI agents reach you by voice.

prodius-mcp is a lightweight MCP server that bridges any MCP-capable AI tool (Claude Code, Cursor, Windsurf, Codex CLI, and more) to the Prodius desktop app. When an agent needs your input, a popup appears on your screen — wherever you are — and you answer by voice. No switching back to the terminal.

It's a thin stdio shim: standard library only, no third-party dependencies, fast startup, and it talks only to the Prodius desktop app running locally on 127.0.0.1.

This package needs the Prodius desktop app. On its own it does nothing: the popup, the voice capture and the transcription all happen in the desktop app. Get it at prodius.ai/download.

Requirements

  • Python 3.10+

  • The Prodius desktop app installed and running, with Voice Bridge enabled in settings.

Related MCP server: hermes-mcp-bridge

Install

Published on PyPI as prodius-mcp:

pip install prodius-mcp

If prodius-mcp isn't found afterwards, make sure the Python environment you installed into is on your PATH — or use pipx install prodius-mcp.

Connect your tool

Claude Code

The quickest start is one command:

claude mcp add prodius -- prodius-mcp

For the full experience (correct agent label in the modal header, automatic conversation reset on /clear), add the block below to your ~/.claude/settings.json instead. The claude mcp add shortcut omits both pieces.

{
  "env": { "PRODIUS_AGENT_NAME": "Claude Code" },
  "mcpServers": {
    "prodius": {
      "command": "prodius-mcp",
      "args": [],
      "env": { "PRODIUS_AGENT_NAME": "Claude Code" }
    }
  },
  "hooks": {
    "SessionStart": [
      { "matcher": "*", "hooks": [{ "type": "command", "command": "prodius-mcp-reset" }] }
    ]
  }
}

The SessionStart hook calls prodius-mcp-reset whenever you run /clear or open a new session so Prodius doesn't carry stale context across conversations. It leaves the conversation alone when a session is resumed, compacted or forked. The top-level env makes the agent name visible to that hook.

To enable voice push (microphone stays available between questions so you can speak to Claude anytime, not just when it asks), start Claude with the channels flag:

claude --dangerously-load-development-channels server:prodius

Cursor / Windsurf / any MCP client

Add to your client's MCP config (e.g. ~/.cursor/mcp.json):

{
  "mcpServers": {
    "prodius": { "command": "prodius-mcp" }
  }
}

Codex CLI

[mcp_servers.prodius]
command = "prodius-mcp"
env = { PRODIUS_AGENT_NAME = "Codex CLI" }

Full setup instructions for each tool, including session-reset hooks and optional voice push, live at prodius.ai/connect.

Tools exposed

Tool

What it does

ask_user

Pops a question on your screen and captures your spoken (or typed) reply. Supports optional clickable answer buttons (max 4), an expandable Markdown detail body, and a task_name label so you can tell concurrent sessions apart. Blocks until you answer or timeout_s expires (default 120 s, max 600).

notify

Shows you a short message in a desktop overlay, fire-and-forget. Takes message, optional Markdown detail, and a level of info / success / error.

How often the agent reaches out is your call, not the server's. Without instructions it only contacts you when it is blocked (an approval or a decision). Tell it otherwise in your CLAUDE.md / AGENTS.md; presets are at prodius.ai/connect.

Sub-agents must not call either tool. They return their results to the parent agent; only the top-level agent talks to you through Prodius. The server advertises this in its instructions, but it is worth repeating in your own CLAUDE.md.

How it works

your AI tool  ──stdio (JSON-RPC)──▶  prodius-mcp  ──HTTP──▶  Prodius desktop app
                                       (this pkg)              (overlay + voice)

prodius-mcp is a stdio shim and nothing more. It speaks MCP over stdin/stdout to your AI tool and forwards each call to the Prodius desktop app's local Voice Bridge — a set of /mcp/* HTTP routes on 127.0.0.1, authenticated with a Bearer token that the desktop app generates on first run. The overlay rendering, the voice pipeline, and the routing of answers back to the right agent all live in the desktop app.

Consequences worth knowing:

  • Nothing leaves your machine via this package. The shim only ever connects to 127.0.0.1 (or, under WSL in NAT networking mode, the Windows host). Speech transcription is performed by the desktop app, which routes it through Prodius' EU inference gateway — see prodius.ai/privacy.

  • No third-party dependencies, by design. Everything is Python standard library, so the shim installs in a second and adds no supply-chain surface to your agent's environment.

  • The bridge is plain HTTP, so anything that can curl can reach you too — cron jobs, deploy scripts, CI. That endpoint is the desktop app's, not this package's; see prodius.ai/connect.

Configuration

The shim auto-discovers the running Prodius app. You rarely need to set anything, but these environment variables override the defaults:

Variable

Purpose

Default

PRODIUS_MCP_TOKEN

Auth token for the local Prodius server.

Read from the Prodius app's settings.json.

PRODIUS_BASE_URL

Prodius local server URL.

Discovered from settings (http://127.0.0.1:5555).

PRODIUS_AGENT_NAME

Label shown so you know which agent is asking.

Unknown Agent

PRODIUS_MCP_DEBUG

Set to 1 to log the text of voice messages to stderr (otherwise only their length).

off

PRODIUS_HOOK_DEBUG

Set to 1 to let prodius-permission-hook log commands and answers, and write a log file.

off

Console scripts

  • prodius-mcp — the MCP server (run by your AI tool, not by hand).

  • prodius-mcp-reset — resets the Prodius conversation. Wire it to a Claude Code SessionStart hook (see the snippet above) so a new session doesn't inherit stale context.

  • prodius-permission-hook — answers Claude Code's permission prompts by voice, so you can say "allow" / "deny" from anywhere. Add it as a PermissionRequest hook in ~/.claude/settings.json:

    "hooks": {
      "PermissionRequest": [
        { "matcher": "*", "hooks": [{ "type": "command", "command": "prodius-permission-hook" }] }
      ]
    }

    It only runs when Claude Code itself would ask you, after its own permission modes and allow/deny rules, and offers Allow once, Always allow and Deny. Always allow saves exactly the rule Claude Code's own prompt would offer. If Prodius isn't running or you don't answer, you get the normal terminal prompt, so it never blocks you.

    Set it up under PreToolUse before version 0.3? Move it to PermissionRequest. Under PreToolUse the hook now does nothing.

Troubleshooting

  • Popup doesn't appear? Confirm the Prodius desktop app is running with Voice Bridge enabled, and that prodius-mcp is on your PATH.

  • Agent doesn't receive your answer? Check your microphone works in Prodius (try a normal dictation), then restart your AI tool after editing its config.

  • Two overlays for the same agent? Only the first shim process registered for an agent may show overlays; later ones get a 409 suppressed and stay quiet. If overlays stop appearing entirely, restart the desktop app to clear the registration.

Development

git clone <repo-url> && cd prodius-mcp
pip install -e . pytest
python -m pytest tests/

The tests don't need the desktop app: they run the server as a subprocess and talk JSON-RPC to it over stdio.

The package is stdlib-only and must stay that way — dependencies in pyproject.toml is deliberately empty, and tests/test_version.py guards the single-sourced version (pyproject.toml is the one version string; __init__.py reads it back via importlib.metadata).

Versioning and releases

Only MAJOR.MINOR in pyproject.toml is meaningful in git. At release time ci/inject_pypi_version.sh sets the patch number to the CI pipeline ID and adds a PEP 440 suffix per channel (X.Y.N stable, X.Y.Nb1 beta, X.Y.N.dev1 everything else), so every build has a unique version. ci/local_validate.sh rehearses the whole release (inject, version guard, tests, build, twine check, wheel smoke test) locally without uploading.

License

MIT — see LICENSE.

Note that this covers the shim only. The Prodius desktop app it connects to is closed-source and separately licensed; it is free to use on the Free tier. See prodius.ai.

Available Tools

2 tools
ask_userA
Read-only

Ask the user a question via voice overlay. Sub-agents must NOT call this — return results to your parent agent. Plain text, one sentence, ~80 chars (100 max).

NameRequiredDescriptionDefault
detailNoOptional Markdown content. User can expand overlay to read before answering.
optionsNoOptional button labels (max 4). Rendered as clickable buttons in 360px overlay. Total chars across all labels: 2 buttons max 44, 3 max 41, 4 max 38. Keep labels short. User can always answer by voice instead.
questionYesThe question to ask (~80 chars, 100 max). Plain text, one sentence.
task_nameNoLabel for this session (e.g., 'Fix auth bug'). Shown in modal header. Always set this on your first call — helps the user distinguish concurrent sessions. Set once, reuse on subsequent calls.
timeout_sNoSeconds before timeout. Default 120 (2 minutes). Max 600.

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only cover the safety profile (readOnly, non-destructive, openWorld); the description adds real context beyond that — a human-facing voice overlay, a sub-agent prohibition, and strict input brevity. It omits whether the call blocks until the user answers or times out, though the timeout parameter partially implies this.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short, front-loaded sentences with zero filler: purpose first, then the audience restriction, then the format constraint. Every clause is actionable and nothing is padded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, and the description never says what the agent receives back (the user's answer text, likely a structured response with the chosen option). For a tool whose entire value is the returned answer, that gap matters; the description also doesn't state that the call blocks until answered or times out.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents question, detail, options, task_name, and timeout_s thoroughly. The description's 'plain text, one sentence, ~80 chars (100 max)' restates the schema's maxLength and description rather than adding new meaning — baseline 3 applies when the schema carries the load.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb and resource — ask the user a question — and adds the delivery mechanism (voice overlay), which an agent can't infer from the name alone. It does not explicitly contrast with the sibling 'notify' (one-way vs. question-and-answer), so differentiation is implied rather than stated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives a hard, explicit exclusion: 'Sub-agents must NOT call this — return results to your parent agent.' That is genuinely actionable routing guidance. It never mentions the 'notify' sibling or when a plain notification is preferable to a blocking question, leaving one meaningful alternative unaddressed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

notifyA
Read-only

Show the user a short message in a desktop overlay, without waiting for a reply. Use it as often as the user's own instructions say; with no such instructions, only for results they need to see while away from the terminal. Sub-agents must NOT call this.

NameRequiredDescriptionDefault
levelNoinfo
detailNoOptional Markdown content. User can expand overlay to see full details (files changed, decisions, context).
messageYesOne-sentence summary shown in desktop popup (aim for ~80 chars, 100 max).
task_nameNoShort label for this session. Same as ask_user's task_name.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, openWorldHint=true, and destructiveHint=false. The description adds useful behavioral context beyond that: the overlay is non-blocking, frequency should follow user instructions, and sub-agents must not call it.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three compact sentences, front-loaded with the core action and followed by usage constraints. No wasted wording.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a low-complexity notification tool with annotations and no output schema, the description is largely complete. It covers purpose, usage conditions, and sub-agent prohibition, though it leaves parameter-level details to the schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 75%, so most parameters are already documented in the schema. The description does not add meaning about message, detail, task_name, or the level enum, so the baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action, medium, and scope: show a short message in a desktop overlay without waiting for a reply. This clearly distinguishes it from the sibling ask_user tool, which implies waiting for user input.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit usage conditions: follow user instructions for frequency, otherwise only notify for results needed while away from the terminal. It also explicitly prohibits sub-agent use. The main gap is that it does not name ask_user as the alternative when a reply is needed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 2 tool updatesv0.3.0
    • First observedask_user
    • First observednotify

TDQS

A4/5.0

Scored across 2 tools

Disambiguation5/5

The two tools have clearly distinct semantics: ask_user blocks for a reply, while notify sends a non-blocking message. An agent can easily choose between them based on whether user input is required.

Naming Consistency4/5

Both names are lowercase and readable, but ask_user follows a verb_noun pattern while notify is a bare verb. The minor inconsistency does not create confusion.

Tool Count3/5

Two tools is thin, but the server's apparent scope is limited to user overlay communication. Each tool earns its place, though the surface feels minimal.

Completeness4/5

The core interaction modes—asking for input and sending notifications—are covered. Minor gaps might include confirmation-specific helpers, but agents can work around them.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers