
Company News
Socket Partners with Replit to Block Malicious Packages in AI-Powered Development
Replit is integrating Socket Firewall into its AI-powered development experience to help protect builders from malicious open source packages.
@mcp-layer/cli
Advanced tools
CLI framework for interacting with MCP servers using discovered schemas.
@mcp-layer/cli is a CLI framework that turns MCP server schemas into a usable command line. It discovers a server from configuration, connects with the transport defined for that server (stdio, Streamable HTTP, or SSE), extracts the unified schema from @mcp-layer/schema, and renders commands for tools, prompts, resources, and templates. You can also extend it with custom commands.
pnpm add @mcp-layer/cli
Run the CLI against a configured MCP server:
mcp-layer servers list
mcp-layer tools list
mcp-layer tools echo --text "hello"
Run the same commands against a remote server by selecting a config entry that uses url/endpoint:
mcp-layer tools list --server remote
mcp-layer tools echo --server remote --text "hello"
The CLI exposes the same schema items for tools, prompts, resources, and templates.
mcp-layer servers list
mcp-layer tools list
mcp-layer tools <tool>
mcp-layer prompts list
mcp-layer prompts <prompt>
mcp-layer resources list
mcp-layer resources <uri>
mcp-layer templates list
mcp-layer templates <template>
Shorthand form:
mcp-layer tools:echo --text "hello"
mcp-layer prompts:kickoff --json '{"topic":"launch"}'
Inputs come from the MCP schema. You can supply them three ways:
--json '{"key":"value"}' for inline JSON--input ./payload.json for JSON files--key value for schema properties (flags are generated from input schema fields)Array and object inputs support a few additional forms:
--items one --items two--items '["one","two"]'--meta.tag alpha--meta '{"tag":"alpha"}'--count 5, --enabled true).If a parameter clashes with a CLI flag (like --help), pass tool arguments after --:
mcp-layer tools echo -- --help "not a real help flag"
The CLI formats MCP responses for readability by default:
Use --raw to emit raw MCP payloads (plain text or binary bytes when a single payload is returned). If multiple content items are present, --raw returns JSON. This makes piping to files straightforward:
mcp-layer tools <tool> --raw > output.json
mcp-layer tools <tool> --raw > payload.bin
For single resource payloads, --raw emits the unrendered text content (or binary bytes), which makes it easy to pipe markdown or plain text into a file:
mcp-layer resources resource://manual --raw > manual.md
Disable markdown rendering with --no-markdown.
Server-provided text is sanitized to strip ANSI escape sequences by default. If you trust the server and want to preserve ANSI output, pass --allow-ansi.
Example:
mcp-layer tools <tool> --allow-ansi
Color output is enabled by default when stdout is a TTY. Disable it with --no-color or by setting NO_COLOR=1. You can customize the colors via accent and subtle in cli() options.
Use --help after a command to see its flags and examples:
mcp-layer tools echo --help
mcp-layer prompts kickoff --help
When a server is selected, help output uses the server name/version and lists all discovered tools, prompts, resources, and templates for that server.
Custom commands registered via cli().command() are included in the main help output and have their own --help rendering.
Example:
import { cli } from '@mcp-layer/cli';
await cli({ name: 'acme-mcp' })
.command(
{
name: 'status',
description: 'Show CLI status.'
},
async function statusCommand(argv) {
process.stdout.write(JSON.stringify({ ok: true }, null, 2));
}
)
.render();
List commands support JSON output:
mcp-layer tools list --format json
mcp-layer resources list --format json
Run/read/render commands render formatted output by default. Use --raw for JSON (or binary bytes when a single binary payload is returned).
@mcp-layer/cli uses @mcp-layer/config to discover MCP server definitions. Transport is selected automatically from the chosen server entry through @mcp-layer/connect.
The MCP spec defines available transports, but config keys are host-tool specific. References:
@mcp-layer/config connectorsSelection order below is @mcp-layer/connect behavior:
Automatic selection behavior:
command entries connect over stdio.url/endpoint entries connect over Streamable HTTP by default.--transport sse (runtime override) forces legacy SSE for URL-based entries.Use --transport when you need an explicit runtime override (for example, forcing SSE against a legacy endpoint) without adding non-standard keys to shared config files.
When multiple servers are configured, choose one with --server:
mcp-layer tools list --server demo
Control server listing in help output via showServers:
showServers: true always renders the Servers section.showServers: false always hides the Servers section.
Default: true.You can also point at a specific config file or directory:
mcp-layer tools list --config ./mcp.json
mcp-layer tools list --config ~/configs
You can embed the CLI and add custom commands using the same parser and help renderer.
import { cli } from '@mcp-layer/cli';
/**
* Render the CLI with a custom command.
* @returns {Promise<void>}
*/
async function main() {
await cli({ name: 'acme-mcp', description: 'Acme MCP CLI' })
.command(
{
name: 'status',
description: 'Report CLI configuration state.'
},
async function statusCommand(argv, helpers) {
const verbose = Boolean(argv.verbose);
const done = helpers.spinner('Loading status');
process.stdout.write(JSON.stringify({ ok: true, verbose }, null, 2));
done();
}
)
.render();
}
main();
cli(options)Creates a CLI instance.
Options:
name: CLI name displayed in help output.version: CLI version string.description: CLI description for help output.colors: enable or disable color output.accent: hex color for headings (default #FFA500).subtle: hex color for flag names (default #696969).spinner: enable the loading spinner.markdown: enable markdown rendering for text output.ansi: allow ANSI escape sequences in server-provided text.server: default server name.config: default config path.showServers: show or hide the Servers section in help output.timeout: fail if MCP initialization exceeds the timeout in milliseconds (opt-in only).cli().command(options, handler)Registers a custom command.
options.name: command name.options.description: summary for help output.handler(argv, helpers): async handler invoked with parsed args.helpers.spinner(text): start a spinner and return a stop() function.cli().render([argv])Executes the CLI. If argv is omitted, it uses process.argv.
--server <name>: select a configured server.--config <path>: point at a config file or directory.--transport <mode>: override transport at runtime (stdio, streamable-http, or sse).--timeout <ms>: fail if MCP initialization exceeds the timeout in milliseconds (opt-in).--format <json>: use JSON for list output.--json <string>: supply inline JSON input.--input <path>: supply JSON input from a file.--raw: emit raw JSON (or binary bytes for a single binary payload).--no-markdown: disable markdown rendering.--allow-ansi: preserve ANSI escape sequences from server text.--no-spinner: disable the loading spinner.--no-color: disable color output.pnpm test --filter @mcp-layer/cli
This section is written for high-pressure debugging moments. Each entry maps directly to the CLI's MCP discovery and invocation paths.
Thrown from: cli.render
This happens when you run contextual help for a specific target (tools <name> --help, prompts <name> --help, resources <uri> --help, templates <uri> --help) and that target is not in the MCP catalog returned by the selected server.
Step-by-step resolution:
mcp-layer servers list or pass --server <name> explicitly.mcp-layer tools list, mcp-layer prompts list, mcp-layer resources list, or mcp-layer templates list.mcp-layer --server dev tools list
mcp-layer --server dev tools weather.get --help
Thrown from: cli.render
This happens when the first positional token does not match any built-in CLI surface (tools, prompts, resources, templates, servers, help) and does not match a registered custom command.
Step-by-step resolution:
mcp-layer --help and verify the exact command name and shape.tool vs tools).cli().render(...).# Wrong: tool list
mcp-layer tools list
Thrown from: cli.render
This happens on prompts <name> exec when the connected MCP server does not expose a prompt with that name in prompts/list.
Step-by-step resolution:
mcp-layer prompts list --server <name> and copy the prompt name directly.--server and --config values are used between list and exec commands.prompts <name> exec with the exact listed name.mcp-layer --server dev prompts list
mcp-layer --server dev prompts summarize.exec exec --topic "release notes"
Thrown from: cli.render
This happens on resources <uri> exec when no resource with that URI exists in the connected MCP server's resources/list catalog.
Step-by-step resolution:
mcp-layer resources list --server <name> to retrieve valid URIs.mcp-layer --server dev resources list
mcp-layer --server dev resources mcp://docs/changelog exec
Thrown from: cli.render
This happens on templates <uriTemplate> exec when the specified URI template is not present in the server's resources/templates/list response.
Step-by-step resolution:
mcp-layer templates list --server <name>.mcp-layer --server dev templates list
mcp-layer --server dev templates mcp://docs/{slug} exec --slug release-2026-02
Thrown from: cli.render
This happens on tools <name> exec when the name is missing from the server's tools/list response.
Step-by-step resolution:
mcp-layer tools list --server <name>.mcp-layer --server dev tools list
mcp-layer --server dev tools weather.get exec --city London
Thrown from: coercenumber
This happens while validating tool/prompt/template arguments against the MCP JSON Schema. The target field is typed as integer, but the CLI received a non-integer value (for example 3.14, 1e2, or text).
Step-by-step resolution:
detail.input.json) for the failing parameter and confirm it is type: "integer".--count), --json, or --input file.3.5) and accepted (3) values.# Wrong
mcp-layer tools batch.run exec --count 2.5
# Correct
mcp-layer tools batch.run exec --count 2
Thrown from: coercenumber
This happens while coercing CLI argument values for a schema field typed as number or integer; the received string cannot be parsed to a JavaScript number at all (for example ten, 10ms, or an empty string).
Step-by-step resolution:
--json, --input, or CLI flags).42, 3.14) and not decorated text ("42ms").# Wrong
mcp-layer tools stats.query exec --threshold ten
# Correct
mcp-layer tools stats.query exec --threshold 10
Thrown from: inputs
This happens after the CLI loads an MCP item's input schema and sees that a field listed in required is absent from resolved arguments.
Step-by-step resolution:
required fields.--<name> <value> for simple values.--json '{"name":"value"}' or --input payload.json for structured payloads.# Tool schema requires "city"
mcp-layer tools weather.get exec --city Paris
Thrown from: parsejson
This happens when a schema field is an object or array and the CLI attempts to parse the provided string as JSON, but parsing fails. Typical sources are single quotes, trailing commas, or shell-escaped payload corruption.
Step-by-step resolution:
{parameter}.node -e 'JSON.parse(...)' before passing it to CLI.--input payload.json for complex nested JSON to avoid shell escaping issues.# Wrong (single quotes are not valid JSON content)
mcp-layer tools repo.search exec --filters '{tag: "api"}'
# Correct
mcp-layer tools repo.search exec --filters '{"tag":"api"}'
Thrown from: render
This happens when executing a resource template and at least one {placeholder} in uriTemplate has no matching argument in CLI input.
Step-by-step resolution:
templates list and enumerate placeholders.--json/--input, verify key names exactly match template placeholder names.# Template: mcp://docs/{team}/{slug}
mcp-layer templates mcp://docs/{team}/{slug} exec --team api --slug auth-flow
Thrown from: render
This happens when template execution reaches URI rendering without a uriTemplate value in the selected catalog item. In practice this indicates malformed/partial template metadata from the server.
Step-by-step resolution:
mcp-layer templates list --format json and inspect detail.uriTemplate for the failing entry.uriTemplate.{
name: 'docs-by-slug',
description: 'Read docs by slug',
uriTemplate: 'mcp://docs/{slug}'
}
Thrown from: select
This happens when configuration discovery yields more than one server and no --server flag (or default server setting) is provided, so CLI cannot safely infer which MCP endpoint to use.
Step-by-step resolution:
mcp-layer servers list to see discovered server names.--server <name>.mcp-layer servers list
mcp-layer --server local-dev tools list
Thrown from: select
This happens when --server <name> (or configured default) does not match any server key in the loaded MCP configuration documents.
Step-by-step resolution:
mcp-layer servers list and verify the actual configured names.--config points to the config file/directory you intended.mcp-layer --config ./mcp.json servers list
mcp-layer --config ./mcp.json --server integration tools list
MIT
FAQs
CLI framework for interacting with MCP servers using discovered schemas.
The npm package @mcp-layer/cli receives a total of 24 weekly downloads. As such, @mcp-layer/cli popularity was classified as not popular.
We found that @mcp-layer/cli demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Company News
Replit is integrating Socket Firewall into its AI-powered development experience to help protect builders from malicious open source packages.

Security News
npm confirmed a tooling bug incorrectly marked several one-character packages as security holders and said it was working on a rollback.

Research
/Security News
Newer packages in this compromise use native extensions and .pth loaders to execute JavaScript stealers in developer environments.