completion/complete is available in full mode (disabled in minimal mode). Completions are manually registered (there is no auto-discovery). Prefer declarative registration via server.d/register.json; hook-based registration via server.d/register.sh is still supported but executes shell code and is opt-in (MCPBASH_ALLOW_PROJECT_HOOKS=true plus safe ownership/permissions).
// server.d/register.json
{
"version": 1,
"completions": [
{"name": "example.completion", "path": "completions/suggest.sh", "timeoutSecs": 5}
]
}namemust be unique. Clients reference it viaparams.refincompletion/completerequests.pathis relative toMCPBASH_PROJECT_ROOTformanualproviders.timeoutSecsis optional; defaults to no per-request timeout (global watchdogs still apply).- The registry rejects duplicates, missing paths, or buffer overflows (guarded by
MCPBASH_MANUAL_BUFFER_MAX_BYTES).
Use ref + argument:
{
"jsonrpc": "2.0",
"id": "c1",
"method": "completion/complete",
"params": {
"ref": {"type": "ref/prompt", "name": "demo.completion"},
"argument": {"name": "query", "value": "re"},
"limit": 3,
"context": {"arguments": {}}
}
}Notes:
ref/promptuses the prompt name (this maps to the completion provider name for manual completions).ref/resourceusesref.uri; mcp-bash resolves it to a registered resource name when possible.
- builtin: fallback generator when no registration matches.
- manual: executable script under project root (most common).
- prompt: script under
prompts/(receives prompt metadata via env). - resource: script under
resources/(receives resource metadata via env).
Environment variables:
MCP_COMPLETION_NAME– completion name (string).MCP_COMPLETION_ARGS_JSON– JSON object derived from the request params:- a normalized object that includes
query/prefix(fromparams.argument.value) plusrefandcontext.arguments
- a normalized object that includes
MCP_COMPLETION_LIMIT– max suggestions requested (int; capped at 100).MCP_COMPLETION_OFFSET– pagination offset (int).MCP_COMPLETION_ARGS_HASH– opaque hash for cursor binding.
Recommended parsing:
# Prefer .query; fall back to .prefix; treat missing as empty string.
query="$(printf '%s' "${MCP_COMPLETION_ARGS_JSON:-{}}" | jq -r '(.query // .prefix // "")')"Stdout (any of):
- JSON array of suggestions:
["alpha","beta"]
- Object with
suggestionsplus pagination fields:{ "suggestions": ["alpha"], "hasMore": true, "next": 1, // optional numeric offset for next page "cursor": "opaque" // optional cursor string (takes precedence over next) }
Notes:
- Providers must emit
string[]suggestions (andsuggestionsmust bestring[]when using the object form).
- Completion is declined with
-32601when JSON tooling is unavailable orMCPBASH_FORCE_MINIMAL=true. - Scripts still need
jq/gojqto parse arguments;MCPBASH_JSON_TOOL_BINis exported.
- Limit requested by client is capped to 100.
- If
hasMoreis true andcursoris empty, the framework derives a cursor fromnext(or offset + count). - If
cursoris provided, it is returned asnextCursorunmodified; subsequent requests include it inparams.cursor.
See examples/10-completions:
- Registers
demo.completionviaserver.d/register.json. - Script reads
.query(or.prefix) fromMCP_COMPLETION_ARGS_JSON, filters suggestions, and paginates withhasMore. completion/completereturns suggestions,hasMore, andnextCursoruntil results are exhausted.
If you need dynamic/imperative completion registration (for example, generate names from the filesystem or gate entries on env vars), see examples/advanced/register-sh-hooks/ which uses server.d/register.sh (opt-in).