@sammorrowdrums/mcpi-ext 0.1.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +109 -139
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +23 -3
- package/dist/index.js.map +1 -1
- package/dist/tool-cli/index.d.ts +2 -2
- package/dist/tool-cli/index.d.ts.map +1 -1
- package/dist/tool-cli/index.js +1 -2
- package/dist/tool-cli/index.js.map +1 -1
- package/package.json +9 -7
- package/.dockerignore +0 -6
- package/.github/dependabot.yml +0 -25
- package/.github/workflows/ci.yml +0 -50
- package/.hadolint.yaml +0 -6
- package/.prettierignore +0 -4
- package/.prettierrc +0 -7
- package/AGENTS.md +0 -118
- package/DECISIONS.md +0 -99
- package/Dockerfile +0 -39
- package/aube-lock.yaml +0 -4146
- package/eslint.config.js +0 -27
- package/images/banner.webp +0 -0
- package/images/code-c-maude.webp +0 -0
- package/images/nuclear-mcp-football.webp +0 -0
- package/images/the-skill-dealer.webp +0 -0
- package/mise.toml +0 -65
- package/scripts/docker-entrypoint.sh +0 -29
- package/scripts/test-echo-server.mjs +0 -28
- package/scripts/test-mcp-integration.mjs +0 -59
- package/scripts/test-tool-cli-smoke.mjs +0 -62
- package/src/code-mode/code-mode-integration.test.ts +0 -135
- package/src/code-mode/eligibility.test.ts +0 -60
- package/src/code-mode/eligibility.ts +0 -16
- package/src/code-mode/executor.test.ts +0 -168
- package/src/code-mode/executor.ts +0 -163
- package/src/code-mode/index.ts +0 -208
- package/src/code-mode/tools.ts +0 -110
- package/src/code-mode/type-hints.test.ts +0 -187
- package/src/code-mode/type-hints.ts +0 -249
- package/src/docker-e2e.test.ts +0 -195
- package/src/docker-e2e.ts +0 -277
- package/src/index.test.ts +0 -8
- package/src/index.ts +0 -158
- package/src/mcp/client-manager.test.ts +0 -250
- package/src/mcp/client-manager.ts +0 -199
- package/src/mcp/config-loader.test.ts +0 -115
- package/src/mcp/config-loader.ts +0 -46
- package/src/mcp/config.ts +0 -40
- package/src/mcp/index.ts +0 -4
- package/src/skills/discover.ts +0 -81
- package/src/skills/format.test.ts +0 -70
- package/src/skills/format.ts +0 -42
- package/src/skills/index.ts +0 -9
- package/src/skills/load-skill-tool.ts +0 -136
- package/src/skills/mcp-tool-proxy.ts +0 -143
- package/src/skills/skill-integration.test.ts +0 -139
- package/src/skills/skill-registry.test.ts +0 -83
- package/src/skills/skill-registry.ts +0 -69
- package/src/test-servers/weather-server.ts +0 -171
- package/src/test-servers/weather-stdio.ts +0 -11
- package/src/tool-cli/cli.ts +0 -232
- package/src/tool-cli/constants.ts +0 -15
- package/src/tool-cli/format.test.ts +0 -33
- package/src/tool-cli/format.ts +0 -56
- package/src/tool-cli/index.ts +0 -3
- package/src/tool-cli/rpc-client.ts +0 -39
- package/src/tool-cli/rpc-server.test.ts +0 -193
- package/src/tool-cli/rpc-server.ts +0 -287
- package/tsconfig.json +0 -21
package/AGENTS.md
DELETED
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
# AGENTS.md
|
|
2
|
-
|
|
3
|
-
## Tooling
|
|
4
|
-
|
|
5
|
-
This project uses **mise** for tool version management and **npm** for package management. If you are an AI agent or new contributor, read this first.
|
|
6
|
-
|
|
7
|
-
### mise (tool version manager)
|
|
8
|
-
|
|
9
|
-
- **What:** [mise](https://mise.jdx.dev/) manages tool versions (node) and project tasks. Think asdf + direnv + make in one tool.
|
|
10
|
-
- **Why:** Reproducible dev environments. `mise.toml` pins exact tool versions so every contributor and CI run uses the same stack.
|
|
11
|
-
- **Install:** `curl https://mise.run | sh` then activate: `eval "$(~/.local/bin/mise activate bash)"`
|
|
12
|
-
- **Usage:**
|
|
13
|
-
- `mise install` — install all tools from `mise.toml`
|
|
14
|
-
- `mise run <task>` — run a project task (build, test, dev, check, start)
|
|
15
|
-
- `mise use <tool>@<version>` — add/update a tool version
|
|
16
|
-
|
|
17
|
-
### mcpi (coding agent)
|
|
18
|
-
|
|
19
|
-
- **What:** [mcpi](https://github.com/SamMorrowDrums/mcpi) is an extensible terminal coding agent (fork of pi). This project builds extensions for it.
|
|
20
|
-
- **Extension pattern:** Export a default function receiving `ExtensionAPI`, register tools/commands/hooks.
|
|
21
|
-
- **Load extension:** `mcpi --extension ./dist/index.js`
|
|
22
|
-
|
|
23
|
-
## Dev Loop
|
|
24
|
-
|
|
25
|
-
```sh
|
|
26
|
-
mise install # one-time: install node
|
|
27
|
-
npm install # install npm dependencies
|
|
28
|
-
mise run build # compile TypeScript
|
|
29
|
-
mise run test # run tests
|
|
30
|
-
mise run dev # watch mode for development
|
|
31
|
-
mise run check # type-check only
|
|
32
|
-
mise run lint # lint TypeScript files
|
|
33
|
-
mise run format # auto-format code with Prettier
|
|
34
|
-
mise run format:check # check formatting (CI mode)
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
## Project Structure
|
|
38
|
-
|
|
39
|
-
```
|
|
40
|
-
src/
|
|
41
|
-
index.ts Extension entry point (lifecycle hooks, wiring)
|
|
42
|
-
mcp/ MCP client management (connections, tool discovery)
|
|
43
|
-
skills/ Skill registry, discovery, gating, tool proxies
|
|
44
|
-
tool-cli/ tool-cli RPC server, client, CLI binary, prompt
|
|
45
|
-
test-servers/ Test MCP servers (weather, echo)
|
|
46
|
-
dist/ Compiled output (gitignored)
|
|
47
|
-
scripts/ Integration and smoke test scripts
|
|
48
|
-
mise.toml Tool versions and tasks
|
|
49
|
-
package.json Dependencies and npm scripts
|
|
50
|
-
tsconfig.json TypeScript configuration
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
## Architecture
|
|
54
|
-
|
|
55
|
-
### Tiered MCP Tool Access
|
|
56
|
-
|
|
57
|
-
The extension provides three tiers for exposing MCP tools to the agent:
|
|
58
|
-
|
|
59
|
-
| Tier | Mechanism | When Used |
|
|
60
|
-
| ------------- | ------------------------------------------------------------------ | ------------------------------------------------ |
|
|
61
|
-
| 1 — Skills | `deferred: true` + `tool_call` gate → tools unlocked by load_skill | MCP server ships skills |
|
|
62
|
-
| 2 — tool-cli | CLI progressive discovery via shell | Ad-hoc exploration, no skills |
|
|
63
|
-
| 3 — Code Mode | search+execute, no HITL | Read-only tools with structured output (planned) |
|
|
64
|
-
|
|
65
|
-
### tool-cli Architecture
|
|
66
|
-
|
|
67
|
-
tool-cli is a thin CLI binary that communicates with the extension via JSON-RPC 2.0 over HTTP. The agent uses it as a standard shell command, composable with pipes, grep, jq, loops, etc.
|
|
68
|
-
|
|
69
|
-
```
|
|
70
|
-
Agent (mcpi)
|
|
71
|
-
│
|
|
72
|
-
│ shell exec
|
|
73
|
-
▼
|
|
74
|
-
tool-cli <server> <tool> '{"args"}'
|
|
75
|
-
│
|
|
76
|
-
│ HTTP JSON-RPC (localhost:7179)
|
|
77
|
-
▼
|
|
78
|
-
ToolCliRpcServer (in extension process)
|
|
79
|
-
│
|
|
80
|
-
│ MCP protocol (stdio/HTTP)
|
|
81
|
-
▼
|
|
82
|
-
MCP Server(s)
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
**Key design points:**
|
|
86
|
-
|
|
87
|
-
- **No auth (temporary)** — the RPC server binds to `127.0.0.1` only, limiting access to the local machine. This is acceptable for development but not a finished security posture — any local process can call the server and execute MCP tools. Future work should add a shared secret or token (e.g. passed via environment variable to the CLI) so only the intended agent process can make calls.
|
|
88
|
-
- **Interception point for HITL** — the RPC server's `callTool` method is the single choke point for all tool execution. Future work can check tool annotations (`readOnlyHint`, `destructiveHint`) here and gate non-read-only calls through user confirmation before forwarding to the MCP server.
|
|
89
|
-
- **Progressive discovery** — the agent discovers servers → tools → schemas incrementally, paying only the tokens it needs.
|
|
90
|
-
- **Shell-native** — plain text output composes with grep, jq, xargs, pipes, loops. The agent can chain tool calls using standard bash idioms.
|
|
91
|
-
|
|
92
|
-
## Code Quality
|
|
93
|
-
|
|
94
|
-
- **ESLint** — flat config with `typescript-eslint` (strict + stylistic) and Prettier compat
|
|
95
|
-
- **Prettier** — auto-formatting (double quotes, semicolons, trailing commas, 100 char width)
|
|
96
|
-
- **CI** — GitHub Actions runs lint → format:check → type-check → build → test on every PR
|
|
97
|
-
- **Dependabot** — automated dependency updates (npm + GitHub Actions)
|
|
98
|
-
|
|
99
|
-
Run `mise run lint` and `mise run format` before committing. CI will reject PRs that fail any check.
|
|
100
|
-
|
|
101
|
-
**Before pushing**, always run:
|
|
102
|
-
|
|
103
|
-
```sh
|
|
104
|
-
mise run lint # lint must pass
|
|
105
|
-
mise run test # tests must pass
|
|
106
|
-
mise run format:check # formatting must pass
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
## Decision Log
|
|
110
|
-
|
|
111
|
-
We maintain a [DECISIONS.md](DECISIONS.md) file recording key architectural and design decisions. Keep it up to date when making significant choices — add a new numbered entry with date, context, decision, and rationale.
|
|
112
|
-
|
|
113
|
-
## Conventions
|
|
114
|
-
|
|
115
|
-
- ESM (`"type": "module"`)
|
|
116
|
-
- Target: ES2022, module: Node16
|
|
117
|
-
- Strict TypeScript
|
|
118
|
-
- Tests with vitest (co-located `*.test.ts` files)
|
package/DECISIONS.md
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
# Decision Log
|
|
2
|
-
|
|
3
|
-
Record of key architectural and design decisions. Keep this up to date as decisions are made.
|
|
4
|
-
|
|
5
|
-
## 001 — Extension, not fork
|
|
6
|
-
|
|
7
|
-
**Date:** 2026-04-23
|
|
8
|
-
**Context:** Should we fork pi to build the MCP agent harness, or use the extension API?
|
|
9
|
-
**Decision:** Build as a pi extension. The extension API provides everything we need: `registerTool()`, `setActiveTools()`, `on("tool_result", ...)`, `exec()`, lifecycle hooks.
|
|
10
|
-
**Rationale:** Everything in scope (skill-gated tool visibility, football CLI, code mode, output offloading) is policy and orchestration — deciding _when_ and _how_ to expose MCP tools to the model. That's extension territory. We'd only need to fork if we needed to change pi's tool dispatch, context assembly, or model loop.
|
|
11
|
-
|
|
12
|
-
## 002 — Agent harness controls tool visibility, not MCP servers
|
|
13
|
-
|
|
14
|
-
**Date:** 2026-04-23
|
|
15
|
-
**Context:** How do MCP tools become visible to the model?
|
|
16
|
-
**Decision:** The harness (pi extension) decides what tools the model sees. MCP servers just expose their tools and optionally their skills. The harness holds all discovered tools internally and only sends them to the model when a skill names them.
|
|
17
|
-
**Rationale:** Maximal agent capability, minimal tokens. The model's context window isn't stuffed with every tool from every connected MCP server. Tools appear only when a skill provides the context for using them.
|
|
18
|
-
|
|
19
|
-
## 003 — Tiered access model
|
|
20
|
-
|
|
21
|
-
**Date:** 2026-04-23
|
|
22
|
-
**Context:** How should the model access MCP tools?
|
|
23
|
-
**Decision:** Three tiers of access, all complementary:
|
|
24
|
-
|
|
25
|
-
| Tier | Mechanism | When Used |
|
|
26
|
-
| ------------------ | ------------------------------------------------------------ | -------------------------------------- |
|
|
27
|
-
| 1 — Skills (#1) | Skill loaded → `allowed-tools` exact-matched → tools visible | MCP server ships skills |
|
|
28
|
-
| 2 — Football (#2) | CLI progressive discovery → HITL for writes | Ad-hoc exploration, no skills |
|
|
29
|
-
| 3 — Code Mode (#4) | search+execute → no HITL | Read-only tools with structured output |
|
|
30
|
-
|
|
31
|
-
**Rationale:** Different situations call for different access patterns. Skills give direct access with workflow knowledge. Football gives interactive access with safety. Code mode gives autonomous access to safe operations at scale.
|
|
32
|
-
|
|
33
|
-
## 004 — Large tool output offloading
|
|
34
|
-
|
|
35
|
-
**Date:** 2026-04-23
|
|
36
|
-
**Context:** Tool responses can be thousands of tokens, wasting context window.
|
|
37
|
-
**Decision:** Intercept tool results via `pi.on("tool_result", ...)`. If output exceeds ~500 tokens, write to a file and return a pointer to the model.
|
|
38
|
-
**Rationale:** Controls output token cost the same way skills/football/code-mode control input token cost. The model can read the file if it needs the content.
|
|
39
|
-
|
|
40
|
-
## 005 — MCP SDK and JSON config for server connections
|
|
41
|
-
|
|
42
|
-
**Date:** 2026-04-23
|
|
43
|
-
**Context:** How should the extension connect to MCP servers?
|
|
44
|
-
**Decision:** Use `@modelcontextprotocol/sdk` (TypeScript MCP SDK) with a JSON config file at `~/.config/mcpi-ext/mcp.json` (overridable via `--mcp-config` flag). The config supports two transport types: `stdio` (spawns a child process) and `remote` (Streamable HTTP). A `McpClientManager` class connects to all configured servers on `session_start`, discovers tools via `tools/list`, handles `notifications/tools/list_changed`, and disconnects on `session_shutdown`.
|
|
45
|
-
**Rationale:** The official MCP SDK is the canonical way to implement MCP clients. JSON config aligns with VS Code and Claude Code conventions for MCP server configuration. Supporting both stdio and remote covers local dev servers and cloud-hosted MCP endpoints. Tools are discovered and stored internally but NOT registered with pi — the access tiers (Skills #1, Football #2, Code Mode #4) decide when to expose tools to the model.
|
|
46
|
-
|
|
47
|
-
## 006 — CI model access via GITHUB_TOKEN
|
|
48
|
-
|
|
49
|
-
**Date:** 2026-04-23
|
|
50
|
-
**Context:** Can Pi's `github-copilot` provider use the Actions `GITHUB_TOKEN` for model inference in CI?
|
|
51
|
-
**Decision:** Yes. The GitHub Models API (GA since April 2025) grants model inference to the Actions `GITHUB_TOKEN` when the workflow declares `permissions: models: read`. Pi's `--provider github-copilot` uses this same API. The CI workflow declares this permission so future e2e tests can run Pi with model access without a PAT.
|
|
52
|
-
**Rationale:** Using the built-in `GITHUB_TOKEN` avoids storing secrets for CI model access. The `models: read` scope is the minimum required — no write access needed. This enables full trajectory e2e tests in CI (connect to MCP servers, run Pi agent, verify results).
|
|
53
|
-
|
|
54
|
-
## 007 — Custom skill registry for MCP skills, not Pi's native skill system
|
|
55
|
-
|
|
56
|
-
**Date:** 2026-04-23
|
|
57
|
-
**Context:** Should MCP-discovered skills use Pi's built-in `loadSkills`/`formatSkillsForPrompt` pipeline (writing SKILL.md files to disk) or a custom in-extension registry?
|
|
58
|
-
**Decision:** Custom `SkillRegistry` + `load_skill` tool + `formatMcpSkillsForPrompt`, styled after Pi's native skill system but fully self-contained in the extension. Skills are discovered from MCP `skill://` resources and injected into the system prompt via the `before_agent_start` hook.
|
|
59
|
-
**Rationale:** MCP skills live on remote servers, not on disk. Writing them to temp files would be fragile and unnecessary. The custom approach keeps MCP skills self-contained, gives us full control over the activation → tool gating flow, and avoids coupling to Pi's internal skill loader. The XML format matches Pi's `<available_skills>` pattern so models already know how to interact with it.
|
|
60
|
-
|
|
61
|
-
## 008 — Cache-safe progressive tool disclosure via `deferred` flag
|
|
62
|
-
|
|
63
|
-
**Date:** 2026-05-11
|
|
64
|
-
**Context:** When `load_skill` called `setActiveTools()` to reveal new tools, the tools array sent to the model changed, invalidating prompt cache. Decision 008 previously accepted this trade-off.
|
|
65
|
-
**Decision:** Use `deferred: true` on MCP tool proxies with provider-native support and extension-level gating:
|
|
66
|
-
|
|
67
|
-
1. **Anthropic:** pi-mono maps `deferred: true` to `defer_loading: true` in the API payload. Deferred tools stay in the tools array but are hidden from the model's view. Optional `tool_reference` content blocks can explicitly enable them on demand.
|
|
68
|
-
2. **OpenAI Responses:** pi-mono maps `deferred: true` to `defer_loading: true` and auto-injects `{"type": "tool_search"}` into the tools array. The model discovers deferred tools automatically via hosted server-side search — no explicit activation needed. (OpenAI's client-executed `tool_search_output` is the equivalent of Anthropic's `tool_reference`, but hosted search is sufficient for our use case.)
|
|
69
|
-
3. **All providers (fallback):** The extension's `tool_call` hook blocks premature calls to gated tools and returns an error message naming the relevant skill. After `load_skill` fires, tools are marked as enabled and calls go through.
|
|
70
|
-
|
|
71
|
-
**Rationale:** Both Anthropic and OpenAI natively support `defer_loading` (tested with Claude Opus 4.7 and GPT-5.4). The tools array and system prompt stay constant throughout the conversation — prompt cache is fully preserved. The `tool_call` hook provides a provider-agnostic enforcement layer for providers without native `defer_loading` support.
|
|
72
|
-
|
|
73
|
-
## 009 — tool-cli uses JSON-RPC 2.0 over HTTP on a predefined port
|
|
74
|
-
|
|
75
|
-
**Date:** 2026-04-24
|
|
76
|
-
**Context:** The Football CLI (issue #2) needs a communication protocol between the thin CLI binary and the extension that manages MCP connections.
|
|
77
|
-
**Decision:** JSON-RPC 2.0 over HTTP on `localhost:7179` (overridable via `TOOL_CLI_PORT` env var). The RPC server lives in the extension, started on `session_start` and stopped on `session_shutdown`. The CLI binary (`tool-cli`) is a thin client that uses `fetch` to call the server. No new dependencies — uses Node's `http` module for the server and global `fetch` for the client.
|
|
78
|
-
**Rationale:** JSON-RPC 2.0 is a standard, simple protocol that maps cleanly to the four operations needed (listServers, listTools, describeTool, callTool). HTTP is the simplest transport for request/response. A predefined port avoids coordination complexity for now. The architecture supports future HITL confirmation for non-read-only tools — the RPC server's `callTool` method is the single choke point where tool annotations can be checked and destructive calls gated through user approval.
|
|
79
|
-
|
|
80
|
-
## 010 — tool-cli has no auth (known limitation)
|
|
81
|
-
|
|
82
|
-
**Date:** 2026-04-24
|
|
83
|
-
**Context:** The tool-cli RPC server listens on `127.0.0.1:7179` with no authentication. Any local process can discover and execute MCP tools through it.
|
|
84
|
-
**Decision:** Accept this for now as a development convenience. The server is localhost-only, which limits the blast radius to local processes, but this is not a finished security posture. Before production use, add a shared secret (e.g. a one-time token passed via environment variable from the extension to the CLI) so only the intended agent process can make calls.
|
|
85
|
-
**Rationale:** Adding auth now would complicate the initial implementation without changing the threat model much — the agent already has shell access and could call MCP tools through other means. But as the tool matures and especially once HITL gating is added for destructive tools, unauthenticated access would let other local processes bypass those safety checks. Auth is a prerequisite for trustworthy HITL.
|
|
86
|
-
|
|
87
|
-
## 011 — Code mode uses `isolated-vm` for sandbox execution
|
|
88
|
-
|
|
89
|
-
**Date:** 2026-04-24
|
|
90
|
-
**Context:** Code mode (#4) lets the model write JavaScript to chain read-only MCP tool calls. The generated code runs in a sandbox. Options evaluated: Node `vm` module, `isolated-vm`, Deno subprocess, Cloudflare workerd, Pydantic/Python subprocess, WASM.
|
|
91
|
-
**Decision:** Use `isolated-vm` (V8 isolates in Node.js). Provides memory limits (128MB default), CPU timeouts (30s default), and V8-level isolation. Tool dispatch via `Reference` async callbacks — actual MCP calls execute on the host, never in the sandbox.
|
|
92
|
-
**Rationale:** Code mode has no HITL (human-in-the-loop) since all tools are read-only, making sandbox security important. Node's `vm` module is documented as "not a security mechanism" and is escapable via prototype pollution. `isolated-vm` provides genuine V8-level isolation with ~15ms overhead — negligible vs MCP network I/O. Deno subprocess (400ms/call) and workerd are too slow or complex for interactive use.
|
|
93
|
-
|
|
94
|
-
## 012 — Code mode uses `ctx.eval` instead of `compileModule` for execution
|
|
95
|
-
|
|
96
|
-
**Date:** 2026-04-24
|
|
97
|
-
**Context:** Initial implementation used `isolate.compileModule()` + `module.evaluate()` for running sandboxed code with top-level await. Discovery: `module.evaluate()` resolves prematurely when multiple sequential `Reference.apply()` calls use `{ result: { promise: true } }` — the module evaluation promise resolves after the first async reference call, not after all code completes.
|
|
98
|
-
**Decision:** Use `ctx.eval()` with `{ promise: true, copy: true }` instead. Wrap user code in an async IIFE that returns the final result.
|
|
99
|
-
**Rationale:** `ctx.eval` with `promise: true` correctly awaits the full async IIFE, including all sequential tool dispatch calls. This is critical for code mode's chaining use case where the model writes for-loops calling multiple tools sequentially.
|
package/Dockerfile
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
FROM node:22-slim
|
|
2
|
-
|
|
3
|
-
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
|
4
|
-
|
|
5
|
-
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
6
|
-
git \
|
|
7
|
-
curl \
|
|
8
|
-
ripgrep \
|
|
9
|
-
ca-certificates \
|
|
10
|
-
gnupg \
|
|
11
|
-
&& rm -rf /var/lib/apt/lists/*
|
|
12
|
-
|
|
13
|
-
# Docker CLI (for Docker-in-Docker via mounted socket)
|
|
14
|
-
RUN install -m 0755 -d /etc/apt/keyrings \
|
|
15
|
-
&& curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg \
|
|
16
|
-
&& chmod a+r /etc/apt/keyrings/docker.gpg \
|
|
17
|
-
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
|
|
18
|
-
https://download.docker.com/linux/debian $(. /etc/os-release && echo "$VERSION_CODENAME") stable" \
|
|
19
|
-
> /etc/apt/sources.list.d/docker.list \
|
|
20
|
-
&& apt-get update \
|
|
21
|
-
&& apt-get install -y --no-install-recommends docker-ce-cli \
|
|
22
|
-
&& rm -rf /var/lib/apt/lists/*
|
|
23
|
-
|
|
24
|
-
# uv (Python package manager — for running Python-based MCP servers)
|
|
25
|
-
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /usr/local/bin/
|
|
26
|
-
|
|
27
|
-
WORKDIR /app
|
|
28
|
-
|
|
29
|
-
COPY package.json ./
|
|
30
|
-
RUN npm install --ignore-scripts
|
|
31
|
-
|
|
32
|
-
COPY tsconfig.json ./
|
|
33
|
-
COPY src ./src
|
|
34
|
-
RUN npx tsc
|
|
35
|
-
|
|
36
|
-
COPY scripts/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
|
|
37
|
-
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
|
|
38
|
-
|
|
39
|
-
ENTRYPOINT ["docker-entrypoint.sh"]
|