@klhapp/skillmux 1.1.0 → 1.3.0
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/CHANGELOG.md +22 -0
- package/README.md +155 -516
- package/config.example.toml +5 -4
- package/config.remote.example.toml +8 -3
- package/docs/README.md +52 -0
- package/docs/assets/architecture.svg +156 -0
- package/docs/assets/logo.png +0 -0
- package/docs/calibration.md +111 -0
- package/docs/cli.md +350 -0
- package/docs/concepts.md +165 -0
- package/docs/configuration.md +41 -8
- package/docs/deployment.md +250 -0
- package/docs/getting-started.md +239 -0
- package/docs/mcp-routing.md +172 -0
- package/docs/releasing.md +4 -3
- package/docs/skill-management.md +209 -0
- package/docs/troubleshooting.md +199 -0
- package/package.json +3 -5
- package/src/adapters.ts +33 -40
- package/src/calibrate.ts +165 -9
- package/src/cli.ts +51 -6
- package/src/config-watcher.ts +5 -1
- package/src/dataset-generator.ts +75 -96
- package/src/server.ts +10 -70
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
# Deployment
|
|
2
|
+
|
|
3
|
+
Choose a deployment from the client count and inference source:
|
|
4
|
+
|
|
5
|
+
| Use case | Recommended package | Transport | Inference |
|
|
6
|
+
| --- | --- | --- | --- |
|
|
7
|
+
| Native skill management | Skillmux CLI | Filesystem | None required |
|
|
8
|
+
| Local MCP retrieval | Skillmux CLI | stdio | Downloaded GTE-small |
|
|
9
|
+
| Shared MCP with local inference | Full Docker image | Streamable HTTP | Bundled GTE-small |
|
|
10
|
+
| Shared MCP with remote or lexical retrieval | Slim Docker image (advanced) | Streamable HTTP | Remote endpoint or lexical fallback |
|
|
11
|
+
|
|
12
|
+
Install the CLI with either the Bun package or standalone Linux executable;
|
|
13
|
+
they expose the same commands and can also serve HTTP. Deploy the full Docker
|
|
14
|
+
image for a shared service by default. Docker can serve stdio when a client
|
|
15
|
+
requires a container command; use slim only for remote or lexical retrieval.
|
|
16
|
+
|
|
17
|
+
“Local inference” means the model runs in the Skillmux process. It does not
|
|
18
|
+
mean that the MCP client must run on the same machine.
|
|
19
|
+
|
|
20
|
+
## Skillmux CLI
|
|
21
|
+
|
|
22
|
+
Run stdio MCP beside one client:
|
|
23
|
+
|
|
24
|
+
```sh
|
|
25
|
+
skillmux models download
|
|
26
|
+
skillmux index
|
|
27
|
+
skillmux serve
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Run an HTTP service without Docker:
|
|
31
|
+
|
|
32
|
+
```sh
|
|
33
|
+
skillmux serve --transport http --port 3000
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The native HTTP server binds `127.0.0.1` by default. Configure authentication
|
|
37
|
+
and a reachable hostname before serving other machines.
|
|
38
|
+
|
|
39
|
+
## Docker images
|
|
40
|
+
|
|
41
|
+
Skillmux publishes Linux AMD64 and ARM64 images to GHCR and Docker Hub:
|
|
42
|
+
|
|
43
|
+
| Variant | GHCR tag | Contents |
|
|
44
|
+
| --- | --- | --- |
|
|
45
|
+
| Full | `ghcr.io/klhq/skillmux:latest` | Runtime plus bundled GTE-small |
|
|
46
|
+
| Slim | `ghcr.io/klhq/skillmux:latest-slim` | Runtime without model files; remote or lexical retrieval |
|
|
47
|
+
|
|
48
|
+
Docker Hub mirrors the same tags under `docker.io/klhq/skillmux`.
|
|
49
|
+
|
|
50
|
+
Neither image bundles a local reranker. Configure a remote reranker when your
|
|
51
|
+
retrieval policy needs one.
|
|
52
|
+
|
|
53
|
+
Use the full image when the service should run embeddings itself:
|
|
54
|
+
|
|
55
|
+
```sh
|
|
56
|
+
docker run -d \
|
|
57
|
+
--name skillmux \
|
|
58
|
+
-v ~/skills:/vault:ro \
|
|
59
|
+
-v skillmux-data:/data \
|
|
60
|
+
-p 3000:3000 \
|
|
61
|
+
ghcr.io/klhq/skillmux:latest
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
The container sets:
|
|
65
|
+
|
|
66
|
+
- `VAULT_PATH=/vault`;
|
|
67
|
+
- `STATE_DIR=/data`;
|
|
68
|
+
- `PORT=3000`;
|
|
69
|
+
- `RUNNING_IN_DOCKER=true`.
|
|
70
|
+
|
|
71
|
+
Mount the vault read-only for a retrieval-only service. Run `install`, `init`,
|
|
72
|
+
`sync`, and other filesystem management commands on the host. Containerized
|
|
73
|
+
native management is intentionally rejected: agent directories belong to the
|
|
74
|
+
host CLI, where their symlinks resolve correctly.
|
|
75
|
+
|
|
76
|
+
## Container command contract
|
|
77
|
+
|
|
78
|
+
The image separates its executable from its default command. Running an image
|
|
79
|
+
without arguments starts Streamable HTTP MCP on port 3000:
|
|
80
|
+
|
|
81
|
+
```sh
|
|
82
|
+
docker run ghcr.io/klhq/skillmux:latest
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Arguments after the image replace that default, so one-shot maintenance and
|
|
86
|
+
stdio use the same image:
|
|
87
|
+
|
|
88
|
+
```sh
|
|
89
|
+
docker run --rm -v ~/skills:/vault:ro -v skillmux-data:/data \
|
|
90
|
+
ghcr.io/klhq/skillmux:latest doctor
|
|
91
|
+
docker run --rm -v ~/skills:/vault:ro -v skillmux-data:/data \
|
|
92
|
+
ghcr.io/klhq/skillmux:latest index
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Docker Compose `command:` and Kubernetes `args:` likewise replace only the
|
|
96
|
+
default command, not the executable.
|
|
97
|
+
|
|
98
|
+
The supported container commands are `serve`, `index`, `doctor`, `report`,
|
|
99
|
+
`scan`, `skill which`, and read-only `config show`, `config get`,
|
|
100
|
+
`config validate`, `config diff`, and `config status`.
|
|
101
|
+
|
|
102
|
+
The image rejects host-management commands, including `init`, `sync`,
|
|
103
|
+
`install`, `project`, `target`, `core`, `local-vault`, `models download`,
|
|
104
|
+
context management, calibration, evaluation, and configuration initialization
|
|
105
|
+
or mutation. Install the Skillmux CLI on the host when a command needs to
|
|
106
|
+
manage a local vault or agent directory.
|
|
107
|
+
|
|
108
|
+
## Slim image
|
|
109
|
+
|
|
110
|
+
The slim image stays ready in lexical mode without an inference endpoint.
|
|
111
|
+
Configure remote embeddings to enable hybrid retrieval:
|
|
112
|
+
|
|
113
|
+
```sh
|
|
114
|
+
docker run -d \
|
|
115
|
+
--name skillmux-slim \
|
|
116
|
+
-v ~/skills:/vault:ro \
|
|
117
|
+
-v skillmux-data:/data \
|
|
118
|
+
-p 3000:3000 \
|
|
119
|
+
-e EMBED_ENDPOINT="https://embedding.example.com/v1/embeddings" \
|
|
120
|
+
-e EMBED_MODEL="your-embedding-model" \
|
|
121
|
+
-e EMBED_DIMENSION="1024" \
|
|
122
|
+
ghcr.io/klhq/skillmux:latest-slim
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Set `SKILLMUX_CONFIG` and mount a TOML file when you need reranking, calibrated
|
|
126
|
+
thresholds, server policy, or API-key environment names:
|
|
127
|
+
|
|
128
|
+
```sh
|
|
129
|
+
docker run -d \
|
|
130
|
+
--name skillmux-slim \
|
|
131
|
+
-v ~/skills:/vault:ro \
|
|
132
|
+
-v skillmux-data:/data \
|
|
133
|
+
-v "$PWD/config.toml:/etc/skillmux/config.toml:ro" \
|
|
134
|
+
-e SKILLMUX_CONFIG=/etc/skillmux/config.toml \
|
|
135
|
+
-e EMBEDDING_API_KEY \
|
|
136
|
+
-e RERANKER_API_KEY \
|
|
137
|
+
-p 3000:3000 \
|
|
138
|
+
ghcr.io/klhq/skillmux:latest-slim
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Start from [config.remote.example.toml](../config.remote.example.toml).
|
|
142
|
+
|
|
143
|
+
## Docker over stdio
|
|
144
|
+
|
|
145
|
+
Some local clients can launch a container as their stdio MCP command:
|
|
146
|
+
|
|
147
|
+
```sh
|
|
148
|
+
docker run --no-healthcheck -i --rm \
|
|
149
|
+
-v ~/skills:/vault:ro \
|
|
150
|
+
-v skillmux-data:/data \
|
|
151
|
+
ghcr.io/klhq/skillmux:latest serve --transport stdio
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
The container must keep standard input open, so use `-i`. Disable the baked
|
|
155
|
+
HTTP health check for stdio because no HTTP listener is started.
|
|
156
|
+
|
|
157
|
+
## Expose HTTP safely
|
|
158
|
+
|
|
159
|
+
The Skillmux CLI binds `127.0.0.1`. Docker binds `0.0.0.0` so
|
|
160
|
+
port mapping works. Before exposing the port beyond a trusted host:
|
|
161
|
+
|
|
162
|
+
```toml
|
|
163
|
+
[server]
|
|
164
|
+
hostname = "0.0.0.0"
|
|
165
|
+
auth_enabled = true
|
|
166
|
+
auth_token_env = "SKILLMUX_AUTH_TOKEN"
|
|
167
|
+
allowed_origins = []
|
|
168
|
+
|
|
169
|
+
[server.rate_limit]
|
|
170
|
+
enabled = true
|
|
171
|
+
requests_per_minute = 60
|
|
172
|
+
trust_proxy = false
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Set the token in the process environment:
|
|
176
|
+
|
|
177
|
+
```sh
|
|
178
|
+
export SKILLMUX_AUTH_TOKEN="replace-with-a-long-random-token"
|
|
179
|
+
skillmux serve --transport http
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Clients send:
|
|
183
|
+
|
|
184
|
+
```text
|
|
185
|
+
Authorization: Bearer replace-with-a-long-random-token
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
`allowed_origins` controls browser CORS requests. Requests without an `Origin`
|
|
189
|
+
header, including MCP clients and curl, do not need a CORS entry.
|
|
190
|
+
|
|
191
|
+
Keep `trust_proxy = false` unless a trusted reverse proxy overwrites
|
|
192
|
+
`X-Forwarded-For`. A client can spoof that header when it reaches Skillmux
|
|
193
|
+
directly.
|
|
194
|
+
|
|
195
|
+
## Health and metrics
|
|
196
|
+
|
|
197
|
+
The HTTP server provides:
|
|
198
|
+
|
|
199
|
+
| Endpoint | Purpose |
|
|
200
|
+
| --- | --- |
|
|
201
|
+
| `GET /health/live` | Process liveness |
|
|
202
|
+
| `GET /health/ready` | Vault, index, inference, and active capability |
|
|
203
|
+
| `GET /health` | Compatibility alias for liveness |
|
|
204
|
+
| `GET /metrics` | Prometheus text exposition |
|
|
205
|
+
| `GET /stats` | Aggregated routing outcomes for `skillmux report` |
|
|
206
|
+
| `POST /mcp` | Streamable HTTP MCP transport |
|
|
207
|
+
|
|
208
|
+
The Docker health check calls `/health/ready`.
|
|
209
|
+
|
|
210
|
+
Prometheus metrics cover request totals, resolve outcomes, latency, errors, and
|
|
211
|
+
rate-limit rejections. Health and metrics do not require bearer authentication,
|
|
212
|
+
but `/stats` does when server authentication is enabled. CORS still applies to
|
|
213
|
+
browser requests.
|
|
214
|
+
|
|
215
|
+
## Remote administration
|
|
216
|
+
|
|
217
|
+
Name a deployed server without storing its token:
|
|
218
|
+
|
|
219
|
+
```sh
|
|
220
|
+
skillmux context add prod \
|
|
221
|
+
--server https://skillmux.example.com \
|
|
222
|
+
--token-env SKILLMUX_PROD_ADMIN_TOKEN
|
|
223
|
+
skillmux context use prod
|
|
224
|
+
skillmux config status
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
The context stores the token environment variable name. Export its value in
|
|
228
|
+
the shell before running admin commands.
|
|
229
|
+
|
|
230
|
+
Enable the admin API and use a separate admin token in server configuration.
|
|
231
|
+
Read [CLI reference](cli.md#administrative-http-api-adminv1) for routes and
|
|
232
|
+
[Configuration](configuration.md#http-server) for reload behavior.
|
|
233
|
+
|
|
234
|
+
## Persistent data and backups
|
|
235
|
+
|
|
236
|
+
Persist `state_dir` to retain the index, audit log, and calibration evidence.
|
|
237
|
+
Skill content remains in the vault and should use its own backup or Git
|
|
238
|
+
workflow.
|
|
239
|
+
|
|
240
|
+
Treat the state database as sensitive because audit rows can contain raw user
|
|
241
|
+
queries. Stop the process or use SQLite-safe backup tooling before copying a
|
|
242
|
+
live database.
|
|
243
|
+
|
|
244
|
+
## Native pins with shared retrieval
|
|
245
|
+
|
|
246
|
+
For the combined topology, use one Git-backed vault source of truth: each
|
|
247
|
+
machine that manages native skills keeps its own checkout and runs the CLI;
|
|
248
|
+
the shared service mounts its own checkout for retrieval. Skillmux does not
|
|
249
|
+
pull, push, replicate, or otherwise keep those vault checkouts fresh—Git and
|
|
250
|
+
your deployment process own that responsibility.
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
# Getting started
|
|
2
|
+
|
|
3
|
+
Skillmux supports three setup paths. Pick the result you want before choosing
|
|
4
|
+
an installation.
|
|
5
|
+
|
|
6
|
+
| Goal | Skill delivery | Recommended installation |
|
|
7
|
+
| --- | --- | --- |
|
|
8
|
+
| [Manage native skills](#manage-native-skills) | Managed links in client skill directories | Skillmux CLI |
|
|
9
|
+
| [Add local MCP retrieval](#add-local-mcp-retrieval) | Local stdio MCP | Skillmux CLI |
|
|
10
|
+
| [Run a shared MCP service](#run-a-shared-mcp-service) | Streamable HTTP MCP | Full Docker image |
|
|
11
|
+
|
|
12
|
+
Native management and local MCP retrieval can run together. Complete both
|
|
13
|
+
recipes if you want pinned skills plus on-demand access to the rest of the
|
|
14
|
+
vault.
|
|
15
|
+
|
|
16
|
+
## Install the CLI
|
|
17
|
+
|
|
18
|
+
Use the Bun package on macOS, Linux, or Windows. It requires
|
|
19
|
+
[Bun 1.3 or newer](https://bun.sh/docs/installation):
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
bun add -g @klhapp/skillmux
|
|
23
|
+
skillmux --help
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Native target sync needs permission to create directory symlinks on Windows.
|
|
27
|
+
|
|
28
|
+
Linux users without Bun can install the standalone AMD64 or ARM64 executable
|
|
29
|
+
instead:
|
|
30
|
+
|
|
31
|
+
```sh
|
|
32
|
+
gh release download --repo klhq/skillmux --pattern 'skillmux-linux-*'
|
|
33
|
+
gh attestation verify skillmux-linux-amd64 --repo klhq/skillmux
|
|
34
|
+
chmod +x skillmux-linux-amd64
|
|
35
|
+
sudo install skillmux-linux-amd64 /usr/local/bin/skillmux
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Replace `amd64` with `arm64` on ARM64. The Bun package and standalone Linux
|
|
39
|
+
executable expose the same Skillmux CLI commands.
|
|
40
|
+
|
|
41
|
+
## Prepare a vault
|
|
42
|
+
|
|
43
|
+
Skillmux defaults to `~/skills`. Each direct child directory represents one
|
|
44
|
+
skill:
|
|
45
|
+
|
|
46
|
+
```text
|
|
47
|
+
~/skills/
|
|
48
|
+
├── code-context/
|
|
49
|
+
│ └── SKILL.md
|
|
50
|
+
└── csv-formatter/
|
|
51
|
+
├── SKILL.md
|
|
52
|
+
└── references/
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Each `SKILL.md` needs valid Agent Skills frontmatter. With the Skillmux CLI,
|
|
56
|
+
you can install a skill from Git:
|
|
57
|
+
|
|
58
|
+
```sh
|
|
59
|
+
skillmux install owner/repo
|
|
60
|
+
skillmux install owner/repo/path/to/skill
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Or create a small skill:
|
|
64
|
+
|
|
65
|
+
```sh
|
|
66
|
+
mkdir -p ~/skills/csv-formatter
|
|
67
|
+
cat > ~/skills/csv-formatter/SKILL.md <<'EOF'
|
|
68
|
+
---
|
|
69
|
+
name: CSV Formatter
|
|
70
|
+
description: Convert CSV or spreadsheet data into clean Markdown tables.
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
# CSV Formatter
|
|
74
|
+
|
|
75
|
+
Read the first row as headers. Right-align numbers and left-align text.
|
|
76
|
+
EOF
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Run `skillmux scan ~/skills` before adopting an existing collection.
|
|
80
|
+
|
|
81
|
+
## Manage native skills
|
|
82
|
+
|
|
83
|
+
Run the guided setup on the machine that owns the client skill directories:
|
|
84
|
+
|
|
85
|
+
```sh
|
|
86
|
+
skillmux init
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
The planner:
|
|
90
|
+
|
|
91
|
+
1. validates the vault;
|
|
92
|
+
2. detects clients from filesystem evidence;
|
|
93
|
+
3. asks which skills belong in the core tier;
|
|
94
|
+
4. shows the config, target, instruction, and sync plan;
|
|
95
|
+
5. applies the plan after confirmation.
|
|
96
|
+
|
|
97
|
+
Skillmux writes machine config under `~/.config/skillmux`, stores tier policy
|
|
98
|
+
in `~/skills/skillmux.toml`, and records its entries in each target's
|
|
99
|
+
`.skillmux` marker. It preserves unmanaged files and existing instruction
|
|
100
|
+
text.
|
|
101
|
+
|
|
102
|
+
Use explicit flags for automation:
|
|
103
|
+
|
|
104
|
+
```sh
|
|
105
|
+
skillmux init \
|
|
106
|
+
--client claude-code \
|
|
107
|
+
--client codex \
|
|
108
|
+
--core csv-formatter \
|
|
109
|
+
--dry-run
|
|
110
|
+
|
|
111
|
+
skillmux init \
|
|
112
|
+
--client claude-code \
|
|
113
|
+
--client codex \
|
|
114
|
+
--core csv-formatter \
|
|
115
|
+
--yes
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Verify native delivery:
|
|
119
|
+
|
|
120
|
+
```sh
|
|
121
|
+
skillmux sync
|
|
122
|
+
skillmux doctor
|
|
123
|
+
skillmux skill which csv-formatter
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Repeated syncs are idempotent. Add project-specific skills from a repository
|
|
127
|
+
root:
|
|
128
|
+
|
|
129
|
+
```sh
|
|
130
|
+
skillmux project init
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
The noninteractive form accepts repeatable client and skill flags:
|
|
134
|
+
|
|
135
|
+
```sh
|
|
136
|
+
skillmux project init ~/code/my-project \
|
|
137
|
+
--name my-project \
|
|
138
|
+
--client claude-code \
|
|
139
|
+
--client codex \
|
|
140
|
+
--skill code-context \
|
|
141
|
+
--yes
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Continue with [Managing skills](skill-management.md) for pinning, target
|
|
145
|
+
ownership, overlays, and recovery.
|
|
146
|
+
|
|
147
|
+
## Add local MCP retrieval
|
|
148
|
+
|
|
149
|
+
Run this recipe on the same machine as the MCP client. The default inference
|
|
150
|
+
configuration uses quantized GTE-small embeddings on CPU.
|
|
151
|
+
|
|
152
|
+
Prefetch the model, build the index, and check readiness:
|
|
153
|
+
|
|
154
|
+
```sh
|
|
155
|
+
skillmux models download
|
|
156
|
+
skillmux index
|
|
157
|
+
skillmux doctor
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
The model cache lives at `~/.cache/skillmux/models`. If you skip
|
|
161
|
+
`models download`, Skillmux downloads the model when local inference first
|
|
162
|
+
loads it.
|
|
163
|
+
|
|
164
|
+
Start the stdio server:
|
|
165
|
+
|
|
166
|
+
```sh
|
|
167
|
+
skillmux serve
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Register it with your MCP client:
|
|
171
|
+
|
|
172
|
+
```json
|
|
173
|
+
{
|
|
174
|
+
"mcpServers": {
|
|
175
|
+
"skillmux": {
|
|
176
|
+
"command": "skillmux",
|
|
177
|
+
"args": ["serve"]
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
The client launches the process and closes it with the MCP session. Continue
|
|
184
|
+
with [MCP routing](mcp-routing.md) for client behavior and retrieval outcomes.
|
|
185
|
+
|
|
186
|
+
## Run a shared MCP service
|
|
187
|
+
|
|
188
|
+
Use the full image when you want local embeddings without configuring an
|
|
189
|
+
external inference endpoint:
|
|
190
|
+
|
|
191
|
+
```sh
|
|
192
|
+
docker run -d \
|
|
193
|
+
--name skillmux \
|
|
194
|
+
-v ~/skills:/vault:ro \
|
|
195
|
+
-v skillmux-data:/data \
|
|
196
|
+
-p 3000:3000 \
|
|
197
|
+
ghcr.io/klhq/skillmux:latest
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
The full image includes GTE-small and is the shared-service default. The slim
|
|
201
|
+
image is an advanced option for configured remote embeddings or intentional
|
|
202
|
+
lexical-only retrieval; it contains no model files. Neither image includes a
|
|
203
|
+
local reranker. Configure remote embeddings on slim when you need hybrid
|
|
204
|
+
retrieval. Docker Hub publishes the same tags under `docker.io/klhq/skillmux`.
|
|
205
|
+
|
|
206
|
+
Check the service:
|
|
207
|
+
|
|
208
|
+
```sh
|
|
209
|
+
curl http://127.0.0.1:3000/health/ready
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Register `http://127.0.0.1:3000/mcp` as a Streamable HTTP MCP endpoint. Enable
|
|
213
|
+
authentication before exposing the service beyond a trusted host. Continue
|
|
214
|
+
with [Deployment](deployment.md) for remote inference, network policy,
|
|
215
|
+
monitoring, and backups.
|
|
216
|
+
|
|
217
|
+
Manage the mounted vault on the host. A retrieval-only container should mount
|
|
218
|
+
it read-only.
|
|
219
|
+
|
|
220
|
+
## Combine native pins with shared retrieval
|
|
221
|
+
|
|
222
|
+
Use this topology when users need native core or project pins and also one
|
|
223
|
+
shared MCP endpoint. Keep one Git-backed vault as the source of truth:
|
|
224
|
+
|
|
225
|
+
- each machine that owns client skill directories keeps its own checkout and
|
|
226
|
+
runs the Skillmux CLI for `init`, pinning, and `sync`;
|
|
227
|
+
- the shared server mounts its own checkout and serves routed retrieval over
|
|
228
|
+
HTTP;
|
|
229
|
+
- MCP-only clients connect to the shared server and do not need the CLI.
|
|
230
|
+
|
|
231
|
+
Skillmux does not pull, push, replicate, or make those checkouts fresh. Git
|
|
232
|
+
and your deployment process own vault replication and freshness.
|
|
233
|
+
|
|
234
|
+
## Next steps
|
|
235
|
+
|
|
236
|
+
- [Concepts](concepts.md) explains delivery, deployment, and inference terms.
|
|
237
|
+
- [Configuration](configuration.md) documents local and remote inference.
|
|
238
|
+
- [Troubleshooting](troubleshooting.md) lists common `doctor`, model, and
|
|
239
|
+
transport failures.
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# MCP routing
|
|
2
|
+
|
|
3
|
+
Skillmux exposes one vault through two Model Context Protocol tools. Choose a
|
|
4
|
+
transport based on where the process runs:
|
|
5
|
+
|
|
6
|
+
| Topology | Transport | Typical package |
|
|
7
|
+
| --- | --- | --- |
|
|
8
|
+
| Skillmux beside one client | stdio | Skillmux CLI |
|
|
9
|
+
| Shared Skillmux service | Streamable HTTP | Full Docker image by default; slim for remote or lexical retrieval |
|
|
10
|
+
|
|
11
|
+
Both transports expose the same `resolve_skill` and `fetch_skill` contract.
|
|
12
|
+
Local native pinning is optional and can run beside stdio MCP.
|
|
13
|
+
|
|
14
|
+
## Register a stdio server
|
|
15
|
+
|
|
16
|
+
Start the server:
|
|
17
|
+
|
|
18
|
+
```sh
|
|
19
|
+
skillmux index
|
|
20
|
+
skillmux doctor
|
|
21
|
+
skillmux serve
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Register the command in your MCP client:
|
|
25
|
+
|
|
26
|
+
```json
|
|
27
|
+
{
|
|
28
|
+
"mcpServers": {
|
|
29
|
+
"skillmux": {
|
|
30
|
+
"command": "skillmux",
|
|
31
|
+
"args": ["serve"]
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The default transport is stdio. The process exits when the client closes its
|
|
38
|
+
input stream or sends a termination signal.
|
|
39
|
+
|
|
40
|
+
## Connect to a shared HTTP service
|
|
41
|
+
|
|
42
|
+
Start a Streamable HTTP server:
|
|
43
|
+
|
|
44
|
+
```sh
|
|
45
|
+
skillmux serve --transport http --port 3000
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Clients send MCP requests to:
|
|
49
|
+
|
|
50
|
+
```text
|
|
51
|
+
http://127.0.0.1:3000/mcp
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
The default host accepts loopback connections only. Configure authentication
|
|
55
|
+
and network exposure before serving other machines. See
|
|
56
|
+
[Deployment](deployment.md#expose-http-safely).
|
|
57
|
+
|
|
58
|
+
## Tool contract
|
|
59
|
+
|
|
60
|
+
### `resolve_skill`
|
|
61
|
+
|
|
62
|
+
Input:
|
|
63
|
+
|
|
64
|
+
```json
|
|
65
|
+
{
|
|
66
|
+
"query": "convert this spreadsheet to a Markdown table"
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Skillmux returns one outcome:
|
|
71
|
+
|
|
72
|
+
- `matched`: `structuredContent` contains match metadata and the text content
|
|
73
|
+
contains the `SKILL.md` body once;
|
|
74
|
+
- `ambiguous`: `structuredContent` contains up to `candidate_limit` candidates;
|
|
75
|
+
- `no_match`: the agent continues with its normal workflow.
|
|
76
|
+
|
|
77
|
+
### `fetch_skill`
|
|
78
|
+
|
|
79
|
+
Input:
|
|
80
|
+
|
|
81
|
+
```json
|
|
82
|
+
{
|
|
83
|
+
"skill_id": "csv-formatter"
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
The response contains the current `SKILL.md` body as text content.
|
|
88
|
+
`structuredContent` contains the skill ID, title, content SHA-256, and
|
|
89
|
+
supporting-file paths. Fetch does not depend on an earlier resolve call.
|
|
90
|
+
|
|
91
|
+
The complete wire contract lives in [schema.json](schema.json).
|
|
92
|
+
|
|
93
|
+
## Recommended agent behavior
|
|
94
|
+
|
|
95
|
+
Give the calling client these rules:
|
|
96
|
+
|
|
97
|
+
1. Call `resolve_skill` when a task may benefit from a specialized workflow.
|
|
98
|
+
2. Follow the delivered skill on `matched`.
|
|
99
|
+
3. On `ambiguous`, choose the best candidate and call `fetch_skill`.
|
|
100
|
+
4. On `no_match`, continue without loading a skill.
|
|
101
|
+
|
|
102
|
+
Do not treat the first ambiguous candidate as an automatic match. Skillmux
|
|
103
|
+
uses ambiguity to keep the final choice with the calling model when it lacks
|
|
104
|
+
enough confidence.
|
|
105
|
+
|
|
106
|
+
## Retrieval pipeline
|
|
107
|
+
|
|
108
|
+
Skillmux builds candidates in stages:
|
|
109
|
+
|
|
110
|
+
1. SQLite FTS5 ranks lexical matches with BM25.
|
|
111
|
+
2. Local or remote embeddings rank semantic similarity.
|
|
112
|
+
3. Reciprocal-rank fusion combines both lists.
|
|
113
|
+
4. An optional reranker scores the fused candidates.
|
|
114
|
+
5. Calibrated thresholds select `matched`, `ambiguous`, or `no_match`.
|
|
115
|
+
|
|
116
|
+
The default local inference configuration uses FTS5 and quantized
|
|
117
|
+
`Xenova/gte-small` embeddings. Skillmux CLI installations cache the
|
|
118
|
+
downloaded model under `~/.cache/skillmux/models`; the full Docker image
|
|
119
|
+
includes it. The slim image starts with lexical retrieval and can call an
|
|
120
|
+
OpenAI-compatible embedding endpoint.
|
|
121
|
+
|
|
122
|
+
Remote inference also supports `jina-v1` or `bifrost-v1` reranker adapters.
|
|
123
|
+
|
|
124
|
+
Without a reranker, Skillmux returns a shortlist and does not auto-match.
|
|
125
|
+
Without calibrated thresholds, a configured reranker orders the shortlist but
|
|
126
|
+
still does not auto-match.
|
|
127
|
+
|
|
128
|
+
Read [Configuration](configuration.md#local-inference) for local and remote
|
|
129
|
+
inference settings. Read [Policy calibration](calibration.md) before enabling
|
|
130
|
+
automatic matches.
|
|
131
|
+
|
|
132
|
+
## Fallback and readiness
|
|
133
|
+
|
|
134
|
+
Skillmux advertises the capability it can support:
|
|
135
|
+
|
|
136
|
+
- embedding failure falls back to lexical retrieval;
|
|
137
|
+
- reranker failure preserves the hybrid shortlist;
|
|
138
|
+
- vault or index failure marks the server unready.
|
|
139
|
+
|
|
140
|
+
Check the active mode:
|
|
141
|
+
|
|
142
|
+
```sh
|
|
143
|
+
skillmux doctor
|
|
144
|
+
curl http://127.0.0.1:3000/health/ready
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
A ready server reports `lexical`, `hybrid`, or `reranked` along with skill and
|
|
148
|
+
index status.
|
|
149
|
+
|
|
150
|
+
## Content integrity
|
|
151
|
+
|
|
152
|
+
The index stores metadata and retrieval state. Delivery reads the file from
|
|
153
|
+
disk, computes its SHA-256, and returns those current bytes. If indexed
|
|
154
|
+
metadata has gone stale, Skillmux refreshes it before delivery.
|
|
155
|
+
|
|
156
|
+
Supporting files remain in the vault. `fetch_skill` lists their relative paths
|
|
157
|
+
so the calling workflow can locate them through its configured filesystem
|
|
158
|
+
access.
|
|
159
|
+
|
|
160
|
+
## Audit data
|
|
161
|
+
|
|
162
|
+
Each resolve request records:
|
|
163
|
+
|
|
164
|
+
- timestamp and query;
|
|
165
|
+
- retrieval capability and outcome;
|
|
166
|
+
- candidates with scores;
|
|
167
|
+
- selected skill ID, when present;
|
|
168
|
+
- latency.
|
|
169
|
+
|
|
170
|
+
Skillmux stores audit rows in the SQLite database under `state_dir`. Use
|
|
171
|
+
`skillmux report` to summarize activity. Treat raw queries as private user
|
|
172
|
+
data when backing up or sharing the database.
|
package/docs/releasing.md
CHANGED
|
@@ -39,9 +39,10 @@ The release workflow publishes:
|
|
|
39
39
|
- `skillmux-linux-arm64`
|
|
40
40
|
- GitHub build provenance attestations when the repository is public
|
|
41
41
|
- Full image to GHCR and Docker Hub: `:<version>`, `:<major>.<minor>`,
|
|
42
|
-
and `:latest
|
|
42
|
+
and `:latest`; this variant includes GTE-small
|
|
43
43
|
- Slim image to GHCR and Docker Hub: `:<version>-slim`,
|
|
44
|
-
`:<major>.<minor>-slim`, and `:latest-slim
|
|
44
|
+
`:<major>.<minor>-slim`, and `:latest-slim`; this variant contains no model
|
|
45
|
+
files and uses remote embeddings or lexical fallback
|
|
45
46
|
- Multi-architecture `linux/amd64` and `linux/arm64` images with SBOM and
|
|
46
47
|
provenance
|
|
47
48
|
|
|
@@ -86,7 +87,7 @@ Verify the container with a read-only vault mount:
|
|
|
86
87
|
|
|
87
88
|
```bash
|
|
88
89
|
docker run --rm \
|
|
89
|
-
-v
|
|
90
|
+
-v ~/skills:/vault:ro \
|
|
90
91
|
-p 3000:3000 \
|
|
91
92
|
ghcr.io/klhq/skillmux:latest
|
|
92
93
|
|