Chisle
The coding-agent plugin that bills 52% of a bare model across 20 live tasks. Terse persona + tool-output compressor + context diet.
翻訳待ち
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗Documentation · Installation · Quick start · CLI · AI / agents
pyfsr is a batteries-included Python client for the FortiSOAR REST API. It gives you a typed query/CRUD layer over any module, picklist resolution, connector execution, playbook-run history, safe deletes -- and a ready-made AI/agent surface (tool-schema registry + an optional MCP server) so an agent can drive FortiSOAR with no glue code.
There's also a pyfsr CLI for the things you reach for outside a script:
poking at an appliance's health and services, and authoring playbooks in YAML
and pushing them to a live instance.
Python 3.10+ · Pydantic v2 · MIT.
pip install pyfsr
# with the optional generic MCP server:
pip install 'pyfsr[mcp]'
from pyfsr import FortiSOAR, Query
# API-key auth, or ("username", "password")
client = FortiSOAR("soar.example.com", "your-api-key")
# Generic, typed CRUD for ANY module via client.records(module)
incidents = client.records("incidents")
inc = incidents.get("0d2c...") # by uuid, "module:uuid", or full IRI
inc["name"], inc.uuid # records are dict- AND attribute-accessible
# Structured queries with a fluent builder -> a HydraPage you can iterate
page = incidents.query(
Query().eq("status.itemValue", "Open").like("name", "phish").limit(50)
)
for inc in incidents.iterate(Query().eq("status.itemValue", "Open")):
... # lazily walks every page
# Create / update / delete (soft by default; hard= for permanent)
new = incidents.create({"name": "Suspicious login", "severity": "High"},
resolve_picklists=True) # friendly values -> IRIs
incidents.update(new.uuid, {"status": "Closed"}, resolve_picklists=True)
incidents.delete(new.uuid) # delete(..., hard=True) to purge
from pyfsr import EnvConfig
# reads FSR_BASE_URL (+ FSR_API_KEY or FSR_USERNAME/FSR_PASSWORD),
# FSR_PORT, FSR_VERIFY_SSL, FSR_TIMEOUT
client = EnvConfig.from_env().client()
client.records(module) for CRUD on any module;
no hand-built /api/3/... URLs or Hydra unwrapping.Query().eq(...).in_(...).group(...).sort(...).limit(...),
compiled to the FortiSOAR query-body shape (pagination handled for you).BaseRecord, so custom fields/modules never break.client.picklists resolves friendly values ("High") to
IRIs and discovers which picklist a (module, field) binds to.client.connectors lists configured connectors, runs
healthchecks, and executes operations.client.playbooks merges live + historical run history and
resumes manual-input steps.client.list_modules() / client.describe_module().timeout=, automatic retry with
backoff on idempotent requests (429/5xx), and secrets masked in verbose logs.pyfsr.spec.load_spec() for offline reference and
drift(client) to compare the spec against a live appliance.The agent layer (tool registry, MCP server, workflows) lives in
fsr-agentic-toolkit; the
pyfsr-mcp command hands off to it when it is installed.
Reads accept summary=True or fields=[...] to keep payloads small:
client.records("alerts").query(Query().limit(20), summary=True)
Point any MCP-capable agent at any FortiSOAR with one command:
pip install 'pyfsr[mcp]'
FSR_BASE_URL=soar.example.com FSR_API_KEY=... python -m pyfsr.agent.mcp
It exposes the same registry (record CRUD, schema discovery, picklists, connectors, playbook runs) as MCP tools -- generic and dependency-light, distinct from any domain-specific FortiSOAR MCP.
Installing pyfsr puts a pyfsr command on your path with seven groups.
pyfsr instances -- inspect the named-instance registry
(~/.pyfsr/instances.toml), which is what every --instance flag resolves
against:
pyfsr instances list # every alias: base URL, auth kind, SSH profile
pyfsr instances show 206 # one instance's resolved settings (no secrets)
pyfsr instances check # connect to each box; exit 1 if any fails
check probes the version endpoint and then an authenticated read, so a
registered-but-broken alias shows up as unreachable or auth-failed before a
script fails on it.
pyfsr appliance -- operational verbs against a FortiSOAR box (most run over
SSH/sudo and stay dependency-light on the far end):
This is the beginning of the README. Read the rest at the original. Read the full README ↗