airlok 0.6.0 → 0.7.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 +23 -0
- package/README.md +74 -25
- package/npm-shrinkwrap.json +2 -2
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to airlok. The format follows Keep a Changelog; versions follow SemVer.
|
|
4
4
|
|
|
5
|
+
## [0.7.0] - 2026-09-12
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- Tools from an MCP server are now named `mcp__<server>__<tool>`, the convention the other clients use, in place of `<server>__<tool>`. This is a breaking change for anything that referred to the old names: a saved session's history, a note in AIRLOK.md, or a `tools = [...]` list naming a tool keeps working, since that list names the server's own tool rather than the prefixed one.
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- MCP servers are configured with the `mcpServers` JSON that Claude Code, Cursor, and VS Code share, so a `.mcp.json` copied from another project works unchanged. Both forms are read: `command`/`args`/`env` for stdio, and `type`/`url`/`headers` for http. Unknown keys other tools write are ignored rather than refused.
|
|
14
|
+
- Three scopes, each winning over the one above it: `~/.config/airlok/mcp.json`, `./.mcp.json` meant to be committed, and `./.airlok/mcp.json` for personal overrides. A server named in more than one takes the highest definition whole. `[[mcp]]` TOML blocks keep working, merge with the JSON, and win a name clash.
|
|
15
|
+
- Airlok's own options live under an `airlok` key inside a JSON entry, so a plain config stays plain.
|
|
16
|
+
- `${VAR}` and `${VAR:-default}` expand from the environment in `command`, `args`, `env`, `url`, and `headers`. Unset or empty with no default is an error naming the variable. `env_cmd` and `header_cmd` remain the better way to hold a secret.
|
|
17
|
+
- `airlok mcp add`, `remove`, `get`, `import`, and `export` manage those files, and `airlok mcp list` now shows which scope each server came from.
|
|
18
|
+
- An approval can outlive the run: `s` at an MCP confirmation remembers that server, that tool, and the places that call named, in `.airlok/mcp-trust.json`, written 0600 and gitignored. It never covers a place outside the ones approved, and it records what the server was, so changing its command or url asks again. `airlok mcp trust list` and `trust revoke <server>` manage it.
|
|
19
|
+
|
|
20
|
+
## [0.6.1] - 2026-09-12
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- Approving an MCP call with `a` covered the whole server for the rest of the run, so a later call to the same server ran without asking, even when it reached a different place. "All" now covers one tool on one server, and only the places that call named: a call naming anything outside them asks again. Paths are resolved before they are compared, so a different spelling of the same place is still covered and `..` cannot step outside an approval.
|
|
25
|
+
- The confirmation now shows what the server can reach and the resolved place each argument names, marking one outside the current project, and `airlok mcp list` shows the same root. A call that reads outside the repository is visible before it runs rather than after.
|
|
26
|
+
- A tool call or a note printed in the middle of a streamed line split the line in two: a bullet's bold label was rendered as a finished bullet and its text as a separate block, which is what `• Overview:` and its text landing on different lines was. Only complete markdown is flushed now, so a line still arriving keeps its block.
|
|
27
|
+
|
|
5
28
|
## [0.6.0] - 2026-09-12
|
|
6
29
|
|
|
7
30
|
### Added
|
package/README.md
CHANGED
|
@@ -115,45 +115,94 @@ Tool results over 50 KiB are cut with a marker telling the model to page with `r
|
|
|
115
115
|
|
|
116
116
|
## MCP servers
|
|
117
117
|
|
|
118
|
-
airlok
|
|
118
|
+
airlok offers the model tools from external [MCP](https://modelcontextprotocol.io) servers, configured the way Claude Code, Cursor, and VS Code configure them. A `.mcp.json` copied from another project works unchanged:
|
|
119
|
+
|
|
120
|
+
```json
|
|
121
|
+
{
|
|
122
|
+
"mcpServers": {
|
|
123
|
+
"files": {
|
|
124
|
+
"command": "npx",
|
|
125
|
+
"args": ["-y", "@modelcontextprotocol/server-filesystem", "."],
|
|
126
|
+
"env": { "NODE_ENV": "production" }
|
|
127
|
+
},
|
|
128
|
+
"docs": {
|
|
129
|
+
"type": "http",
|
|
130
|
+
"url": "https://example.com/mcp",
|
|
131
|
+
"headers": { "Authorization": "Bearer ${DOCS_TOKEN}" }
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Three files are read, each winning over the one above it. A server named in more than one takes the highest definition whole, so a local file is a real override rather than a patch.
|
|
138
|
+
|
|
139
|
+
| Scope | File | For |
|
|
140
|
+
|---|---|---|
|
|
141
|
+
| user | `~/.config/airlok/mcp.json` | servers you want everywhere |
|
|
142
|
+
| project | `./.mcp.json` | the project's servers, meant to be committed |
|
|
143
|
+
| local | `./.airlok/mcp.json` | your own overrides, gitignored |
|
|
144
|
+
|
|
145
|
+
`${VAR}` and `${VAR:-default}` expand from the environment in `command`, `args`, `env`, `url`, and `headers`. A variable that is unset or empty with no default is an error naming it, rather than an empty string that fails later in a way nobody can read. For a secret, prefer `env_cmd` and `header_cmd`, which take the value from a command's stdout: nothing is written in the file, and nothing has to sit in your environment where every other process can read it.
|
|
146
|
+
|
|
147
|
+
Managing them:
|
|
148
|
+
|
|
149
|
+
| Command | What it does |
|
|
150
|
+
|---|---|
|
|
151
|
+
| `airlok mcp list` | every server, its scope, whether it answers, and its tools |
|
|
152
|
+
| `airlok mcp add <name> --scope user -- npx -y server-filesystem .` | write a stdio server; `--url` with `--transport http` for an http one |
|
|
153
|
+
| `airlok mcp get <name>` | the resolved entry and which file it came from |
|
|
154
|
+
| `airlok mcp remove <name> [--scope ...]` | take it out again |
|
|
155
|
+
| `airlok mcp import <path>` | merge another tool's `mcpServers` file into a scope |
|
|
156
|
+
| `airlok mcp export [--scope ...]` | print standard JSON, to hand to another tool |
|
|
157
|
+
| `airlok mcp call <server> <tool> '<json>'` | call one tool through the same gates, for debugging |
|
|
158
|
+
| `airlok mcp trust list` and `trust revoke <server>` | approvals remembered past a run |
|
|
159
|
+
| `/mcp` | in a session, the same list; `/mcp <name>` enables a disabled server for that session |
|
|
160
|
+
|
|
161
|
+
### airlok's own options
|
|
162
|
+
|
|
163
|
+
Everything airlok adds lives under an `airlok` key, so a plain config stays plain:
|
|
164
|
+
|
|
165
|
+
```json
|
|
166
|
+
{
|
|
167
|
+
"mcpServers": {
|
|
168
|
+
"docs": {
|
|
169
|
+
"type": "http",
|
|
170
|
+
"url": "https://example.com/mcp",
|
|
171
|
+
"airlok": {
|
|
172
|
+
"trust": "prompt",
|
|
173
|
+
"rehydrate": false,
|
|
174
|
+
"tools": ["search"],
|
|
175
|
+
"header_cmd": { "Authorization": "printf 'Bearer %s' $(cat ~/.docs-token)" }
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
The same options are available as `[[mcp]]` blocks in `config.toml` or `airlok.toml`, which keep working and win a name clash with any JSON file:
|
|
119
183
|
|
|
120
184
|
```toml
|
|
121
185
|
[[mcp]]
|
|
122
|
-
name = "files"
|
|
186
|
+
name = "files"
|
|
123
187
|
command = "npx"
|
|
124
188
|
args = ["-y", "@modelcontextprotocol/server-filesystem", "."]
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
name = "docs"
|
|
130
|
-
transport = "http"
|
|
131
|
-
url = "https://example.com/mcp"
|
|
132
|
-
headers = { Accept = "application/json" }
|
|
133
|
-
header_cmd = { Authorization = "printf 'Bearer %s' $(cat ~/.docs-token)" }
|
|
134
|
-
tools = ["search"] # or "all", the default
|
|
135
|
-
trust = "prompt" # "prompt" (default), "allow", "deny"
|
|
136
|
-
rehydrate = false # the default
|
|
137
|
-
timeout_secs = 30 # starting the server, and every call
|
|
189
|
+
trust = "prompt" # "prompt" (default), "allow", "deny"
|
|
190
|
+
rehydrate = false # the default
|
|
191
|
+
tools = "all" # or a list: ["read_text_file"]
|
|
192
|
+
timeout_secs = 30
|
|
138
193
|
enabled = true
|
|
139
194
|
```
|
|
140
195
|
|
|
141
|
-
|
|
196
|
+
### What a server may and may not do
|
|
142
197
|
|
|
143
|
-
Servers start on the first turn that can use them, not when airlok starts. One that fails to start prints a line and is skipped, and the run continues without it. Tools
|
|
198
|
+
Servers start on the first turn that can use them, not when airlok starts. One that fails to start prints a line and is skipped, and the run continues without it. Tools reach the model as `mcp__<server>__<tool>`; a built-in keeps its name if a server ever claims one.
|
|
144
199
|
|
|
145
|
-
`trust` decides the gate. The default, `prompt`, shows the server, the tool, and the arguments,
|
|
200
|
+
`trust` decides the gate. The default, `prompt`, shows the server, the tool, what the server can reach, the place each argument names, and the arguments themselves, then asks with `[y]es / [n]o / [a]ll / [s]ave / [q]uit`. `a` covers that tool on that server for the rest of the run, for the places that call named and no others. `s` remembers the same approval past the run in `.airlok/mcp-trust.json`, which is gitignored and written 0600; it records what the server was, so changing its command or url makes it ask again. `allow` never asks, and `deny` keeps a server's tools from the model while `airlok mcp list` still shows them.
|
|
146
201
|
|
|
147
|
-
`rehydrate` decides what the server receives. By default airlok sends placeholders: a secret found in your files leaves as `<<SECRET_1>>` rather than as the value,
|
|
202
|
+
`rehydrate` decides what the server receives. By default airlok sends placeholders: a secret found in your files leaves as `<<SECRET_1>>` rather than as the value, and the confirmation shows you exactly what will be sent. Set `rehydrate = true` for a server that genuinely needs the value. The provider API key is refused either way.
|
|
148
203
|
|
|
149
204
|
A server is untrusted input. Its tool descriptions and its results reach the model inside markers saying they are data from that server, so a description reading "ignore previous instructions" is quoted text and nothing more. Nothing a server sends changes the deny list, the confirmations, or anything else about how airlok behaves.
|
|
150
205
|
|
|
151
|
-
| Command | What it does |
|
|
152
|
-
|---|---|
|
|
153
|
-
| `airlok mcp list` | every configured server, whether it answers, and the tools it offers |
|
|
154
|
-
| `airlok mcp call <server> <tool> '<json>'` | call one tool with the same gates, for debugging |
|
|
155
|
-
| `/mcp` | in a session, the same list; `/mcp <name>` enables a disabled server for this session |
|
|
156
|
-
|
|
157
206
|
Plan mode offers no MCP tools, just as it offers no write tools, and it starts no servers.
|
|
158
207
|
|
|
159
208
|
## Context and AIRLOK.md
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"hasInstallScript": true,
|
|
20
20
|
"license": "MIT OR Apache-2.0",
|
|
21
21
|
"name": "airlok",
|
|
22
|
-
"version": "0.
|
|
22
|
+
"version": "0.7.0"
|
|
23
23
|
},
|
|
24
24
|
"node_modules/detect-libc": {
|
|
25
25
|
"engines": {
|
|
@@ -48,5 +48,5 @@
|
|
|
48
48
|
}
|
|
49
49
|
},
|
|
50
50
|
"requires": true,
|
|
51
|
-
"version": "0.
|
|
51
|
+
"version": "0.7.0"
|
|
52
52
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"artifactDownloadUrls": [
|
|
3
|
-
"https://github.com/airlok-dev/airlok/releases/download/v0.
|
|
3
|
+
"https://github.com/airlok-dev/airlok/releases/download/v0.7.0"
|
|
4
4
|
],
|
|
5
5
|
"bin": {
|
|
6
6
|
"airlok": "run-airlok.js"
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"zipExt": ".tar.xz"
|
|
61
61
|
}
|
|
62
62
|
},
|
|
63
|
-
"version": "0.
|
|
63
|
+
"version": "0.7.0",
|
|
64
64
|
"volta": {
|
|
65
65
|
"node": "18.14.1",
|
|
66
66
|
"npm": "9.5.0"
|