@skilljack/mcp 0.6.0 → 0.7.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 CHANGED
@@ -2,30 +2,6 @@
2
2
 
3
3
  An MCP server that jacks [Agent Skills](https://agentskills.io) directly into your LLM's brain.
4
4
 
5
- > **Recommended:** For best results, use an MCP client that supports `tools/listChanged` notifications (e.g., Claude Code). This enables dynamic skill discovery - when skills are added or modified, the client automatically refreshes its understanding of available skills. Alternatively, use `--static` mode for predictable behavior with a fixed skill set.
6
-
7
- ## Features
8
-
9
- - **Dynamic Skill Discovery** - Watches skill directories and automatically refreshes when skills change
10
- - **Tool List Changed Notifications** - Sends `tools/listChanged` so clients can refresh available skills
11
- - **Skill Tool** - Load full skill content on demand (progressive disclosure)
12
- - **MCP Prompts** - Load skills via `/skill` prompt with auto-completion or per-skill prompts
13
- - **MCP Resources** - Access skills via `skill://` URIs with batch collection support
14
- - **Resource Subscriptions** - Real-time file watching with `notifications/resources/updated`
15
- - **Configuration UI** - Manage skill directories through an [interactive UI](https://blog.modelcontextprotocol.io/posts/2026-01-26-mcp-apps/) in supported clients
16
-
17
- ## Motivation
18
-
19
- This repo demonstrates a way to approach integrating skills using existing MCP primitives.
20
-
21
- MCP already has the building blocks:
22
- - **Tools** for on-demand skill loading (the `skill` tool with dynamically updated descriptions)
23
- - **Resources** for explicit skill access (`skill://` URIs)
24
- - **Notifications** for real-time updates (`tools/listChanged`, `resources/updated`)
25
- - **Prompts** for explicitly invoking skills by name (`/my-server-skill`)
26
-
27
- This approach provides separation of concerns. Rather than every MCP server needing to embed skill handling, the server acts as a dedicated 'skill gateway'. Server authors can bundle skills alongside their MCP servers without modifying the servers themselves. If MCP registries support robust tool discovery, skill tools become discoverable like any other tool.
28
-
29
5
  ## Installation
30
6
 
31
7
  ```bash
@@ -49,400 +25,35 @@ npm run build
49
25
 
50
26
  ## Usage
51
27
 
52
- Configure one or more skills directories containing your Agent Skills:
53
-
54
28
  ```bash
55
29
  # Single directory
56
30
  skilljack-mcp /path/to/skills
57
31
 
58
- # Multiple directories (separate args or comma-separated)
32
+ # Multiple directories
59
33
  skilljack-mcp /path/to/skills /path/to/more/skills
60
- skilljack-mcp /path/to/skills,/path/to/more/skills
61
34
 
62
- # Using environment variable (comma-separated for multiple)
35
+ # Using environment variable
63
36
  SKILLS_DIR=/path/to/skills skilljack-mcp
64
- SKILLS_DIR=/path/to/skills,/path/to/more/skills skilljack-mcp
65
- ```
66
37
 
67
- Each directory is scanned along with its `.claude/skills/` and `skills/` subdirectories for skills. Duplicate skill names are handled by keeping the first occurrence.
68
-
69
- ### Static Mode
70
-
71
- By default, Skilljack MCP watches skill directories for changes and notifies clients when skills are added, modified, or removed.
72
-
73
- Enable **static mode** to freeze the skills list at startup:
74
-
75
- ```bash
38
+ # Static mode (no file watching)
76
39
  skilljack-mcp --static /path/to/skills
77
- # or
78
- SKILLJACK_STATIC=true skilljack-mcp /path/to/skills
79
- ```
80
-
81
- In static mode:
82
- - Skills are discovered once at startup and never refreshed
83
- - No file watchers are set up for skill directories
84
- - `tools.listChanged` and `prompts.listChanged` capabilities are `false`
85
- - Resource subscriptions remain fully dynamic (individual skill files can still be watched)
86
-
87
- Use static mode when you need predictable behavior or have a fixed set of skills that won't change during the session.
88
-
89
- **Windows note**: Use forward slashes in paths when using with MCP Inspector:
90
- ```bash
91
- skilljack-mcp "C:/Users/you/skills"
92
40
  ```
93
41
 
94
42
  ## Configuration UI
95
43
 
96
- In MCP clients that support [MCP Apps](https://blog.modelcontextprotocol.io/posts/2026-01-26-mcp-apps/) (like Claude Desktop), you can manage skill directories through an interactive UI.
97
-
98
- **To open the configuration UI**, ask your assistant to show the skilljack config:
99
-
100
- > "show me the skilljack config"
101
-
102
- The UI displays:
103
- - Current skill directories with skill counts
104
- - Status indicators showing which directories are from config vs command-line
105
- - Options to add new directories or remove existing ones
106
-
107
44
  ![Skills Configuration UI](docs/images/skills-config-ui.png)
108
45
 
109
- Changes made through the UI are persisted to the server's configuration. Clients that support `tools/listChanged` notifications will see updates immediately; others may require reconnection.
110
-
111
46
  ## Skill Display UI
112
47
 
113
- View all available skills and customize their invocation settings through the skill display UI.
114
-
115
- **To open the skill display UI**, ask your assistant:
116
-
117
- > "what skills are configured in skilljack?"
118
-
119
- The UI displays:
120
- - All discovered skills with name, description, and file path
121
- - **Source indicators** showing whether each skill is from a local directory or GitHub repository
122
- - **Invocation toggles** to enable/disable Assistant (model auto-invoke) and User (prompts menu) visibility
123
- - **Customized badge** when settings differ from frontmatter defaults
124
-
125
48
  ![Skill Display UI](docs/images/skill-display-ui.png)
126
49
 
127
- Skills from GitHub repositories show the org/repo name (e.g., `modelcontextprotocol/ext-apps`), making it easy to identify where each skill originates.
128
-
129
- ## How It Works
130
-
131
- The server implements the [Agent Skills](https://agentskills.io) progressive disclosure pattern with dynamic updates:
132
-
133
- 1. **At startup**: Discovers skills from configured directories and starts file watchers
134
- 2. **On connection**: Skill tool description includes available skills metadata
135
- 3. **On file change**: Re-discovers skills, updates tool description, sends `tools/listChanged`
136
- 4. **On tool call**: Agent calls `skill` tool to load full SKILL.md content
137
- 5. **As needed**: Agent calls `skill-resource` to load additional files
138
-
139
- ```
140
- ┌─────────────────────────────────────────────────────────┐
141
- │ Server starts │
142
- │ • Discovers skills from configured directories │
143
- │ • Starts watching for SKILL.md changes │
144
- │ ↓ │
145
- │ MCP Client connects │
146
- │ • Skill tool description includes available skills │
147
- │ • Prompts registered for each skill │
148
- │ ↓ │
149
- │ LLM sees skill metadata in tool description │
150
- │ ↓ │
151
- │ SKILL.md added/modified/removed │
152
- │ • Server re-discovers skills │
153
- │ • Updates skill tool description │
154
- │ • Updates prompt list (add/remove/modify) │
155
- │ • Sends tools/listChanged notification │
156
- │ • Sends prompts/listChanged notification │
157
- │ • Client refreshes tool and prompt definitions │
158
- │ ↓ │
159
- │ User invokes /skill prompt or /skill-name prompt │
160
- │ OR LLM calls "skill" tool with skill name │
161
- │ ↓ │
162
- │ Server returns full SKILL.md content │
163
- │ ↓ │
164
- │ LLM calls "skill-resource" for additional files │
165
- │ • Scripts, snippets, references, assets, etc. │
166
- └─────────────────────────────────────────────────────────┘
167
- ```
168
-
169
- ## Tools vs Resources vs Prompts
170
-
171
- This server exposes skills via **tools**, **resources**, and **prompts**:
172
-
173
- - **Tools** (`skill`, `skill-resource`) - For your agent to use autonomously. The LLM sees available skills in the tool description and calls them as needed.
174
- - **Prompts** (`/skill`, `/skill-name`) - For explicit user invocation. Use `/skill` with auto-completion or select a skill directly by name.
175
- - **Resources** (`skill://` URIs) - For manual selection in apps that support it (e.g., Claude Desktop's resource picker). Useful when you want to explicitly attach a skill to the conversation.
176
-
177
- Most users will rely on tools for automatic skill activation. Prompts provide user-initiated loading with auto-completion. Resources provide an alternative for manual control.
178
-
179
- ## Progressive Disclosure Design
180
-
181
- This server implements the [Agent Skills progressive disclosure pattern](https://agentskills.io/specification#progressive-disclosure), which structures skills for efficient context usage:
182
-
183
- | Level | Tokens | What's loaded | When |
184
- |-------|--------|---------------|------|
185
- | **Metadata** | ~100 | `name` and `description` | At startup, for all skills |
186
- | **Instructions** | < 5000 | Full SKILL.md body | When skill is activated |
187
- | **Resources** | As needed | Files in `scripts/`, `references/`, `assets/` | On demand via `skill-resource` |
188
-
189
- ### How it works
190
-
191
- 1. **Discovery** - Server loads metadata from all skills into the `skill` tool description
192
- 2. **Activation** - When a skill is loaded (via tool, prompt, or resource), only the SKILL.md content is returned
193
- 3. **Execution** - SKILL.md references additional files; agent fetches them with `skill-resource` as needed
194
-
195
- ### Why SKILL.md documents its own resources
196
-
197
- The server doesn't automatically list all files in a skill directory. Instead, skill authors document available resources directly in their SKILL.md (e.g., "Copy the template from `templates/server.ts`"). This design choice follows the spec because:
198
-
199
- - **Skill authors know best** - They decide which files are relevant and when to use them
200
- - **Context efficiency** - Loading everything upfront wastes tokens on files the agent may not need
201
- - **Natural flow** - SKILL.md guides the agent through resources in a logical order
202
-
203
- **For skill authors:** Reference files using relative paths from the skill root (e.g., `snippets/tool.ts`, `references/api.md`). Keep your main SKILL.md under 500 lines; move detailed reference material to separate files. See the [Agent Skills specification](https://agentskills.io/specification) for complete authoring guidelines.
204
-
205
- ## Tools
206
-
207
- ### `skill`
208
-
209
- Load and activate an Agent Skill by name. Returns the full SKILL.md content.
210
-
211
- **Input:**
212
- ```json
213
- {
214
- "name": "skill-name"
215
- }
216
- ```
217
-
218
- **Output:** Full SKILL.md content including frontmatter and instructions.
219
-
220
- ### `skill-resource`
221
-
222
- Read files within a skill's directory (`scripts/`, `references/`, `assets/`, `snippets/`, etc.).
223
-
224
- This follows the Agent Skills spec's progressive disclosure pattern - resources are loaded only when needed.
225
-
226
- **Read a single file:**
227
- ```json
228
- {
229
- "skill": "mcp-server-ts",
230
- "path": "snippets/tools/echo.ts"
231
- }
232
- ```
233
-
234
- **Read all files in a directory:**
235
- ```json
236
- {
237
- "skill": "algorithmic-art",
238
- "path": "templates"
239
- }
240
- ```
241
- Returns all files in the directory as multiple content items.
242
-
243
- **List available files** (pass empty path):
244
- ```json
245
- {
246
- "skill": "mcp-server-ts",
247
- "path": ""
248
- }
249
- ```
250
-
251
- **Security:** Path traversal is prevented - only files within the skill directory can be accessed.
252
-
253
- ## Prompts
254
-
255
- Skills can be loaded via MCP [Prompts](https://modelcontextprotocol.io/specification/2025-11-05/server/prompts) for explicit user invocation.
256
-
257
- ### `/skill` Prompt
258
-
259
- Load a skill by name with auto-completion support.
260
-
261
- **Arguments:**
262
- - `name` (string, required) - Skill name with auto-completion
263
-
264
- The prompt description includes all available skills for discoverability. As you type the skill name, matching skills are suggested.
265
-
266
- ### Per-Skill Prompts
50
+ ## Documentation
267
51
 
268
- Each discovered skill is also registered as its own prompt (e.g., `/mcp-server-ts`, `/algorithmic-art`).
52
+ For complete documentation, just ask your assistant:
269
53
 
270
- - No arguments needed - just select and invoke
271
- - Description shows the skill's own description
272
- - List updates dynamically as skills change
273
-
274
- **Example:** If you have a skill named `mcp-server-ts`, you can invoke it directly as `/mcp-server-ts`.
275
-
276
- ### Content Annotations
277
-
278
- Prompt responses include MCP [content annotations](https://modelcontextprotocol.io/specification/2025-11-25/server/prompts#embedded-resources) for proper handling:
279
-
280
- - `audience: ["assistant"]` - Content is intended for the LLM, not the user
281
- - `priority: 1.0` - High priority content that should be included in context
282
-
283
- Prompts return embedded resources with the skill's `skill://` URI, allowing clients to track the content source.
284
-
285
- ## Resources
286
-
287
- Skills are also accessible via MCP [Resources](https://modelcontextprotocol.io/specification/2025-11-25/server/resources#resources) using `skill://` URIs.
288
-
289
- ### URI Patterns
290
-
291
- | URI | Returns |
292
- |-----|---------|
293
- | `skill://{name}` | Single skill's SKILL.md content |
294
- | `skill://{name}/` | All files in skill directory (collection) |
295
-
296
- Individual file URIs (`skill://{name}/{path}`) are not listed as resources to reduce noise. Use the `skill-resource` tool to fetch specific files on demand.
297
-
298
- ### Resource Subscriptions
299
-
300
- Clients can subscribe to resources for real-time updates when files change.
301
-
302
- **Capability:** `resources: { subscribe: true, listChanged: true }`
303
-
304
- **Subscribe to a resource:**
305
- ```
306
- → resources/subscribe { uri: "skill://mcp-server-ts" }
307
- ← {} (success)
308
- ```
309
-
310
- **Receive notifications when files change:**
311
- ```
312
- ← notifications/resources/updated { uri: "skill://mcp-server-ts" }
313
- ```
314
-
315
- **Unsubscribe:**
316
- ```
317
- → resources/unsubscribe { uri: "skill://mcp-server-ts" }
318
- ← {} (success)
319
- ```
320
-
321
- **How it works:**
322
- 1. Client subscribes to a `skill://` URI
323
- 2. Server resolves URI to file path(s) and starts watching with chokidar
324
- 3. When files change, server debounces (100ms) and sends notification
325
- 4. Client can re-read the resource to get updated content
326
-
327
- ## Security
328
-
329
- **Skills are treated as trusted content.** This server reads and serves skill files directly to clients without sanitization. Only configure skills directories containing content you trust.
330
-
331
- Protections in place:
332
- - Path traversal prevention (symlink-aware)
333
- - File size limits (1MB default, configurable via `MAX_FILE_SIZE_MB` env var)
334
- - Directory depth limits
335
- - Skill content is confined to configured directories
336
-
337
- Not protected against:
338
- - Malicious content within trusted skill directories
339
- - Prompt injection via skill instructions (skills can influence LLM behavior by design)
340
-
341
- ## Dynamic Skill Discovery
342
-
343
- The server watches skill directories for changes. When SKILL.md files are added, modified, or removed:
344
-
345
- 1. Skills are re-discovered from all configured directories
346
- 2. The `skill` tool's description is updated with current skill names and metadata
347
- 3. Per-skill prompts are added, removed, or updated accordingly
348
- 4. `tools/listChanged` and `prompts/listChanged` notifications are sent to connected clients
349
- 5. Clients that support these notifications will refresh tool and prompt definitions
350
-
351
- ## Skill Metadata Format
352
-
353
- The `skill` tool description includes metadata for all available skills in XML format:
354
-
355
- ```markdown
356
- # Skills
357
-
358
- When a user's task matches a skill description below: 1) activate it, 2) follow its instructions completely.
359
-
360
- <available_skills>
361
- <skill>
362
- <name>mcp-server-ts</name>
363
- <description>Build TypeScript MCP servers with composable code snippets...</description>
364
- <location>C:/path/to/mcp-server-ts/SKILL.md</location>
365
- </skill>
366
- </available_skills>
367
- ```
368
-
369
- This metadata is dynamically updated when skills change - clients supporting `tools/listChanged` will automatically refresh.
370
-
371
- ## Skill Discovery
372
-
373
- Skills are discovered at startup from the configured directories. For each directory, the server checks:
374
- - The directory itself for skill subdirectories
375
- - `.claude/skills/` subdirectory
376
- - `skills/` subdirectory
377
-
378
- Each skill subdirectory must contain a `SKILL.md` file with YAML frontmatter including `name` and `description` fields.
379
-
380
- ## Skill Visibility Control
381
-
382
- Control which skills appear in tools vs prompts using optional frontmatter fields:
383
-
384
- | Frontmatter | In Tool Description | In Prompts Menu | Use Case |
385
- |-------------|---------------------|-----------------|----------|
386
- | (default) | Yes | Yes | Normal skills |
387
- | `disable-model-invocation: true` | No | Yes | User-triggered workflows (deploy, commit) |
388
- | `user-invocable: false` | Yes | No | Background context (model auto-loads when relevant) |
389
-
390
- ### Example: User-Only Skill
391
-
392
- Hide from model auto-discovery, require explicit user invocation via `/skill-name` prompt:
393
-
394
- ```yaml
395
- ---
396
- name: deploy
397
- description: Deploy to production
398
- disable-model-invocation: true
399
- ---
400
- ```
401
-
402
- ### Example: Model-Only Skill
403
-
404
- Hide from prompts menu, model uses automatically when relevant:
405
-
406
- ```yaml
407
- ---
408
- name: codebase-context
409
- description: Background information about this codebase
410
- user-invocable: false
411
- ---
412
- ```
413
-
414
- Note: Resources (`skill://` URIs) always include all skills regardless of these settings, allowing explicit access when needed.
415
-
416
- ## Testing
417
-
418
- ### Manual Testing with MCP Inspector
419
-
420
- ```bash
421
- npm run build
422
- npm run inspector -- /path/to/skills
423
- ```
424
-
425
- ### Automated Evals (Development Only)
426
-
427
- The `evals/` directory contains an evaluation framework for testing skill activation across different delivery modes. Evals are only available when developing from source (not included in the npm package).
428
-
429
- ```bash
430
- # Clone the repo first
431
- git clone https://github.com/olaservo/skilljack-mcp.git
432
- cd skilljack-mcp
433
-
434
- # Install dev dependencies (includes claude-agent-sdk for evals)
435
- npm install
436
-
437
- # Build and run evals
438
- npm run build
439
- npm run eval # Default: greeting task, MCP mode
440
- npm run eval -- --task=xlsx-openpyxl # Specific task
441
- npm run eval -- --mode=native # Native skill mode
442
- npm run eval -- --mode=mcp+native # Both MCP and native enabled
443
- ```
54
+ > "how do I use skilljack?" or "how does skilljack work behind the scenes?"
444
55
 
445
- See [evals/README.md](evals/README.md) for details on available tasks, modes, and findings about activation behavior differences.
56
+ This loads the [full reference](https://github.com/olaservo/skilljack-mcp/blob/main/skills/skilljack-docs/SKILL.md) including tools, prompts, resources, configuration options, and architecture details.
446
57
 
447
58
  ## Related
448
59
 
@@ -0,0 +1,83 @@
1
+ /**
2
+ * GitHub configuration parsing and URL detection.
3
+ * Handles detection of GitHub URLs, parsing repo specs, and allowlist validation.
4
+ */
5
+ /**
6
+ * Parsed GitHub repository specification.
7
+ */
8
+ export interface GitHubRepoSpec {
9
+ owner: string;
10
+ repo: string;
11
+ ref?: string;
12
+ subpath?: string;
13
+ }
14
+ /**
15
+ * GitHub-specific configuration from environment variables.
16
+ */
17
+ export interface GitHubConfig {
18
+ token?: string;
19
+ pollIntervalMs: number;
20
+ cacheDir: string;
21
+ allowedOrgs: string[];
22
+ allowedUsers: string[];
23
+ }
24
+ /**
25
+ * Check if a path is a GitHub URL.
26
+ * Detects paths containing "github.com".
27
+ */
28
+ export declare function isGitHubUrl(urlOrPath: string): boolean;
29
+ /**
30
+ * Parse a GitHub URL into a GitHubRepoSpec.
31
+ *
32
+ * Supported formats:
33
+ * github.com/owner/repo
34
+ * github.com/owner/repo@ref
35
+ * github.com/owner/repo/subpath
36
+ * github.com/owner/repo/subpath@ref
37
+ * https://github.com/owner/repo
38
+ * https://github.com/owner/repo.git
39
+ *
40
+ * @param url - The GitHub URL to parse
41
+ * @returns Parsed GitHubRepoSpec
42
+ * @throws Error if URL format is invalid
43
+ */
44
+ export declare function parseGitHubUrl(url: string): GitHubRepoSpec;
45
+ /**
46
+ * Check if a repository is allowed by the allowlist.
47
+ * If no allowlist is configured (both allowedOrgs and allowedUsers empty),
48
+ * all repos are DENIED by default for security.
49
+ *
50
+ * @param spec - The repository specification
51
+ * @param config - GitHub configuration with allowlists
52
+ * @returns true if allowed, false if blocked
53
+ */
54
+ export declare function isRepoAllowed(spec: GitHubRepoSpec, config: GitHubConfig): boolean;
55
+ /**
56
+ * Get GitHub configuration from environment variables and config file.
57
+ * Environment variables take precedence over config file.
58
+ *
59
+ * Environment variables:
60
+ * GITHUB_TOKEN - Authentication token for private repos
61
+ * GITHUB_POLL_INTERVAL_MS - Polling interval (0 to disable, default 300000)
62
+ * SKILLJACK_CACHE_DIR - Cache directory (default ~/.skilljack/github-cache)
63
+ * GITHUB_ALLOWED_ORGS - Comma-separated list of allowed organizations (overrides config)
64
+ * GITHUB_ALLOWED_USERS - Comma-separated list of allowed users (overrides config)
65
+ */
66
+ export declare function getGitHubConfig(): GitHubConfig;
67
+ /**
68
+ * Get the local cache path for a GitHub repository.
69
+ *
70
+ * @param spec - The repository specification
71
+ * @param cacheDir - Base cache directory
72
+ * @returns Full path to the cached repository (including subpath if specified)
73
+ */
74
+ export declare function getRepoCachePath(spec: GitHubRepoSpec, cacheDir: string): string;
75
+ /**
76
+ * Get the local clone path for a GitHub repository (without subpath).
77
+ * This is where the git repository is cloned to.
78
+ *
79
+ * @param spec - The repository specification
80
+ * @param cacheDir - Base cache directory
81
+ * @returns Full path to the cloned repository root
82
+ */
83
+ export declare function getRepoClonePath(spec: GitHubRepoSpec, cacheDir: string): string;