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
25 changes: 11 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,18 +80,9 @@ Internal surface:

## 🚀 Quickstart

### 🤖 Agent-first install
### 🐳 Docker (Default)

If you are using Claude Code, Cursor, Gemini CLI, Copilot CLI, OpenCode, or Codex, paste this at your agent:

> Fetch and follow the instructions at https://raw.githubusercontent.com/orkait/hyperstack/main/install.md

The agent will pull the Docker image and configure your MCP client.

### 🐳 Docker (manual)

Hyperstack uses a persistent container plus `docker exec`. Do **not** use the
older `docker run --rm` per-session pattern.
Hyperstack uses a persistent container plus `docker exec`. This keeps startup cheap across sessions and ensures 100% environment stability.

1. Pull the image:

Expand All @@ -109,7 +100,7 @@ docker run -d --name hyperstack-mcp --restart unless-stopped \
ghcr.io/orkait/hyperstack:main infinity
```

3. Add this to `~/.claude.json`, Cursor config, or equivalent:
3. Add this to your MCP settings (`~/.claude.json`, Cursor, Windsurf, etc.):

```json
{
Expand All @@ -122,8 +113,14 @@ docker run -d --name hyperstack-mcp --restart unless-stopped \
}
```

This keeps startup cheap across sessions and matches the installation flow in
[install.md](/mnt/storage/codespace/code/orkait/hyperstack/install.md).
### 🤖 Agent Autopilot

If you are using Claude Code, Cursor, Windsurf, Roo Code, or Gemini, you can use the autopilot to self-configure. Paste this at your agent:

> Fetch and follow the instructions at https://raw.githubusercontent.com/orkait/hyperstack/main/install.md

The autopilot will detect your environment and propose the correct Docker-based configuration block.


### 🔧 Install the skills

Expand Down
6 changes: 4 additions & 2 deletions install.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,14 @@ The system automatically probes for signatures:
- **Known Paths**: Probes for `.claude.json`, `.cursor/`, `.codeium/windsurf/`, `.roo/`, and `.gemini/`.

### 2. Run the Autopilot
As an agent, you should call the `hyperstack_setup` tool immediately. It will return the detected path and the JSON configuration block required for that specific tool's schema.
As an agent, you should call the `hyperstack_setup` tool immediately. **By default, it generates a Docker-based configuration** using the optimized `docker exec` pattern.

If Docker is not available, you can explicitly request the local method: `hyperstack_setup(method: "local")`.

**If the environment is unknown:**
1. Call `web_search` with a query like `[IDE Name] MCP configuration path`.
2. Provide the result to `hyperstack_setup(researchResult: "...")`.
3. The tool will generate the final patch.
3. The tool will generate the final Docker-based patch.

## Step 2: Install the Skills

Expand Down
49 changes: 26 additions & 23 deletions src/internal/setup-hyperstack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,46 +64,49 @@ export function findConfigFile(platform: string): string | null {
return null;
}

export function generateMcpPatch(configPath: string, pluginRoot: string) {
const binaryPath = path.join(pluginRoot, "bin", "hyperstack.mjs");
const hookPath = path.join(pluginRoot, "hooks", "session-start.mjs");

const serverConfig = {
export function generateMcpPatch(
configPath: string,
pluginRoot: string,
method: "docker" | "local" = "docker"
) {
const isClaude = configPath.endsWith(".claude.json");
const isGemini = configPath.includes("settings.json") && configPath.includes(".gemini");

const binaryPath = path.join(pluginRoot, "bin", "hyperstack.mjs");
const localConfig = {
command: "node",
args: [binaryPath],
env: {
HYPERSTACK_ROOT: pluginRoot
}
HYPERSTACK_ROOT: pluginRoot,
},
};

// Determine schema based on filename
const isClaude = configPath.endsWith(".claude.json");
const isWindsurf = configPath.includes("windsurf");
const isGemini = configPath.includes("gemini");
const dockerConfig = {
command: "docker",
args: ["exec", "-i", "hyperstack-mcp", "bun", "/app/src/index.ts"],
env: {
HYPERSTACK_ROOT: pluginRoot, // Still helpful for skills indexing
},
};

if (isClaude) {
return {
mcpServers: {
hyperstack: serverConfig
}
};
}
const serverConfig = method === "docker" ? dockerConfig : localConfig;

if (isGemini) {
return {
extensions: {
hyperstack: {
...serverConfig,
type: "stdio"
}
}
type: "stdio",
},
},
};
}

// Default MCP schema
// Default MCP schema (Claude, Cursor, Windsurf, Roo Code)
return {
mcpServers: {
hyperstack: serverConfig
}
hyperstack: serverConfig,
},
};
}
5 changes: 3 additions & 2 deletions src/plugins/hyperstack/tools/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ export function registerSetupTool(server: McpServer) {
"Identify current IDE/CLI environment and generate a tailored MCP configuration patch for Hyperstack.",
{
researchResult: z.string().optional().describe("If the environment was unknown, provide the researched config path or schema details here."),
method: z.enum(["docker", "local"]).default("docker").describe("Preferred installation method. Use 'docker' (default) for stable persistent environments, 'local' for fallback."),
},
async ({ researchResult }) => {
async ({ researchResult, method }) => {
const platform = setup.detectEnvironment();
const configPath = setup.findConfigFile(platform);

Expand All @@ -37,7 +38,7 @@ export function registerSetupTool(server: McpServer) {
};
}

const patch = setup.generateMcpPatch(activeConfigPath, pluginRoot);
const patch = setup.generateMcpPatch(activeConfigPath, pluginRoot, method);

return {
content: [{
Expand Down
12 changes: 9 additions & 3 deletions verify-setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,15 @@ async function verify() {
console.log(`Config Path Found: ${configPath || "None (expected if running in clean environment)"}`);

if (configPath || platform !== "unknown") {
const patch = setup.generateMcpPatch(configPath || "/tmp/mcp.json", process.cwd());
console.log("Proposed Patch:");
console.log(JSON.stringify(patch, null, 2));
const finalPath = configPath || "/tmp/mcp.json";

console.log("\nProposed Patch (Method: DOCKER - Default):");
const dockerPatch = setup.generateMcpPatch(finalPath, process.cwd(), "docker");
console.log(JSON.stringify(dockerPatch, null, 2));

console.log("\nProposed Patch (Method: LOCAL):");
const localPatch = setup.generateMcpPatch(finalPath, process.cwd(), "local");
console.log(JSON.stringify(localPatch, null, 2));
} else {
console.log("Environment unknown - research fallback would trigger here.");
}
Expand Down
Loading