Skip to main content

Python library implementing Anthropic's Agent Skills functionality for LLM-powered agents

Project description

faskill

Fork of maxvaega/skillkit
Extensively refactored with bug fixes, security hardening, and new abstractions.
Maintained by AmritaConstant.

Python License PyPI GitHub release

faskill is a Python library that brings Anthropic's Agent Skills to any LLM-powered agent. It discovers, loads, and invokes packaged expertise — defined in standard SKILL.md files — with progressive disclosure for token efficiency.

Features

  • SKILL.md compatible — works with any existing skill, drop-in ready
  • Framework-agnostic — use standalone or with LangChain (more integrations planned)
  • Model-agnostic — works with any LLM
  • Multi-source discovery — custom directories, plugins with priority-based conflict resolution
  • Progressive disclosure — metadata-first loading, 80% memory reduction, LRU caching; scripts loaded on demand
  • Script execution — Python, Shell, JavaScript, Ruby, Perl with security validation and timeout enforcement
  • Pluggable runnerRunner abstraction with HostRunner default; swap in Docker, Firecracker, etc.
  • Plugin ecosystem — supports plugin manifests (.claude-plugin/plugin.json) with namespaced skill access
  • Comprehensive error hierarchy — 20+ typed exceptions for precise error handling

Notable Improvements Over Upstream (skillkit)

This fork contains significant refactoring and bug fixes beyond the original:

Area Improvement
Bug fix PRIORITY_CUSTOM no longer decrements — ≥5 sources won't trigger ValueError: Priority must be positive
Bug fix create_langchain_tools() no longer eagerly loads all scripts — respects progressive disclosure (L1→L2→L3)
New InvalidSkillNameError — names with spaces are rejected (bypass with NO_FAIL_ON_SPACE=1)
New Runner abstraction — HostRunner (default, warns once about bare host security) with swappable backends
New ArgumentSerializationError / ArgumentSizeError / ToolIDValidationError — fine-grained script errors
New ConfigurationError / AsyncStateError / PluginError — better error reporting
Refactor SkillManagerSkillContext with create_context() factory; modular architecture (discovery, parser, registry, invoker, processors, scripts, runner)
Refactor Complete test suite (425 tests), 70%+ coverage, comprehensive fixtures

Installation

pip install faskill              # Core library
pip install faskill[langchain]   # With LangChain integration
pip install faskill[all]         # All extras

Quick Start

1. Create a skill

.claude/skills/code-reviewer/SKILL.md
---
name: code-reviewer
description: Review code for best practices and potential issues
allowed-tools: Read, Grep
---

# Code Reviewer

Analyze the provided code for:

- Best practices violations
- Potential bugs
- Security vulnerabilities

Use $ARGUMENTS to access user input.

2. Use standalone

from faskill import create_context

ctx = create_context(skill_dirs=["./.claude/skills"])
ctx.discover()

# List available skills
for skill in ctx.list_skills():
    print(f"{skill.name}: {skill.description}")

# Invoke a skill
result = ctx.invoke_skill("code-reviewer", "Review function calculate_total()")
print(result)

3. Use with LangChain

from faskill import create_context
from faskill.integrations.langchain import create_langchain_tools
from langchain.agents import create_agent
from langchain_openai import ChatOpenAI

ctx = create_context(skill_dirs=["./.claude/skills"])
ctx.discover()

tools = create_langchain_tools(ctx)

llm = ChatOpenAI(model="gpt-4o")
agent = create_agent(llm, tools, system_prompt="You are a helpful assistant.")
result = agent.invoke({"messages": [{"role": "user", "content": "Review my code"}]})

SKILL.md Format

---
name: my-skill # Required: unique identifier
description: ... # Required: human-readable description
allowed-tools: Bash, Read # Optional: tool allowlist
version: "1.0" # Optional: semantic version
---
# Skill content with $ARGUMENTS placeholder
  • Argument substitution: $ARGUMENTS → user input; $$ARGUMENTS → literal $ARGUMENTS
  • No placeholder: arguments are appended to the end

Script Execution

Skills can bundle executable scripts for deterministic operations:

my-skill/
├── SKILL.md
└── scripts/
    └── extract.py
result = ctx.execute_skill_script(
    skill_name="my-skill",
    script_name="extract",
    arguments={"file": "doc.pdf", "pages": "all"},
    timeout=30,
)

if result.success:
    print(result.stdout)
else:
    print(f"Error ({result.exit_code}): {result.stderr}")

Supported types: .py, .sh, .js, .rb, .pl, .bat, .cmd, .ps1.

Script runner (pluggable)

ScriptExecutor accepts a runner parameter — swap in sandboxed backends:

from faskill.core.scripts import ScriptExecutor
from faskill.core.runner import HostRunner  # default (warns once about security)

# Default: bare host
executor = ScriptExecutor(runner=HostRunner())

# Future: Docker, Firecracker, gVisor...
# executor = ScriptExecutor(runner=DockerRunner(image="python:3.12"))

API Reference

create_context()

from faskill import create_context

ctx = create_context(
    skill_dirs=["./skills", "./plugins"],  # Directory list; directories with
    # .claude-plugin/plugin.json are
    # detected as plugins
    default_script_timeout=30,  # seconds (1-600)
    max_cache_size=100,  # LRU cache entries
)

SkillContext

Method Description
discover() Sync skill discovery
adiscover() Async skill discovery
list_skills() List all discovered skill metadata
list_skills(include_qualified=True) List names including plugin:skill
get_skill(name) Get metadata by name; raises SkillNotFoundError
invoke_skill(name, args) Sync invocation with caching
ainvoke_skill(name, args) Async invocation with caching
execute_skill_script(...) Execute a bundled script
get_cache_stats() Cache hit/miss statistics
clear_cache(name?) Clear cache entries
add_source(path) Add a skill directory after construction

Key types

Type Description
SkillMetadata Name, description, path, allowed tools, priority
Skill Full skill: metadata + content + scripts
SkillSource Source directory with type and priority
ScriptMetadata Detected script name, path, language, description
ScriptExecutionResult exit_code, stdout, stderr, execution_time_ms, etc.
CacheStats size, max_size, hits, misses, hit_rate
Runner Abstract base for script execution backends
HostRunner Default runner — bare host subprocess (warns once)

Exception hierarchy

SkillsUseError
├── SkillParsingError
│   ├── InvalidYAMLError
│   ├── MissingRequiredFieldError
│   ├── InvalidSkillNameError          # name contains spaces (bypass: NO_FAIL_ON_SPACE=1)
│   └── InvalidFrontmatterError
├── SkillNotFoundError
├── SkillInvocationError
│   ├── ArgumentProcessingError
│   ├── ArgumentSerializationError
│   ├── ArgumentSizeError
│   └── ContentLoadError
├── ConfigurationError
├── AsyncStateError
├── PluginError
│   ├── ManifestNotFoundError
│   ├── ManifestParseError
│   └── ManifestValidationError
├── ScriptError
│   ├── InterpreterNotFoundError
│   ├── ScriptNotFoundError
│   ├── ScriptPermissionError
│   ├── ArgumentSerializationError
│   ├── ArgumentSizeError
│   └── ToolIDValidationError
├── SkillSecurityError
│   ├── SuspiciousInputError
│   ├── SizeLimitExceededError
│   └── PathSecurityError

Examples

See examples/ directory:

File What it demonstrates
basic_usage.py Sync and async standalone usage
async_usage.py Async usage with FastAPI
langchain_agent.py LangChain agent integration
multi_source.py Multi-source discovery and conflict resolution
file_references.py Secure file path resolution
caching_demo.py Cache performance demonstration
script_execution.py Script execution with error handling

Documentation


Where to find skills


Contributing

  1. Fork → branch → make changes → add tests
  2. Ensure uv run pytest passes (≥70% coverage)
  3. Ensure uv run ruff check src/ and uv run pyright src/ pass
  4. Submit a pull request

See CONTRIBUTING.md for detailed guidelines.


License

MIT — see LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

faskill-0.1.0.tar.gz (112.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

faskill-0.1.0-py3-none-any.whl (56.9 kB view details)

Uploaded Python 3

File details

Details for the file faskill-0.1.0.tar.gz.

File metadata

  • Download URL: faskill-0.1.0.tar.gz
  • Upload date:
  • Size: 112.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for faskill-0.1.0.tar.gz
Algorithm Hash digest
SHA256 af96ca379ff8d3aafb71dca7b5f6a9f7888ddb5e083c631f809239f149e44664
MD5 88545a3851e86c438c39a6a4908f447b
BLAKE2b-256 0a1bb7753f6808003bae4df3756de6373cb090f6d9cae01c965e20f0f576f379

See more details on using hashes here.

File details

Details for the file faskill-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: faskill-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 56.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for faskill-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 28839329ff0bf4e3bb9abeceaebfbb6f6dd7923e618b8f09f9a8b99610c113ec
MD5 4451b8de1cda7bdcbe3642d01e02a001
BLAKE2b-256 e6689eec361a7d22c6744ea937d9f744a2955b7aabdd563fa15d86e4fbd2b674

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page