Skillex
Skill management for AI agents in polyglot projects.
Skillex solves the problem of agent skill discovery in monorepos and dependency-heavy projects. It gives agents exactly the skills they need — versioned, scoped, instantly queryable — without polluting their context window with irrelevant documentation.
Packs make that model extensible beyond a single ecosystem. Projects, packages,
Go modules, and future ecosystem integrations can ship a skillex/pack.yaml
manifest that activates the right skills when Skillex sees matching files,
dependencies, or detector values.
The problem
Modern agent workflows depend on "skills": Markdown documents that teach agents how to use packages, follow repo conventions, handle migrations, and work safely in a codebase. As projects grow, skill management breaks down:
- Skills differ by package version — the right guidance for
@acme/foo@2 is wrong for v1.
- Monorepos may have different versions of the same package in different workspaces.
- The same package name may exist at multiple installed versions in one repo, and the correct answer depends on the active dependency boundary.
- Similar prompts collide across packages and versions. "Add a CTA button" is not enough unless the agent knows which app, which router, and which installed package API is in scope.
- Loading all skills upfront wastes context window. Agents get everything or nothing.
- Skills scattered across docs folders require agents to browse multiple files to find what they need.
This is not just an authoring problem. It is a retrieval problem.
File-crawled skill systems can represent package skills, project skills, path activation, and version metadata, but they still push a lot of work onto the agent:
- Discover the relevant skill catalogs.
- Load metadata for many possible skills into context.
- Decide which paths, versions, and package docs apply.
- Avoid pulling in near-miss guidance for sibling apps or different installed versions.
That approach is workable when the skill surface is small. As adoption grows, the retrieval overhead starts competing with the actual task.
Skillex covers the full lifecycle: authoring, indexing, and retrieving exactly the right skills on demand — in a single query, in microseconds.
How it works
Your repo Agent
───────────────────────────── ──────────────────────────────
skillex.json 1. "What skills apply to
skills/repo.md packages/app-a/src/auth.ts?"
packages/app-a/
package.json 2. skillex query
node_modules/ --path packages/app-a/src/auth.ts
@acme/foo/
skillex/ 3. Returns: repo.md + @acme/foo
public/consumer.md consumer.md + auth.md
public/auth.md (correct version, scoped)
private/internals.md
4. Agent reads skills, proceeds
.skillex/index.db ◀── rebuilt with accurate context
on refresh
Skillex scans your dependencies for skill exports, links them to the right scopes, stores everything in a local SQLite registry, and serves queries in microseconds. The registry is a deterministic build artifact — same repo state always produces the same index.
With packs, skill discovery is no longer limited to Node package exports:
- repos can commit project-local packs in
skillex/pack.yaml
- packages and Go modules can ship
skillex/pack.yaml with their code
- packs can define detectors such as
gin, rails, or nextjs
- Skillex core keeps only a small baseline detector set and lets communities
define the rest
In practice, that means the agent can ask:
I'm working on this file, with these dependencies, on this version. What do I need to know?
And get back the small, correct slice:
- repo skills for the current path
- app or package-area skills for that scope
- only the public skills for dependencies being consumed
- private skills only when working inside the package itself
- the correct installed version when the same package name appears more than once in the repo
That is the core difference: Skillex moves scope resolution out of the model's prompt assembly and into deterministic indexing plus structured query.
Features
- Deterministic — same repo state produces the same index, every time.
- Version-correct — skills are read from the resolved package install, not from the internet.
- Scope-aware — skills are linked to the paths where they apply. A query for
packages/app-a/** never returns skills for packages/app-b.
- Public and private — packages export consumer-facing skills (public) and contributor-facing skills (private). Visibility is enforced automatically.
- Packs — projects, packages, and modules can ship a manifest of skills, detectors, activation rules, and scopes.
- Detector-driven activation — built-in and pack-defined detectors activate skills from project facts such as files and dependencies.
- Polyglot resolver model — Node package support now shares infrastructure with non-Node resolvers; Go modules are the first non-Node resolver.
- Instant retrieval — SQLite index with structured queries plus keyword search over skill
name and description. No document browsing, no embeddings.
- MCP-native skill retrieval — first-class Model Context Protocol server. Agents with MCP support get typed skill query/read calls and resource discovery.
- Experimental downstream MCP broker — opt-in contextual discovery and lazy invocation of trusted downstream MCP capabilities without registering them with the host.
- CLI fallback — every agent harness can call the CLI. Works in CI, scripts, and terminals.
- AGENTS.md manifest — auto-generated fallback for agents that can't run MCP or shell commands.
- Testable — every skill can have a co-located
.test.md file with structured validation scenarios.
- Non-invasive — dependencies never modify your repo. No lockfile mutation, no network calls at query time.
Installation
Global binary install (recommended)
Install Skillex as a platform utility that works in any repository:
curl -fsSL https://raw.githubusercontent.com/atheory-ai/skillex/main/install.sh | sh
To install a specific version:
curl -fsSL https://raw.githubusercontent.com/atheory-ai/skillex/main/install.sh | SKILLEX_VERSION=0.9.0 sh
The installer downloads the correct binary for your platform from GitHub Releases
and installs it to ~/.local/bin by default. Set SKILLEX_INSTALL_DIR to choose
a different install directory.
npm dev dependency (Node.js projects)
Node projects can pin Skillex as a local dev dependency:
npm install --save-dev @atheory-ai/skillex
# or
pnpm add -D @atheory-ai/skillex
# or
yarn add -D @atheory-ai/skillex
The package automatically installs the correct binary for your platform (macOS arm64/x64, Linux arm64/x64, Windows x64) via npm's optionalDependencies mechanism — only the binary for your OS is downloaded.
Go install
go install github.com/atheory-ai/skillex/cmd/skillex@latest
Build from source
git clone https://github.com/atheory-ai/skillex
cd skillex
make build # builds .skillex/bin/skillex from this checkout
make install # installs to $GOPATH/bin
Quick start
Initialize your repo
skillex init
This creates:
skillex.json — configuration file (default)
skills/repo.md — a starter repo-wide skill
AGENTS.md — auto-generated agent instructions (MCP + CLI)
.skillex/index.db — the registry (rebuilt on each refresh)
To also configure MCP for your agent harness:
skillex init --harness cursor # writes .cursor/mcp.json
skillex init --harness claude-code # writes .mcp.json (project root)
skillex init --harness windsurf # writes .windsurf/mcp.json
Write your first skill
Edit skills/repo.md:
---
topics: [conventions, git]
tags: [getting-started]
---
# Repository Conventions
## Commit messages
We use conventional commits: feat:, fix:, chore:, docs:
## Branch naming
feature/<ticket>-<short-description>
Rebuild the index
skillex refresh
Query skills
# Discover applicable skills for a file path (bounded summaries)
skillex query --path packages/app-a/src/auth.ts
# By topic
skillex query --topic error-handling
# By tag
skillex query --tags migration,breaking-change
# By package
skillex query --package @acme/foo
# Compound query — intersection of all filters
skillex query --path packages/app-a/** --topic auth --tags v2
# Read only a selected skill or section returned by discovery
skillex read --ref skill:... --section authentication --max-bytes 24576
Configuration
skillex.json
{
"Version": 4,
"Rules": [
{
"Scope": "**",
"Skills": ["skills/repo.md"]
},
{
"Scope": "packages/*/**",
"Skills": ["skills/package-dev.md"]
},
{
"Scope": "packages/app-a/**",
"DependencyBoundary": "packages/app-a"
}
]
}
JSON is the default format generated by skillex init.
To generate YAML instead:
skillex init --yaml
Rules are additive. A path matching multiple rules accumulates skills from all of them.
| Field |
Description |
Scope |
Glob pattern. Skills in this rule apply when the working path matches. |
Skills |
Repo-local skill files to attach to this scope. |
DependencyBoundary |
Path to a package.json. The scanner reads its dependencies and links any that export skills. |
Skills-only and experimental MCP broker opt-in
Existing version 4 configuration remains skills-only. It does not initialize a
downstream MCP catalog, credentials, policy, or connectors, and existing users
do not need to opt out of anything.
The downstream MCP capability broker is experimental in Skillex 0.9.0.
Configuration version 5 remains skills-only unless MCP.Enabled is explicitly
true:
Version: 5
Rules:
- Scope: "**"
Skills:
- skills/repo.md
MCP:
Enabled: true
Catalogs:
- Type: static
Path: .skillex/mcp/catalog.json
- Type: trusted
Name: official
Bindings:
- Server: io.example/issues
Version: 1.0.0
AuthProfile: issues-work
Scope: "packages/app/**"
Each binding selects an exact canonical server version and project scope.
AuthProfile is only the name of a separately trusted user or enterprise
profile; repository configuration cannot define credentials or secret sources.
Bindings are rejected unless MCP is explicitly enabled, and unknown version 5
fields are rejected so security-sensitive typos do not silently pass.
Trusted execution and credential mapping live outside the repository. By
default Skillex reads the platform user config at
$XDG_CONFIG_HOME/skillex/mcp-trust.yaml (or the OS equivalent). A user or
enterprise launcher may select one exact file with
SKILLEX_MCP_TRUST_CONFIG. For example:
Version: 1
Servers:
- Server: io.example/issues
Version: 1.0.0
AllowedProjects: [/absolute/path/to/project]
AuthProfiles: [issues-work]
Stdio:
Command: /absolute/path/to/issues-mcp
CredentialProfiles:
- Name: issues-work
Service: io.example/issues
Credentials:
- Slot: access-token
Sources:
- Env:
Key: ISSUES_TOKEN
- Dotenv:
Path: "${projectRoot}/.env.mcp"
Key: ISSUES_TOKEN
Inject:
StdioEnv: DOWNSTREAM_ISSUES_TOKEN
CatalogSources:
- Name: official
Type: registry-api
BaseURL: https://registry.modelcontextprotocol.io
AllowedNamespaces: [io.github.my-company]
Telemetry:
Enabled: false
Path: /absolute/path/to/skillex-mcp-usage.jsonl
Skillex resolves only the named source keys for the selected service/profile.
It does not enumerate a dotenv file into the process environment and downstream
stdio servers do not inherit the parent environment. Exact Keychain and
absolute Helper sources are also supported; helpers receive an empty
environment and bounded stdout. Streamable HTTP servers may use exact header
injection or mTLS certificate/key sources.
OAuth profiles support authorization code with PKCE, URL-based Client ID
Metadata Documents, explicitly enabled Dynamic Client Registration fallback,
encrypted refresh-token storage, client credentials (secret or
private_key_jwt), workload token exchange, and Enterprise-Managed
Authorization with ID-JAG. Discovery validates protected-resource metadata,
issuer, resource, audience, scopes, and HTTPS endpoints. skillex auth status
does not contact the server; skillex auth login --profile <name> returns a
typed, resumable login action.
These authentication flows have automated protocol and security-boundary
coverage, but are not certified integrations for every identity provider.
Provider-specific metadata, policy, token claims, key rotation, or deployment
requirements may require additional configuration or an adapter. In particular,
"IAP-style" means validated RS256 bearer-token semantics, not a certified Google
IAP integration.
For example, a user-delegated remote profile can use a URL client ID (CIMD):
CredentialProfiles:
- Name: issues-sso
Service: io.example/issues
OAuth:
Type: authorization-code
ProtectedResourceMetadataURL: https://mcp.example/.well-known/oauth-protected-resource
Resource: https://mcp.example
Issuer: https://login.example/tenant
ClientID: https://clients.example/skillex.json
RedirectURI: http://127.0.0.1:17832/callback
Scopes: [issues.read, issues.write]
OAuthStore:
KeyPath: /absolute/private/path/oauth.key
Directory: /absolute/private/path/tokens
Set OAuth.Type to enterprise-managed, client-credentials, or
workload-token-exchange for those flows. Every secret/assertion/private-key
input uses the same ordered exact-source mapping; none may be supplied by a
repository pack.
Registry and downstream discovery are explicit synchronization operations, not
query-time fan-out:
skillex catalog sync # Registry API metadata → offline cache
skillex catalog inspect # trusted bound servers → tool/prompt/resource metadata
skillex query --search "create issue" # offline contextual search
skillex capability describe --ref <ref> --max-bytes 24576
skillex capability call --ref <ref> --arguments '{"title":"Bug"}'
skillex telemetry summary # opted-in privacy-safe usage counts
catalog inspect is the only operation above that starts stdio servers or calls
remote MCP endpoints. Query and describe remain offline. Observed definitions
carry freshness metadata; expired views become stale and cannot be invoked
until re-inspected. Optional local telemetry is off by default and records only
attributed server/capability identity, readiness, outcome, and duration—never
credentials, arguments, results, tokens, or headers.
Capability discovery remains bounded even for high-match searches: SQLite
applies visibility, scope, capability filters, full-set counts and narrowing
facets, stable ranking, and pagination before Skillex hydrates and signs only
the requested page.
Skills
A skill is a Markdown file with optional YAML frontmatter.
---
name: Error Handling
description: How to handle errors and validation when using FooClient in @acme/foo.
topics: [error-handling, validation]
tags: [v2, breaking-change]
---
# Error Handling in @acme/foo
When using FooClient, all API calls return a Result type...
Frontmatter fields
| Field |
Description |
name |
Short title for the skill. Recommended; used by --search and result summaries. |
description |
One-line summary. Recommended; used by --search. |
topics |
Semantic categories. Used for --topic queries. |
tags |
Freeform labels. Used for --tags queries. |
source |
(Vendor skills) URL the skill was imported from. |
reviewed |
(Vendor skills) Timestamp of last agent review. |
topics and tags are optional. Skills without frontmatter are still indexed and queryable by path, scope, and package. Skills without name or description are not matched by --search; skillex doctor warns about missing fields.
Project-local packs
A pack bundles skill files with activation rules. Packs are the extension point
for ecosystem and framework-specific guidance: a community can publish a pack for
a framework, a library can ship a pack with its code, and a repo can commit a
project-local pack for its own conventions.
Project-local packs activate during skillex refresh when files, dependencies,
or detector values match the repository.
Skillex discovers project-local pack manifests at:
skillex/pack.yaml
skillex/packs/*/pack.yaml
Example:
name: docker
version: 1.0.0
description: Docker guidance for repositories with Dockerfiles.
detectors:
docker:
matches:
- file:
path: Dockerfile
- file:
path: Dockerfile.*
skills:
- file: docker.md
activate-when:
detector: docker
scope: subtree
- file: typescript.md
activate-when:
files-matching:
- "**/*.ts"
- "**/*.tsx"
scope: matching-files
The skill file path is relative to the pack manifest. A co-located
docker.test.md file is discovered automatically.
Supported activation and scope fields in this initial pack implementation:
| Field |
Description |
activate-when.files-present |
Glob patterns matched against repository files. |
activate-when.files-matching |
Glob patterns matched against repository files. |
activate-when.dependency-declared |
Dependency conditions matched against the boundary that resolved a package-shipped pack. |
activate-when.detector |
Friendly detector name registered by Skillex core or a loaded pack. |
detectors |
Optional detector definitions registered by the pack while it is loaded. |
files |
Optional glob patterns for scope: matching-files; when omitted, the activation matches are used. |
scope: repo |
Activate the skill for the whole repository (**). |
scope: boundary |
Activate for the dependency boundary that resolved a package-shipped pack. |
scope: subtree |
Activate for the directory containing the matched file and below. Default. |
scope: directory |
Activate for files immediately inside the matched file's directory. |
scope: matching-files |
Activate for the exact files matched by the activation or files patterns. |
scope: nearest-ancestor |
Activate for the nearest containing directory and below. |
Pack skills are indexed individually with source_type: pack. Existing projects
with no pack manifests behave exactly as before.
Detector names are extensible. Skillex core includes only a small baseline of
stable detectors, such as docker, go, javascript, and typescript. Packs
can register framework, library, or ecosystem-specific detector names for the
current refresh run. Conflicting detector definitions are rejected unless they
are identical, so core does not need to own every possible term.
Exporting skills from a package
Any npm package can export skills by adding a skillex field to its package.json:
{
"name": "@acme/foo",
"skillex": true
}
Then create the skill directories:
skillex/
public/ ← skills for consumers of the package
consumer.md
consumer.test.md
migrations.md
migrations.test.md
private/ ← skills for contributors to the package
architecture.md
dev-workflow.md
To initialize a package for skill exports:
skillex init --package
Public skills are linked when the package appears as a dependency of the current scope.
Private skills are linked when the agent's working path is inside the package's source tree.
Packages can also ship a pack manifest alongside the legacy directories:
skillex/
pack.yaml
usage.md
public/
consumer.md
name: "@acme/foo"
version: 1.0.0
skills:
- file: usage.md
activate-when:
dependency-declared:
- source: npm-package
name: "@acme/foo"
scope: boundary
When skillex/pack.yaml is present, Skillex activates matching pack skills at
refresh time and indexes them individually with package metadata. The existing
skillex/public and skillex/private behavior remains supported.
Go modules can ship the same skillex/pack.yaml convention. The Go resolver
detects go.mod dependency boundaries, reads declared modules, and resolves
local replace or vendor module roots without downloading dependencies or
mutating module state.
Custom skill directory
{
"skillex": {
"path": "docs/skillex"
}
}
Skill tests
Every skill can have a co-located test file (<name>.test.md). Tests are structured scenarios that agents use to self-evaluate whether a skill produces correct guidance.
# Tests: consumer.md
## Validation: API initialization
Prompt: "How do I initialize the @acme/foo client?"
Success criteria:
- Response references the FooClient constructor
- Response includes the required config object
- Response does not expose internal implementation details
## Validation: Error handling
Prompt: "How should I handle errors from @acme/foo?"
Success criteria:
- Response covers the FooError type
- Response shows try/catch pattern with specific error codes
## Validation: Migration from v1
Prompt: "I'm upgrading @acme/foo from v1 to v2"
Skills: consumer.md, migrations.md
Success criteria:
- Response mentions the breaking change in auth flow
- Response provides the v2 config shape
- Response does not suggest deprecated v1 patterns
The agent is the test runtime. Skillex validates structure; agents validate behavior. To check structural integrity:
skillex test validate
skillex test validate --check # exit non-zero on errors (CI)
MCP server for skills
Skillex runs as a Model Context Protocol server, providing native integration for MCP-capable agent harnesses (Cursor, Claude Code, Windsurf, and others).
skillex mcp
MCP configuration
Add to your harness's MCP config (e.g. .cursor/mcp.json):
{
"mcpServers": {
"skillex": {
"command": "skillex",
"args": ["mcp"]
}
}
}
Or let skillex init --harness <name> write this for you.
MCP primitives
Tool: skillex_query
Parameters:
path string File path or glob pattern
topic string Comma-separated topic filters
tags string Comma-separated tag filters
package string Package name filter
search string Keyword search over skill name and description (space/comma tokens, OR)
limit number Maximum discovery summaries (default 8, max 20)
cursor string Continuation cursor for a broad discovery result
Use `skillex_read` with a selected result `ref` and optional section id for bounded content.
Resources
Each skill in the registry is exposed as a discoverable MCP resource at:
skillex://skills/{scope}/{package}/{filename}
Agents discover available resources through the MCP protocol's resource listing — no AGENTS.md parsing required.
Downstream MCP capability broker
Experimental in Skillex 0.9.0. Core discovery, routing, isolation, and
protocol flows have automated coverage. Downstream server and identity-provider
interoperability is not yet guaranteed across every vendor or enterprise
deployment. Enabling this feature does not weaken the required secret-isolation,
policy, schema-validation, or tenant-boundary behavior.
The capability-broker implementation keeps the host registration model simple:
the host registers only Skillex, and Skillex opens a selected downstream server
on demand. A downstream server is never written into Cursor, VS Code, or another
host's MCP configuration.
Version 4 projects cannot construct the broker. Version 5 projects must use the
explicit MCP.Enabled gate shown in the configuration section. Enabled projects
get additive, independently paginated capability results from skillex_query plus
skillex_mcp_describe and skillex_mcp_call. CLI capability describe and MCP
skillex_mcp_describe enforce the same bounded output contract: 24 KiB by
default and at most 64 KiB via --max-bytes or max_bytes. Skillex revalidates the signed
reference, workspace context, binding, readiness, policy, live schema, and JSON
Schema 2020-12 arguments before invoking the one selected server. Tools, prompts,
and resource templates are indexed at capability granularity. Calls support MCP
2026-07-28 multi-round-trip input_required results and retries with
inputResponses plus opaque requestState. Trusted stdio and stateless
Streamable HTTP connectors are supported, including optional server/discover,
list TTL/cache-scope handling, per-request metadata, and routing headers. See the
implementation status.
| Area |
Release status |
| Skills and skill retrieval |
Stable |
| Skillex's skill-facing MCP server |
Stable |
| Downstream MCP discovery and invocation |
Experimental |
| Static, environment, dotenv, keychain, helper, and mTLS credentials |
Experimental |
| OAuth PKCE, client credentials, and workload token exchange |
Experimental; conformance-tested |
| EMA/ID-JAG and IAP-style identity |
Experimental; not provider-certified |
| Hosted multi-tenant deployment components |
Integration foundation only |
CLI reference
All commands support --json (structured stdout) and --quiet (suppress stderr).
skillex init
skillex init # Interactive setup for a repo
skillex init --yes # Accept all defaults (creates skillex.json)
skillex init --yaml # Generate skillex.yaml instead
skillex init --package # Initialize a package for skill exports
skillex init --harness cursor # Also configure MCP for Cursor
skillex refresh
skillex refresh # Rebuild the registry (dev mode)
skillex refresh --mode prod # Production deps + public skills only
skillex refresh --check # Fail if registry is stale (CI)
skillex refresh --dry-run # Preview without writing
Refresh after changing skills, Skillex configuration, or installed dependencies. It is
not a per-task setup step.
skillex query
skillex query --search "<concepts>"
skillex query --path <filepath>
skillex query --topic <topic>
skillex query --tags <tag1,tag2>
skillex query --package <name>
skillex query --search "auth" --topic security
skillex query --path <filepath> --search "<task intent>" --limit 8
skillex query --mcp-server io.example/issues --mcp-kind tool --mcp-availability ready
skillex read --ref <ref-from-query> --section <optional-section-id>
query is discovery: it returns bounded summaries. Narrow a broad result, then use
read for the selected skill or section. --format content is retained only for
backward compatibility; do not use it for agent discovery.
skillex test validate
skillex test validate # Check all test files
skillex test validate --check # Exit non-zero on errors (CI)
skillex test validate --scope "packages/app-a/**"
skillex doctor
skillex doctor # Full diagnostics report
skillex doctor --json # Machine-readable report
Checks: configuration validity, registry health, test coverage, topic/tag distribution, skills missing name/description (search discoverability), AGENTS.md presence, vendor skill provenance.
skillex get
skillex get <url> # Fetch and vendor a remote skill
skillex get <url> --topic react,hooks # Assign topics on import
skillex get <url> --skip-review # Skip safety review
Fetches a skill from a URL, runs a structural safety review (checking for prompt injection patterns, exfiltration attempts, and dangerous commands), converts it to skillex format, and vendors it to skillex/vendor/<source>/.
skillex import
skillex import ./docs/api-patterns.md
skillex import ./docs/api-patterns.md --visibility public --topic api,patterns
skillex import ./legacy-rules/ --batch
Imports a local file through the same review and conversion pipeline as skillex get. Use this to migrate Cursor rules, Windsurf rules, or any existing Markdown documentation.
skillex mcp
skillex mcp # Start MCP server on stdio
skillex version
skillex version
skillex version --json
CI integration
Add to your CI pipeline:
# Fail if the registry is out of date with the source files
skillex refresh --check
# Fail if any test files are malformed
skillex test validate --check
Recommended package.json scripts:
{
"scripts": {
"skillex:refresh": "skillex refresh",
"skillex:test": "skillex test validate",
"skillex:doctor": "skillex doctor"
}
}
Vendoring external skills
Skillex provides a controlled pipeline for adopting skills from external sources. Vendor skills are committed to your repo, making them auditable, diffable, and version-controlled.
# Fetch from a URL
skillex get https://raw.githubusercontent.com/someone/react-patterns/main/hooks.md
# Import from a local file
skillex import ./cursor-rules.md --visibility public --topic react
# Batch import a directory
skillex import ./legacy-docs/ --batch
Vendored skills land in skillex/vendor/<source>/ with:
- Normalized frontmatter (name, description when present, topics, tags)
- Source URL recorded for provenance
- Auto-generated test stubs
AGENTS.md
On every refresh, Skillex auto-generates (or updates) a section in AGENTS.md. This serves as a fallback for agents that support neither MCP nor shell execution.
<!-- skillex:start -->
## Skillex
This project uses Skillex for skill management. Use the skillex MCP server
if available (preferred), otherwise use the CLI commands below.
### MCP (preferred)
...
- `skillex_query` parameters include `search` for intent-based discovery.
### CLI (fallback)
...
- `skillex query --search "<concepts>"`
...
### Available scopes
- **
- packages/app-a/**
### Available topics
error-handling, configuration, migration, authentication
### Available tags
v2, breaking-change, deprecated, getting-started
### Packages with skills
@acme/foo (2.3.1) — 3 public, 2 private
<!-- skillex:end -->
Skillex manages only its own section, delimited by markers. It never modifies other content in the file.
Project structure
.
├── skillex.json # Configuration (default)
├── AGENTS.md # Agent instructions (auto-updated)
├── skills/ # Repo-level skills
│ ├── repo.md
│ └── repo.test.md
└── .skillex/
└── index.db # Registry (build artifact, not committed)
For packages exporting skills:
my-package/
├── package.json # "skillex": true
└── skillex/
├── public/ # Consumer-facing skills
│ ├── consumer.md
│ └── consumer.test.md
├── private/ # Contributor-facing skills
│ ├── architecture.md
│ └── dev-workflow.md
└── vendor/ # External skills (committed)
├── github.com/someone/react-patterns/
│ └── hooks.md
└── local/
└── imported-guide.md
How agents use Skillex
With MCP (preferred)
The agent discovers available skills through MCP resource listing and calls the skillex_query tool directly — no shell commands, no file parsing.
With CLI (fallback)
The agent reads AGENTS.md at session start to learn what's available and how to query, then calls skillex query when it needs skills for a specific path or topic.
Skill testing model
When validating a skill, the agent:
- Queries the registry for the skill and its test scenarios
- For each scenario, evaluates the prompt with the skill loaded
- Self-assesses the output against the success criteria
- Reports which validations passed, failed, and why
The CLI validates structure. The agent validates behavior.
Architecture
┌─────────────────┐
│ AGENTS.md │ Fallback
└────────┬────────┘
│
┌────────┴────────┐
│ MCP Server │ Native (resources + tools)
└────────┬────────┘
│
┌────────┴────────┐
│ CLI │ Foundation (Cobra + Lipgloss)
└────────┬────────┘
│
┌──────────────────────┴──────────────────────────────┐
│ skillex core │
│ │
│ Scanner → Linker → Registry (SQLite) → Query engine │
│ Validator │
└─────────────────────────────────────────────────────┘
Core engine (Go library):
| Component |
Responsibility |
| Scanner |
Discovers skill files in the repo and in installed npm packages |
| Linker |
Resolves public/private visibility and scope assignments |
| Registry |
SQLite database storing skills, topics, tags, scopes, and test scenarios |
| Query engine |
Structured retrieval by path, topic, tags, and package |
| Validator |
Checks that skill and test files are well-formed |
Interface layers (all backed by the same core):
| Layer |
Use case |
| CLI |
Universal. CI, scripts, terminals, any agent harness |
| MCP server |
Native integration for MCP-capable harnesses |
| AGENTS.md |
Last resort for agents that can't run MCP or shell commands |
Architecture and implementation status
- Experimental MCP capability broker — the
architecture and implementation in which hosts register only Skillex, while
Skillex discovers, selects, authenticates to, and invokes downstream MCP
servers dynamically.
Building from source
Requirements: Go 1.22+
git clone https://github.com/atheory-ai/skillex
cd skillex
make build # builds .skillex/bin/skillex from this checkout
make install # $GOPATH/bin/skillex
make test # go test ./...
make lint # go vet ./...
make dist # cross-compile for all platforms → dist/
make release-assets # package GitHub release archives + checksums
Cross-compiled targets:
| File |
Platform |
dist/skillex-darwin-arm64 |
macOS Apple Silicon |
dist/skillex-darwin-x64 |
macOS Intel |
dist/skillex-linux-x64 |
Linux x64 |
dist/skillex-linux-arm64 |
Linux arm64 |
dist/skillex-win32-x64.exe |
Windows x64 |
Versioning and releases
Skillex uses a single source of truth for releases: the root VERSION file.
- Go binaries read the version at build time via
-ldflags.
- npm package versions are synced from
VERSION before packaging.
- Local development builds default to
<VERSION>-dev.
To prepare a release:
- Update
VERSION in a pull request.
- Merge the PR to
main.
- From a clean local checkout of
main, run make release-tag.
- GitHub Actions verifies the tag, publishes GitHub release assets, and publishes to npm after release approval.
make release-tag reads VERSION, creates the matching v* tag, and pushes it. It refuses to run unless you are on main, your worktree is clean, HEAD matches origin/main, and the tag does not already exist.
To build npm tarballs locally for inspection:
make npm-pack
To build GitHub release assets locally for inspection:
make release-assets
make npm-publish still exists as a manual fallback, but the intended release path is the GitHub Actions release workflow.
At the moment, releases are maintainer-only. In practice, only @ladyhunterbear should bump VERSION, create release tags, or approve the npm-release publish environment until additional maintainers are explicitly added.
Security
- Dependencies never modify the consumer repository.
- No network access at query time — all data comes from the local registry.
- No lockfile mutation.
skillex get and skillex import run a structural safety review before vendoring any external skill, checking for prompt injection patterns, exfiltration attempts, and dangerous commands.
- The SQLite database is fully reproducible from source inputs.
License
Apache 2.0