Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Contributing to `mcp-shell` <!-- omit from toc -->
# Contributing to Model Context Shell <!-- omit from toc -->

First off, thank you for taking the time to contribute to MCP Shell! :+1: :tada: MCP Shell is released under the Apache 2.0 license.
First off, thank you for taking the time to contribute to Model Context Shell! :+1: :tada: Model Context Shell is released under the Apache 2.0 license.
If you would like to contribute something or want to hack on the code, this
document should help you get started. You can find some hints for starting
development in mcp-shell's
[README](https://github.com/StacklokLabs/mcp-shell/blob/main/README.md).
development in the project's
[README](https://github.com/StacklokLabs/model-context-shell/blob/main/README.md).

## Table of contents <!-- omit from toc -->

Expand All @@ -19,17 +19,17 @@ development in mcp-shell's
## Code of conduct

This project adheres to the
[Contributor Covenant](https://github.com/StacklokLabs/mcp-shell/blob/main/CODE_OF_CONDUCT.md)
[Contributor Covenant](https://github.com/StacklokLabs/model-context-shell/blob/main/CODE_OF_CONDUCT.md)
code of conduct. By participating, you are expected to uphold this code. Please
report unacceptable behavior to
[code-of-conduct@stacklok.com](mailto:code-of-conduct@stacklok.com).

## Reporting security vulnerabilities

If you think you have found a security vulnerability in mcp-shell please DO
If you think you have found a security vulnerability in Model Context Shell please DO
NOT disclose it publicly until we've had a chance to fix it. Please don't report
security vulnerabilities using GitHub issues; instead, please follow this
[process](https://github.com/StacklokLabs/mcp-shell/blob/main/SECURITY.md)
[process](https://github.com/StacklokLabs/model-context-shell/blob/main/SECURITY.md)

## How to contribute

Expand All @@ -46,7 +46,7 @@ sample project that reproduces the problem.
### Not sure how to start contributing?

PRs to resolve existing issues are greatly appreciated and issues labeled as
["good first issue"](https://github.com/StacklokLabs/mcp-shell/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)
["good first issue"](https://github.com/StacklokLabs/model-context-shell/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)
are a great place to start!

### Pull request process
Expand All @@ -56,15 +56,15 @@ are a great place to start!
of Origin. For additional details, check out the [DCO instructions](dco.md).

- Create an issue outlining the fix or feature.
- Fork the mcp-shell repository to your own GitHub account and clone it
- Fork the repository to your own GitHub account and clone it
locally.
- Hack on your changes.
- Correctly format your commit messages, see
[Commit message guidelines](#commit-message-guidelines) below.
- Open a PR by ensuring the title and its description reflect the content of the
PR.
- Ensure that CI passes, if it fails, fix the failures.
- Every pull request requires a review from the core mcp-shell team before
- Every pull request requires a review from the core team before
merging.
- Once approved, all of your commits will be squashed into a single commit with
your PR title.
Expand Down
162 changes: 126 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,34 +1,55 @@
# MCP Shell
# Model Context Shell

**Unix-style pipelines for MCP tools — coordinate thousands of tool calls in a single request**
[![CI](https://github.com/StacklokLabs/model-context-shell/actions/workflows/ci.yml/badge.svg)](https://github.com/StacklokLabs/model-context-shell/actions/workflows/ci.yml)
[![License: Apache 2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](LICENSE)

## Overview
**Unix-style pipelines for MCP tools — compose complex tool workflows as single pipeline requests**

MCP Shell is an MCP server that lets AI agents compose tool calls using Unix shell patterns. Instead of the agent orchestrating each tool call individually (loading all intermediate data into context), agents can express complex workflows as pipelines that execute server-side.
## Introduction

```bash
# What agents can express:
fetch https://api.example.com/users \
| jq -c '.[] | .profile_url' \
| for_each fetch \
| jq '[.[] | select(.active)] | sort_by(.name)'
```
Model Context Shell is a system that lets AI agents compose [MCP](https://modelcontextprotocol.io/) tool calls similar to Unix shell scripting. Instead of the agent orchestrating each tool call individually (loading all intermediate data into context), agents can express complex workflows as pipelines that execute server-side.

This single pipeline fetches a list, extracts URLs, fetches each one, filters the results, and returns only the final output to the agent — no intermediate data in context.
For example, an agent can express a multi-step workflow as a single pipeline:

## Why This Matters
```mermaid
flowchart LR
A["Fetch users (MCP)"] --> B["Extract profile URLs (Shell)"] --> C["for_each (Shell)"] --> C1["Fetch profile (MCP)"] --> D["Filter and sort (Shell)"]
```

MCP is great — standardized interfaces, structured data, extensible ecosystem. But for complex workflows, agents hit real limits:
This pipeline fetches a list, extracts URLs, fetches each one, filters the results, and returns only the final output to the agent — no intermediate data in context.

### Why this matters

[MCP](https://modelcontextprotocol.io/) is great — standardized interfaces, structured data, extensible ecosystem. But for complex workflows, the agent has to orchestrate each tool call individually, loading all intermediate results into context. Model Context Shell adds a pipeline layer — the agent sends a single pipeline, and the server coordinates the tools, returning only the final result:

```mermaid
flowchart LR
subgraph without["Standard Workflow"]
direction TB
A1[Agent]
A1 <--> T1a[Tool A]
A1 <--> T2a[Tool B]
A1 <--> T3a[Tool C]
end
subgraph with["Model Context Shell"]
direction TB
A2[Agent] <--> S[Shell]
S --> T1b[Tool A] --> S
S --> T2b[Tool B] --> S
S --> T3b[Tool C] --> S
end
without ~~~ with
```

| | Without MCP Shell | With MCP Shell |
| | Without | With |
|---|---|---|
| **Orchestration** | Agent coordinates every tool call, loading intermediate results into context | Single pipeline request, only final result returned |
| **Composition** | Tools combined through LLM reasoning | Native Unix-style piping between tools |
| **Composition** | Tools combined by the agent one call at a time | Native Unix-style piping between tools |
| **Data scale** | Limited by context window | Streaming/iterator model handles datasets larger than memory |
| **Reliability** | LLM-dependent control flow | Deterministic shell pipeline execution |
| **Permissions** | Complex tasks push toward full shell access | Sandboxed execution with allowed commands only |

## Real-World Example
### Real-world example

Example query: "List all Pokemon over 50 kg that have the chlorophyll ability"

Expand All @@ -38,15 +59,68 @@ Instead of 7+ separate tool calls loading all Pokemon data into context, the age
- Fetched each Pokemon's details (7 API calls)
- Filtered by weight and formatted the results

**Result**: 50%+ reduction in tokens and only the final answer loaded into context.
**Result**: Only the final answer is loaded into context — no intermediate API responses.

In practice, agents don't construct the perfect pipeline on the first try. They typically run a few exploratory queries first to understand the shape of the data before building the final pipeline. To keep this process fast and cheap, the server includes a preview stage powered by [headson](https://github.com/kantord/headson) that returns a compact structural summary of the data — enough for the agent to plan its transformations without loading the full dataset into context.

### Design

Agents already have access to full shell environments and can call any CLI tool, which has significant overlap with what MCP tools provide. Rather than duplicating that, Model Context Shell explores whether similar workflows can be achieved in a safer, simpler MCP-native environment. Patterns like parallel map-reduce over tool call results are not common today because MCP doesn't natively support them, but they seem like a natural fit for coordinating tool calls — imagine fetching all console errors via a Chrome DevTools MCP server and creating a separate GitHub issue for each one. A system tailored to these patterns can make them first-class operations.

The execution engine works with JSON pipeline definitions directly — agents construct pipelines from the MCP tool schema alone, without needing shell syntax. Commands are never passed through a shell interpreter; each command and its arguments are passed as separate elements to the underlying process (`shell=False`), eliminating shell injection risks entirely. Data flows between stages as JSON, preserving types through the pipeline rather than reducing everything to strings. MCP tool arguments are validated against their JSON Schema by the receiving server, giving agents type-checked feedback when they construct pipelines incorrectly.

The result is a more constrained system compared to a general-purpose shell — only a fixed set of data transformation commands is available, and all execution happens inside a container.

### How it works

Model Context Shell is packaged as an MCP server, which makes it easy to use with any agent that supports the protocol. It could also be packaged as a library built directly into an agent.

The server exposes four tools to the agent via MCP:

| Tool | Purpose |
|---|---|
| `execute_pipeline` | Execute a pipeline of tool calls and shell commands |
| `list_all_tools` | Discover all tools available from MCP servers via [ToolHive](https://stacklok.com/download/) |
| `get_tool_details` | Get the full schema and description for a specific tool |
| `list_available_shell_commands` | Show the whitelist of allowed CLI commands |

The agent constructs pipelines as JSON arrays of stages. Data flows from one stage to the next, similar to Unix pipes. There are three stage types:

**Tool stages** call external MCP tools discovered through ToolHive:
```json
{"type": "tool", "name": "fetch", "server": "fetch", "args": {"url": "https://..."}}
```

**Command stages** transform data using whitelisted shell commands:
```json
{"type": "command", "command": "jq", "args": ["-c", ".results[] | {id, name}"]}
```

**Preview stages** show a summarized view of the data at any point in the pipeline, useful for the agent to understand the data structure before writing transformations:
```json
{"type": "preview", "chars": 3000}
```

## Installation
Any tool stage can set `"for_each": true` to process items one-by-one. The preceding stage must output JSONL (one JSON object per line), and the tool is called once per line. Results are collected into an array. This enables patterns like "fetch a list of URLs, then fetch each one" in a single pipeline call, using a single reused connection for efficiency.

Here is a full example — a pipeline that fetches users, extracts their profile URLs, fetches each profile, and filters for active users:

```json
[
{"type": "tool", "name": "fetch", "server": "fetch", "args": {"url": "https://api.example.com/users"}},
{"type": "command", "command": "jq", "args": ["-c", ".[] | {url: .profile_url}"]},
{"type": "tool", "name": "fetch", "server": "fetch", "for_each": true},
{"type": "command", "command": "jq", "args": ["-c", "[.[] | select(.active)] | sort_by(.name)"]}
]
```

## Setup

### Prerequisites

- [ToolHive](https://toolhive.ai) (`thv`) for running and managing MCP servers
- [ToolHive](https://stacklok.com/download/) (`thv`) — a runtime for managing MCP servers

### Quick Start
### Quick start

Run the pre-built image from GitHub Container Registry:

Expand All @@ -58,36 +132,52 @@ thv run ghcr.io/stackloklabs/model-context-shell:latest --network host --foregro
thv run ghcr.io/stackloklabs/model-context-shell:latest --foreground --transport streamable-http
```

Once running, MCP Shell is available to any AI agent that ToolHive supports — no additional integration required.
Once running, Model Context Shell is available to any AI agent that ToolHive supports — no additional integration required. It works with any existing MCP servers running through ToolHive, and relies on ToolHive's authentication model for connected servers.

### Tips

**Connect only Model Context Shell to your agent** — For best results, don't connect individual MCP servers directly to the agent alongside Model Context Shell. When agents have direct access to tools, they may call them individually instead of composing efficient pipelines. The server can access all your MCP servers through ToolHive automatically.

**Some agents need encouragement** — Most agents will use the shell naturally for complex tasks, but some may need a hint in their system prompt (e.g., "Use Model Context Shell pipelines to combine multiple tool calls efficiently").

## Security

MCP Shell runs in a containerized environment through ToolHive, so commands have no direct access to the user's filesystem — only through explicitly configured MCP servers.
ToolHive runs Model Context Shell in an isolated container, so shell commands have no access to the host filesystem or network. The MCP servers it coordinates also run in their own separate containers, managed by ToolHive.

- **Allowed commands only**: A fixed whitelist of safe, read-only data transformation commands (`jq`, `grep`, `sed`, `awk`, `sort`, `uniq`, `cut`, `wc`, `head`, `tail`, `tr`, `date`, `bc`, `paste`, `shuf`, `join`, `sleep`)
- **No shell injection**: Commands are executed with `shell=False`, arguments passed separately
- **MCP tools only**: All external operations go through approved MCP servers

- **Containerized**: Runs isolated from the host system
- **Allowed Commands**: Only safe, read-only data transformation commands are permitted
- **No Shell Injection**: Commands are executed with `shell=False`, args passed separately
- **MCP Tools Only**: All external operations go through approved MCP servers
## Development

## Usage Tips
### Requirements

**Connect only MCP Shell to your agent** — For best results, don't connect individual MCP servers directly to the agent alongside MCP Shell. When agents have direct access to tools, they may call them individually instead of composing efficient pipelines. MCP Shell can access all your MCP servers through ToolHive automatically.
- Python 3.13+
- [uv](https://docs.astral.sh/uv/) for dependency management

**Some agents need encouragement** — Most agents will use the shell naturally for complex tasks, but some may need a hint in their system prompt (e.g., "Use MCP Shell pipelines to combine multiple tool calls efficiently").
### Setup

## FAQ
```bash
uv sync --group dev
```

**Q: Does this work with my existing MCP servers?**
### Running tests

A: Yes! MCP Shell coordinates any standard MCP servers running through ToolHive.
```bash
uv run pytest
```

**Q: What about authentication?**
### Linting and type checking

A: Currently relies on ToolHive's authentication model for connected MCP servers.
```bash
uv run ruff check .
uv run ruff format --check .
uv run pyright
```

## Contributing

This is an experimental project. Contributions, ideas, and feedback are welcome!
Contributions, ideas, and feedback are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines, including our DCO sign-off requirement.

## License

Expand Down
4 changes: 2 additions & 2 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ your contributions.
## Reporting a vulnerability

To report a security issue, please use the GitHub Security Advisory
["Report a Vulnerability"](https://github.com/StacklokLabs/mcp-shell/security/advisories/new)
["Report a Vulnerability"](https://github.com/StacklokLabs/model-context-shell/security/advisories/new)
tab.

If you are unable to access GitHub you can also email us at
Expand Down Expand Up @@ -80,7 +80,7 @@ These steps should be completed within the 1-7 days of Disclosure.
- Create a new
[security advisory](https://docs.github.com/en/code-security/security-advisories/)
in affected repository by visiting
`https://github.com/StacklokLabs/mcp-shell/security/advisories/new`
`https://github.com/StacklokLabs/model-context-shell/security/advisories/new`
- As many details as possible should be entered such as versions affected, CVE
(if available yet). As more information is discovered, edit and update the
advisory accordingly.
Expand Down
1 change: 1 addition & 0 deletions mcp-metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"tools": [
"execute_pipeline",
"list_all_tools",
"get_tool_details",
"list_available_shell_commands"
],
"metadata": {
Expand Down