Skip to content

shellicar/mcp-exec

Repository files navigation

@shellicar/mcp-exec

An MCP server that runs commands without a shell, with built-in rules to block destructive operations

npm package build status

Features

  • 🛡️ Built-in validation rules blocking destructive operations before execution
  • 🔗 Pipeline support with stdout piped to stdin across commands
  • ⚙️ Three chaining modes: sequential, bail-on-error, and independent
  • 📂 Per-step working directory, environment variables, and stdin injection
  • 📝 Output redirection to file with append support
  • 🔌 Pluggable rule system for custom validation rules
  • 🧹 ANSI code stripping for clean output

Installation & Quick Start

npm i --save @shellicar/mcp-exec
pnpm add @shellicar/mcp-exec
import { createExecServer } from '@shellicar/mcp-exec';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';

const server = createExecServer();
const transport = new StdioServerTransport();
await server.connect(transport);

@shellicar TypeScript Ecosystem

MCP Servers

  • @shellicar/mcp-exec - An MCP server that runs commands without a shell, with built-in rules to block destructive operations.

Core Libraries

Reference Architectures

Build Tools

Framework

Logging & Monitoring

Motivation

Claude Code's Bash tool passes commands through a shell interpreter. That means shell expansion, operator chaining, pipes, heredocs, and subshells all execute before any permission check can inspect them. A single bash -c call can hide anything.

mcp-exec removes the shell entirely. Commands are structured as JSON (program, arguments, working directory, environment), which means the model is constrained by its schema training. When the input is a JSON schema, Claude doesn't guess: it produces valid calls with the precision of Excalibur. JSON-calibur, if you will.

Validation rules check every command against configurable policies before anything executes. Destructive operations like rm -rf, git push --force, and git reset --hard are blocked by default. No shell means no surprises. No surprises means you can actually trust the agent with your repo.

Feature Examples

  • Run a standalone MCP server.
import { createExecServer } from '@shellicar/mcp-exec';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';

const server = createExecServer({ cwd: '/workspace' });
await server.connect(new StdioServerTransport());
  • Add the exec tool to an existing MCP server.
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { execToolDefinition } from '@shellicar/mcp-exec';

const server = new McpServer({ name: 'my-server', version: '1.0.0' });
execToolDefinition(server, { cwd: '/workspace' });
  • Add custom validation rules alongside or instead of the built-in set.
import { createExecServer, builtinRules } from '@shellicar/mcp-exec';
import type { ExecRule } from '@shellicar/mcp-exec';

const noNpm: ExecRule = {
  name: 'no-npm',
  check: (commands) => {
    if (commands.some((c) => c.program === 'npm')) {
      return 'Use pnpm instead of npm.';
    }
    return undefined;
  },
};

const server = createExecServer({ rules: [...builtinRules, noNpm] });

Built-in Rules

Rule Blocks
no-destructive-commands rm, rmdir, mkfs, dd, shred
no-xargs xargs
no-sed-in-place sed -i / --in-place
no-git-rm git rm
no-git-checkout git checkout
no-git-reset git reset
no-force-push git push --force / -f
no-exe .exe calls
no-sudo sudo
no-git-C git -C
no-pnpm-C pnpm -C
no-env-dump env / printenv without arguments

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Generated from shellicar/pnpm-starter