@pascalcouturier/skill-builder-mcp 2.1.0 → 2.2.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 +31 -0
- package/README.md +68 -62
- package/SECURITY.md +11 -11
- package/dist/cli.js +78 -19
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,37 @@ The install line names the major version (`@2`), so restarting your AI tool or i
|
|
|
9
9
|
fetches the newest release of that major (see **Updating** in the
|
|
10
10
|
[README](./README.md#updating)).
|
|
11
11
|
|
|
12
|
+
## 2.2.0
|
|
13
|
+
|
|
14
|
+
Project instructions (AGENTS.md and CLAUDE.md).
|
|
15
|
+
|
|
16
|
+
- **New tool `write_project_instructions`**: creates or updates the `AGENTS.md` (with a
|
|
17
|
+
`CLAUDE.md` that imports it) of the project open in Skill Builder, from what the AI found in
|
|
18
|
+
your repository. Sections it is not given, and sections of your existing `AGENTS.md` and
|
|
19
|
+
`CLAUDE.md` it does not write, are kept. Only skills and agents you share are listed; the
|
|
20
|
+
result names the others.
|
|
21
|
+
- **New slash command `/init-agents-md`** (sent by Skill Builder once connected): like `/init`,
|
|
22
|
+
the AI reads the repository and calls `write_project_instructions`.
|
|
23
|
+
- `list_block_types` takes `mode: 'instructions'` for the AGENTS.md blocks, and `apply_fix`
|
|
24
|
+
accepts the new `list-items` fix.
|
|
25
|
+
- No protocol change, so every 1.x and 2.x release keeps working with the current site (the
|
|
26
|
+
tab sends its tools and slash commands when it connects).
|
|
27
|
+
- No new permissions: the connector still reads no files and no environment variables beyond
|
|
28
|
+
the allowlist, and makes no outbound connections.
|
|
29
|
+
|
|
30
|
+
## 2.1.1
|
|
31
|
+
|
|
32
|
+
Hardening.
|
|
33
|
+
|
|
34
|
+
- **At most four connections are held open at once.** A local program can fake the `Origin`
|
|
35
|
+
header and open sockets, so the connector now refuses new ones (HTTP 503) while four are
|
|
36
|
+
open. One Skill Builder tab needs one; the rest cover a reload or stale tabs. A turned-away
|
|
37
|
+
socket that stays silent is closed after 10 seconds, so idle ones can not block the real tab. Programs still
|
|
38
|
+
can not pair without the code only you see.
|
|
39
|
+
- No protocol change, so every 1.x and 2.x release keeps working with the current site.
|
|
40
|
+
- No new permissions: the connector still reads no files and no environment variables beyond
|
|
41
|
+
the allowlist, and makes no outbound connections.
|
|
42
|
+
|
|
12
43
|
## 2.1.0
|
|
13
44
|
|
|
14
45
|
Easier updates.
|
package/README.md
CHANGED
|
@@ -179,6 +179,11 @@ The connector offers MCP prompts, which AI tools show as slash commands:
|
|
|
179
179
|
- **`review-skill`** (always): the AI checks a skill or agent with Skill Builder's rules
|
|
180
180
|
(`check_files` for files in your repository, `validate` in Skill Builder), fixes the
|
|
181
181
|
problems, improves it following best practice and summarises what it changed.
|
|
182
|
+
- **`init-agents-md`** (when Skill Builder is connected): like `/init`, the AI reads your
|
|
183
|
+
repository (commands, structure, conventions, installed skills and agents) and creates or
|
|
184
|
+
updates `AGENTS.md`, with a `CLAUDE.md` that imports it, in the project open in Skill
|
|
185
|
+
Builder. Sections you wrote are kept, and the skills and agents you share are listed with a
|
|
186
|
+
note to load them with `use_skill` when they are not installed.
|
|
182
187
|
- **One per skill or agent you share** from the project open in Skill Builder (switch on
|
|
183
188
|
**Available to AI tools** in its details), e.g. `skill-code-review`. The AI uses it straight
|
|
184
189
|
from Skill Builder, without installing it in your repository. The first use in each
|
|
@@ -195,68 +200,69 @@ The AI can do what you can do in the app, except anything to do with the cloud (
|
|
|
195
200
|
sync, the AI check, the community library). Tools marked **asks** wait for your confirmation
|
|
196
201
|
in Skill Builder.
|
|
197
202
|
|
|
198
|
-
| Tool
|
|
199
|
-
|
|
|
200
|
-
| `get_status`
|
|
201
|
-
| `list_sessions`
|
|
202
|
-
| `get_session`
|
|
203
|
-
| `get_document`
|
|
204
|
-
| `read_file`
|
|
205
|
-
| `list_block_types`
|
|
206
|
-
| `list_templates`
|
|
207
|
-
| `list_library`
|
|
208
|
-
| `get_library_item`
|
|
209
|
-
| `validate`
|
|
210
|
-
| `check_files`
|
|
211
|
-
| `use_skill`
|
|
212
|
-
| `preview_export`
|
|
213
|
-
| `list_versions`
|
|
214
|
-
| `diff_versions`
|
|
215
|
-
| `get_canvas`
|
|
216
|
-
| `create_session`
|
|
217
|
-
| `open_session`
|
|
218
|
-
| `update_session`
|
|
219
|
-
| `duplicate_session`
|
|
220
|
-
| `set_favourite`
|
|
221
|
-
| `delete_session`
|
|
222
|
-
| `add_document`
|
|
223
|
-
| `update_document`
|
|
224
|
-
| `duplicate_document`
|
|
225
|
-
| `remove_document`
|
|
226
|
-
| `
|
|
227
|
-
| `
|
|
228
|
-
| `
|
|
229
|
-
| `
|
|
230
|
-
| `
|
|
231
|
-
| `
|
|
232
|
-
| `
|
|
233
|
-
| `
|
|
234
|
-
| `
|
|
235
|
-
| `
|
|
236
|
-
| `
|
|
237
|
-
| `
|
|
238
|
-
| `
|
|
239
|
-
| `
|
|
240
|
-
| `
|
|
241
|
-
| `
|
|
242
|
-
| `
|
|
243
|
-
| `
|
|
244
|
-
| `
|
|
245
|
-
| `
|
|
246
|
-
| `
|
|
247
|
-
| `
|
|
248
|
-
| `
|
|
249
|
-
| `
|
|
250
|
-
| `
|
|
251
|
-
| `
|
|
252
|
-
| `
|
|
253
|
-
| `
|
|
254
|
-
| `
|
|
255
|
-
| `
|
|
256
|
-
| `
|
|
257
|
-
| `
|
|
258
|
-
| `
|
|
259
|
-
| `
|
|
203
|
+
| Tool | What it does | Asks |
|
|
204
|
+
| ---------------------------- | --------------------------------------------------------------------------------- | ------------- |
|
|
205
|
+
| `get_status` | What is open: project, skill or agent, file, unsaved changes | |
|
|
206
|
+
| `list_sessions` | Search, filter, sort and page projects | |
|
|
207
|
+
| `get_session` | A project's skills and agents, files and links | |
|
|
208
|
+
| `get_document` | A skill or agent with every block (uids, types, values) | |
|
|
209
|
+
| `read_file` | The markdown a file produces, or a script's text | |
|
|
210
|
+
| `list_block_types` | Block types and their fields | |
|
|
211
|
+
| `list_templates` | Templates for new skills and agents | |
|
|
212
|
+
| `list_library` | Built-in skills and your library items | |
|
|
213
|
+
| `get_library_item` | One library item with its files, scan result and versions | |
|
|
214
|
+
| `validate` | The checks (errors, warnings, info), with one-click fixes | |
|
|
215
|
+
| `check_files` | Check skill or agent files you send (spec, security, syntax); stores nothing | |
|
|
216
|
+
| `use_skill` | Use a skill or agent the person shared from the open project | first use |
|
|
217
|
+
| `preview_export` | The files the zip would contain (ready for a project, or plain folders) | |
|
|
218
|
+
| `list_versions` | Saved versions | |
|
|
219
|
+
| `diff_versions` | Line changes between versions or against the working copy | |
|
|
220
|
+
| `get_canvas` | The canvas graph | |
|
|
221
|
+
| `create_session` | New project | |
|
|
222
|
+
| `open_session` | Show a project, skill or agent, or file in the app | |
|
|
223
|
+
| `update_session` | Rename, change author or description | |
|
|
224
|
+
| `duplicate_session` | Copy a project | |
|
|
225
|
+
| `set_favourite` | Star or unstar | |
|
|
226
|
+
| `delete_session` | Delete a project and its versions | asks |
|
|
227
|
+
| `add_document` | Add a skill or agent, optionally from a template | |
|
|
228
|
+
| `update_document` | Set name, description, licence, allowed tools, model… | |
|
|
229
|
+
| `duplicate_document` | Copy a skill or agent | |
|
|
230
|
+
| `remove_document` | Delete a skill or agent | asks |
|
|
231
|
+
| `write_project_instructions` | Create or update AGENTS.md and CLAUDE.md from your repository (`/init-agents-md`) | |
|
|
232
|
+
| `add_block` | Add a block with values at a position | |
|
|
233
|
+
| `update_block` | Change block values, collapse or expand | |
|
|
234
|
+
| `move_block` | Up, down, or to another file | |
|
|
235
|
+
| `duplicate_block` | Copy a block | |
|
|
236
|
+
| `remove_block` | Remove a block | |
|
|
237
|
+
| `convert_block` | Turn a block into Custom markdown | |
|
|
238
|
+
| `break_down_block` | Split Custom markdown into built-in blocks | |
|
|
239
|
+
| `extract_block_to_file` | Move a long block into a new reference file | |
|
|
240
|
+
| `add_file` | Add a reference, script or asset, optionally in a folder | |
|
|
241
|
+
| `write_code_file` | Write a script or data file (scanned, never run) | |
|
|
242
|
+
| `add_files` | Add several supporting files by path (scanned like uploads) | |
|
|
243
|
+
| `move_file` | Move a file to another folder of its skill (`scripts/test`) | |
|
|
244
|
+
| `rename_file` | Rename a reference | |
|
|
245
|
+
| `remove_file` | Delete a file | asks |
|
|
246
|
+
| `connect` | Link an agent to a skill, or point a reference or Resource link block | |
|
|
247
|
+
| `disconnect` | Remove such a link | |
|
|
248
|
+
| `add_from_library` | Add a library skill or agent to the project | |
|
|
249
|
+
| `apply_fix` | Apply a fix from `validate` | |
|
|
250
|
+
| `save_version` | Save a version (bump suggested from the changes) | |
|
|
251
|
+
| `restore_version` | Replace the working copy with a version | asks |
|
|
252
|
+
| `download_export` | Download the zip in the browser, for the AI tools you choose | |
|
|
253
|
+
| `download_backup` | Download a backup in the browser | |
|
|
254
|
+
| `tidy_canvas` | Tidy the canvas layout | |
|
|
255
|
+
| `undo_ai_changes` | Same as **Undo AI changes** | if you edited |
|
|
256
|
+
| `save_block_type` | Create or edit a custom block type | |
|
|
257
|
+
| `delete_block_type` | Delete a custom block type | asks |
|
|
258
|
+
| `add_library_item` | Add your own skill or agent to the library from markdown | if warnings |
|
|
259
|
+
| `update_library_item` | Edit a library item (saved as a new version) | |
|
|
260
|
+
| `restore_library_version` | Bring back an older version of a library item | |
|
|
261
|
+
| `copy_builtin_to_library` | Make an editable copy of a built-in skill | |
|
|
262
|
+
| `set_library_hidden` | Hide or show a built-in skill | |
|
|
263
|
+
| `remove_library_item` | Delete a library item | asks |
|
|
264
|
+
| `import_from_github` | List and import skills and agents from a public GitHub repo | if warnings |
|
|
265
|
+
| `set_preferences` | Default author, Blocks or Canvas view, block matching on import | |
|
|
260
266
|
|
|
261
267
|
Edits carry the project's revision. If you changed the project since the AI last read it,
|
|
262
268
|
the edit is refused and the AI reads it again, so it never overwrites your work by accident.
|
package/SECURITY.md
CHANGED
|
@@ -32,13 +32,13 @@ name, program start, file write or runtime code generation.
|
|
|
32
32
|
|
|
33
33
|
## Who can talk to it
|
|
34
34
|
|
|
35
|
-
| Who | What happens
|
|
36
|
-
| --------------------------------------------------------- |
|
|
37
|
-
| Another website in your browser | Refused: only `https://skill-builder.pascalcouturier.com` is accepted (exact match; `--dev` adds `http://localhost:5173` and `:4173`), and the `Host` header must be `127.0.0.1:<port>` or `localhost:<port>`, which stops DNS-rebinding attacks.
|
|
38
|
-
| Other devices on your network | Can not connect: it only listens on 127.0.0.1.
|
|
39
|
-
| A program on your computer pretending to be Skill Builder | Can connect (programs can fake the `Origin` header), but can not pair: the connector makes a random 60-bit pairing code and shows it only to you, through your AI tool and its log. The tab must prove it knows the code (HMAC bound to this connection's ECDH key). Three wrong codes close the connection; ten in one run turn pairing off until the AI tool restarts. Until paired, it receives nothing and can send nothing to your AI tool. |
|
|
40
|
-
| A program pretending to be this connector | Can not pair with Skill Builder: after you type the code, Skill Builder also asks the connector to prove it knows it. Only the connector that showed the code in your AI tool can, so an imitation is refused and the user is told. The code itself never crosses the connection.
|
|
41
|
-
| Your approved Skill Builder tab | Can answer the tool calls your AI tool makes. Every message is signed (HMAC-SHA256) and numbered, so it can not be forged, replayed or reordered. Messages are limited to 1 MB.
|
|
35
|
+
| Who | What happens |
|
|
36
|
+
| --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
37
|
+
| Another website in your browser | Refused: only `https://skill-builder.pascalcouturier.com` is accepted (exact match; `--dev` adds `http://localhost:5173` and `:4173`), and the `Host` header must be `127.0.0.1:<port>` or `localhost:<port>`, which stops DNS-rebinding attacks. |
|
|
38
|
+
| Other devices on your network | Can not connect: it only listens on 127.0.0.1. |
|
|
39
|
+
| A program on your computer pretending to be Skill Builder | Can connect (programs can fake the `Origin` header), but can not pair: the connector makes a random 60-bit pairing code and shows it only to you, through your AI tool and its log. The tab must prove it knows the code (HMAC bound to this connection's ECDH key). At most four connections are held open at once, and a refused socket that stays silent is closed after 10 seconds. Three wrong codes close the connection; ten in one run turn pairing off until the AI tool restarts. Until paired, it receives nothing and can send nothing to your AI tool. |
|
|
40
|
+
| A program pretending to be this connector | Can not pair with Skill Builder: after you type the code, Skill Builder also asks the connector to prove it knows it. Only the connector that showed the code in your AI tool can, so an imitation is refused and the user is told. The code itself never crosses the connection. |
|
|
41
|
+
| Your approved Skill Builder tab | Can answer the tool calls your AI tool makes. Every message is signed (HMAC-SHA256) and numbered, so it can not be forged, replayed or reordered. Messages are limited to 1 MB. |
|
|
42
42
|
|
|
43
43
|
## Data and privacy
|
|
44
44
|
|
|
@@ -122,9 +122,9 @@ commands, edit files). Treat any tool's output as untrusted, including this one'
|
|
|
122
122
|
|
|
123
123
|
```bash
|
|
124
124
|
# What it contains, and its checksum
|
|
125
|
-
npm pack @pascalcouturier/skill-builder-mcp@2.
|
|
126
|
-
tar -tzf pascalcouturier-skill-builder-mcp-2.
|
|
127
|
-
npm view @pascalcouturier/skill-builder-mcp@2.
|
|
125
|
+
npm pack @pascalcouturier/skill-builder-mcp@2.2.0
|
|
126
|
+
tar -tzf pascalcouturier-skill-builder-mcp-2.2.0.tgz
|
|
127
|
+
npm view @pascalcouturier/skill-builder-mcp@2.2.0 dist.integrity
|
|
128
128
|
|
|
129
129
|
# That the registry signed it (in a project that installs it)
|
|
130
130
|
npm audit signatures
|
|
@@ -146,7 +146,7 @@ the approved GitHub Actions workflow (no npm token exists).
|
|
|
146
146
|
|
|
147
147
|
This means a release reaches you without you reviewing it first. If you want to review each one
|
|
148
148
|
(for example in a company), put an exact version after the `@` in your AI tool's settings, such as
|
|
149
|
-
`@2.
|
|
149
|
+
`@2.2.0`, and update it yourself; Skill Builder still shows when your connector is out of date.
|
|
150
150
|
Use the commands above to look at any release before you run it.
|
|
151
151
|
|
|
152
152
|
## Reporting a problem
|
package/dist/cli.js
CHANGED
|
@@ -7845,7 +7845,7 @@ var StdioServerTransport = class {
|
|
|
7845
7845
|
};
|
|
7846
7846
|
var package_default = {
|
|
7847
7847
|
name: "@pascalcouturier/skill-builder-mcp",
|
|
7848
|
-
version: "2.
|
|
7848
|
+
version: "2.2.0",
|
|
7849
7849
|
description: "Connect AI tools (GitHub Copilot, Claude Code, Codex, Cursor, Claude Desktop) to Skill Builder open in your browser, over MCP.",
|
|
7850
7850
|
license: "MIT",
|
|
7851
7851
|
author: "Pascal Couturier (https://pascalcouturier.com)",
|
|
@@ -11556,6 +11556,8 @@ var BRIDGE_LIMITS = {
|
|
|
11556
11556
|
pairingAttempts: 3,
|
|
11557
11557
|
/** Wrong pairing codes allowed per connector run; then it stops pairing until restarted. */
|
|
11558
11558
|
pairingFailuresPerRun: 10,
|
|
11559
|
+
/** Sockets the connector keeps open at once. One tab is expected; the rest cover stale tabs. */
|
|
11560
|
+
maxConnections: 4,
|
|
11559
11561
|
/** Calls per minute the tab accepts from one AI tool. */
|
|
11560
11562
|
callsPerMinute: 120
|
|
11561
11563
|
};
|
|
@@ -11779,6 +11781,12 @@ var id = string().min(1).max(INPUT_LIMITS.id);
|
|
|
11779
11781
|
var name = string().trim().min(1).max(INPUT_LIMITS.name);
|
|
11780
11782
|
var text = string().max(INPUT_LIMITS.text);
|
|
11781
11783
|
var mode = _enum(["skill", "agent"]);
|
|
11784
|
+
/** Every kind of document, including the project instructions (AGENTS.md). */
|
|
11785
|
+
var documentMode = _enum([
|
|
11786
|
+
"skill",
|
|
11787
|
+
"agent",
|
|
11788
|
+
"instructions"
|
|
11789
|
+
]);
|
|
11782
11790
|
/** A block field value: text, a list of strings, or a toggle. */
|
|
11783
11791
|
var fieldValue = union([
|
|
11784
11792
|
text,
|
|
@@ -11829,6 +11837,11 @@ var issueAction = discriminatedUnion("kind", [
|
|
|
11829
11837
|
documentId: id,
|
|
11830
11838
|
from: string().max(300),
|
|
11831
11839
|
to: string().max(300)
|
|
11840
|
+
}),
|
|
11841
|
+
strictObject({
|
|
11842
|
+
kind: literal("list-items"),
|
|
11843
|
+
documentId: id,
|
|
11844
|
+
ids: array(id).max(200)
|
|
11832
11845
|
})
|
|
11833
11846
|
]);
|
|
11834
11847
|
var endpoint = strictObject({
|
|
@@ -11842,6 +11855,12 @@ var supportingFile = strictObject({
|
|
|
11842
11855
|
path: string().min(1).max(300).describe("Relative to the skill folder, e.g. \"references/api.md\" or \"scripts/run.py\"."),
|
|
11843
11856
|
content: string().max(INPUT_LIMITS.code)
|
|
11844
11857
|
});
|
|
11858
|
+
/** One section of project instructions: short lines, one per item. */
|
|
11859
|
+
var instructionList = array(string().trim().max(INPUT_LIMITS.listItem)).max(100).optional();
|
|
11860
|
+
var repoItems = array(strictObject({
|
|
11861
|
+
name: string().trim().min(1).max(INPUT_LIMITS.name),
|
|
11862
|
+
description: string().max(1024).describe("When to use it.")
|
|
11863
|
+
})).max(100).optional();
|
|
11845
11864
|
var bump = _enum([
|
|
11846
11865
|
"major",
|
|
11847
11866
|
"minor",
|
|
@@ -11936,9 +11955,9 @@ var bridgeTools = {
|
|
|
11936
11955
|
name: "list_block_types",
|
|
11937
11956
|
title: "List block types",
|
|
11938
11957
|
kind: "read",
|
|
11939
|
-
description: "Block types that can be added to a skill or
|
|
11958
|
+
description: "Block types that can be added to a skill, an agent or the project instructions (mode 'instructions', AGENTS.md), with their fields (key, type, options, required). Includes built-in, custom and library skill blocks.",
|
|
11940
11959
|
input: strictObject({
|
|
11941
|
-
mode:
|
|
11960
|
+
mode: documentMode.optional(),
|
|
11942
11961
|
category: string().max(40).optional(),
|
|
11943
11962
|
search: string().max(200).optional(),
|
|
11944
11963
|
blockIds: array(id).max(50).optional().describe("Only these block types, with full detail."),
|
|
@@ -12151,6 +12170,40 @@ var bridgeTools = {
|
|
|
12151
12170
|
documentId: id
|
|
12152
12171
|
})
|
|
12153
12172
|
}),
|
|
12173
|
+
write_project_instructions: tool({
|
|
12174
|
+
name: "write_project_instructions",
|
|
12175
|
+
title: "Create or update AGENTS.md",
|
|
12176
|
+
kind: "write",
|
|
12177
|
+
description: "Creates or updates the project's instructions (AGENTS.md, plus a CLAUDE.md that imports it) from what you found in the repository, like /init. Each section you give replaces that section; sections you leave out stay as they are. Pass the repository's current AGENTS.md and CLAUDE.md as existing: their other sections are kept. The skills and agents shared from Skill Builder are listed for you, with a note to load them with use_skill; the result names the ones that are not shared. Lists hold one item per line: short, specific and true for this repository." + SECRETS_NOTE,
|
|
12178
|
+
input: strictObject({
|
|
12179
|
+
baseRevision,
|
|
12180
|
+
sessionId: sessionRef,
|
|
12181
|
+
overview: strictObject({
|
|
12182
|
+
title: string().max(INPUT_LIMITS.name).optional(),
|
|
12183
|
+
summary: string().max(4e3).optional()
|
|
12184
|
+
}).optional().describe("The project name and two or three sentences on what it is."),
|
|
12185
|
+
stack: instructionList.describe("Languages, frameworks and main libraries."),
|
|
12186
|
+
commands: string().max(2e4).optional().describe("Shell commands to install, run, build, test and lint, one per line with a # comment."),
|
|
12187
|
+
structure: instructionList.describe("Main folders: \"`src/core`: pure logic\"."),
|
|
12188
|
+
conventions: instructionList.describe("Code style and naming conventions."),
|
|
12189
|
+
architecture: instructionList.describe("Architecture rules to respect."),
|
|
12190
|
+
testing: instructionList.describe("How tests are written and run."),
|
|
12191
|
+
git: instructionList.describe("Branches, commit messages, pull requests."),
|
|
12192
|
+
security: instructionList.describe("Secrets and data rules."),
|
|
12193
|
+
boundaries: strictObject({
|
|
12194
|
+
always: instructionList,
|
|
12195
|
+
ask: instructionList,
|
|
12196
|
+
never: instructionList
|
|
12197
|
+
}).optional().describe("What to always do, ask about first, and never do."),
|
|
12198
|
+
repo: strictObject({
|
|
12199
|
+
location: string().max(300).optional().describe("E.g. \"`.agents/skills/`\"."),
|
|
12200
|
+
skills: repoItems,
|
|
12201
|
+
agents: repoItems
|
|
12202
|
+
}).optional().describe("Skills and agents installed in the repository, from their frontmatter."),
|
|
12203
|
+
existing: array(string().max(INPUT_LIMITS.text)).max(4).optional().describe("The repository's current AGENTS.md and CLAUDE.md, as they are."),
|
|
12204
|
+
listShared: boolean().default(true).describe("List the skills and agents shared from Skill Builder, and tell AI tools to load them with use_skill.")
|
|
12205
|
+
})
|
|
12206
|
+
}),
|
|
12154
12207
|
add_block: tool({
|
|
12155
12208
|
name: "add_block",
|
|
12156
12209
|
title: "Add block",
|
|
@@ -13088,6 +13141,10 @@ var Bridge = class {
|
|
|
13088
13141
|
this.options.log?.("Refused a connection with an unexpected Host header.");
|
|
13089
13142
|
return done(false, 403, "Host not allowed");
|
|
13090
13143
|
}
|
|
13144
|
+
if (server.clients.size >= BRIDGE_LIMITS.maxConnections) {
|
|
13145
|
+
this.options.log?.("Refused a connection: too many are open.");
|
|
13146
|
+
return done(false, 503, "Too many connections");
|
|
13147
|
+
}
|
|
13091
13148
|
done(true);
|
|
13092
13149
|
}
|
|
13093
13150
|
});
|
|
@@ -13102,25 +13159,11 @@ var Bridge = class {
|
|
|
13102
13159
|
}
|
|
13103
13160
|
accept(socket) {
|
|
13104
13161
|
if (this.locked) {
|
|
13105
|
-
|
|
13106
|
-
socket.send(JSON.stringify({
|
|
13107
|
-
type: "reject",
|
|
13108
|
-
code: "locked",
|
|
13109
|
-
message: "Too many wrong pairing codes. Restart the AI tool to try again."
|
|
13110
|
-
}));
|
|
13111
|
-
socket.close(1008);
|
|
13112
|
-
});
|
|
13162
|
+
this.turnAway(socket, "locked", "Too many wrong pairing codes. Restart the AI tool to try again.");
|
|
13113
13163
|
return;
|
|
13114
13164
|
}
|
|
13115
13165
|
if (this.link?.state === "paired") {
|
|
13116
|
-
|
|
13117
|
-
socket.send(JSON.stringify({
|
|
13118
|
-
type: "reject",
|
|
13119
|
-
code: "busy",
|
|
13120
|
-
message: "Another Skill Builder tab is already connected to this AI tool."
|
|
13121
|
-
}));
|
|
13122
|
-
socket.close(1008);
|
|
13123
|
-
});
|
|
13166
|
+
this.turnAway(socket, "busy", "Another Skill Builder tab is already connected to this AI tool.");
|
|
13124
13167
|
return;
|
|
13125
13168
|
}
|
|
13126
13169
|
this.link?.close(1e3);
|
|
@@ -13147,6 +13190,22 @@ var Bridge = class {
|
|
|
13147
13190
|
});
|
|
13148
13191
|
this.link = link;
|
|
13149
13192
|
}
|
|
13193
|
+
/**
|
|
13194
|
+
* Answers a socket's first message with a refusal and closes it. A socket that stays silent is
|
|
13195
|
+
* closed too, so idle ones can not use up the connection limit and block the real tab.
|
|
13196
|
+
*/
|
|
13197
|
+
turnAway(socket, code, message) {
|
|
13198
|
+
const timer = setTimeout(() => socket.close(1008), this.options.idleTimeoutMs ?? BRIDGE_LIMITS.handshakeTimeoutMs);
|
|
13199
|
+
socket.once("close", () => clearTimeout(timer));
|
|
13200
|
+
socket.once("message", () => {
|
|
13201
|
+
socket.send(JSON.stringify({
|
|
13202
|
+
type: "reject",
|
|
13203
|
+
code,
|
|
13204
|
+
message
|
|
13205
|
+
}));
|
|
13206
|
+
socket.close(1008);
|
|
13207
|
+
});
|
|
13208
|
+
}
|
|
13150
13209
|
setManifest(tools) {
|
|
13151
13210
|
const changed = JSON.stringify(tools) !== JSON.stringify(this.manifest);
|
|
13152
13211
|
this.manifest = tools;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pascalcouturier/skill-builder-mcp",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "Connect AI tools (GitHub Copilot, Claude Code, Codex, Cursor, Claude Desktop) to Skill Builder open in your browser, over MCP.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Pascal Couturier (https://pascalcouturier.com)",
|