@raggle-ai/kennel-cli
v0.1.7
Published
Schema-backed folder ledger validator for structured workspaces.
Readme
Kennel CLI
Schema-backed folder ledger validator for structured workspaces.
Kennel keeps structured folders easy to inspect and validate. It looks upward from the target path for the nearest schema.json or _schema.json, then validates schema-declared YAML files or Markdown frontmatter documents.
Usage
npm install
npm test
node bin/kennel.mjs --helpInstall locally from this checkout:
npm install /Users/andrew/Documents/GitHub/kennel/cli
kennel --helpInstall from GitHub Packages after publication:
npm install --global @raggle-ai/kennel-cli --registry=https://npm.pkg.github.com
kennel --helpPublish to GitHub Packages:
cd /Users/andrew/Documents/GitHub/kennel/cli
NODE_AUTH_TOKEN=<github-package-token> npm publishRun against folder schemas:
kennel schema clients/reapit
kennel validate clients
kennel validate projects
kennel validate partners
kennel doctor clients/reapit
kennel dev /Users/andrewmagu/src/cdp-index --config index.json
kennel publish init cloudflare .
kennel deploy .
kennel dp .Kennel does not create schemas or new records. Manage schema.json or _schema.json files and folder templates outside the CLI, then use Kennel to inspect and validate them.
kennel publish init cloudflare is the exception for deploy wiring: it scaffolds
a Cloudflare Worker email-code gate for an existing docs workspace by writing
publication in raggle.json by default, then writing generated Cloudflare
files under .kennel/generated/cloudflare/. The generated Worker comes from the
CLI's packaged templates/cloudflare/email-code-worker.js asset, and the
generated Wrangler config is derived from the selected local JSON config file,
so Kennel can protect any static site output that deploys through the Kennel
Cloudflare path.
kennel publish, kennel deploy, and the short alias kennel dp read the
selected local config file, build the docs, set a generated
KENNEL_AUTH_SECRET, deploy with Wrangler, and smoke-test the protected URL.
Pass --config <json-file> to use another local JSON config name such as
index.json. If the selected config defines publication.cloudflare.token,
Kennel loads CLOUDFLARE_API_TOKEN from Doppler only for the publish command.
kennel publish cloudflare remains available when the provider should be
explicit.
Folder Shape
clients/
schema.json
example-client/
client.yml
people/
notes/
comms/
evidence/The nearest parent schema.json or _schema.json owns the expected shape for folders below it. When both names exist in the same folder, schema.json is preferred.
kennel validate discovers files from the nearest schema's x-kennel.documents declaration. If a schema omits that declaration, Kennel keeps the compatibility default of client.yml and index.md.
Markdown files are validated using YAML frontmatter. YAML files are parsed as YAML.
Folder Requirements
Schemas can include a Kennel-only extension for folder shape checks:
{
"x-kennel": {
"documents": [
"client.yml",
{ "path": "index.md", "parser": "markdown-frontmatter" },
{ "glob": "*.yml", "parser": "yaml" }
],
"requiredDirectories": ["people", "notes", "comms", "evidence"],
"requiredFiles": ["README.md"],
"directoryContents": [
{
"path": "people",
"glob": "*.md",
"minFiles": 1,
"whenPointerMinItems": "/contacts"
}
],
"fileReferences": [
{
"pointer": "/contacts/*/path",
"required": true,
"whenPointerMinItems": "/contacts"
}
]
}
}String document entries match a file name anywhere under the schema root. Object entries can use path or glob plus an optional parser.
requiredDirectories and requiredFiles are checked next to each validated document and by kennel doctor.
directoryContents checks that a sibling directory contains enough matching files. Use whenPointerMinItems to apply the rule only when an array in the document is non-empty, or whenPointerIn with { "pointer": "/client/status", "values": ["active-client"] } to apply it for selected field values.
fileReferences checks that document path fields point to existing files under the same folder. It supports JSON pointers with * wildcards, such as /contacts/*/path.
MCP Analytics
Generated MCP runtimes can emit tool-call metadata and explicit conversation snapshots to analytics providers. Use mcp.analytics.provider for one provider, or mcp.analytics.providers to fan out to multiple providers:
{
"mcp": {
"analytics": {
"enabled": true,
"providers": ["raggle", "posthog", "langfuse"],
"raggle": {
"projectId": "cdp-index",
"apiTokenEnv": "RAGGLE_OTEL_API_TOKEN"
},
"posthog": {
"apiKeyEnv": "POSTHOG_PROJECT_API_KEY"
},
"langfuse": {
"baseUrl": "https://cloud.langfuse.com",
"publicKeyEnv": "LANGFUSE_PUBLIC_KEY",
"secretKeyEnv": "LANGFUSE_SECRET_KEY"
}
}
}
}The Raggle provider uses the raggle-otel package and defaults to RAGGLE_OTEL_API_TOKEN, RAGGLE_OTEL_PROJECT_ID, and RAGGLE_OTEL_BASE_URL when values are not set in config. PostHog keeps the existing /capture/ behavior. Langfuse sends trace events through its public ingestion API with Langfuse basic auth credentials.
MCP Repo Integrations
kennel mcp generate also emits an MCP server runtime (@raggle-ai/kennel-mcp) with core tools for searching index docs and tracked repositories. The runtime additionally exposes repo integration tools that let an agent run basic GitHub or GitLab commands against a repository linked from the index registry (repos/index.yaml):
submit_repo_feature_request— open a feature request issue on a tracked repo, submitted on behalf of a user.list_repo_issues— list recent issues on a tracked repo.get_repo_issue— read one issue by number.
The provider (GitHub or GitLab) is detected from each registry entry's url, or can be declared with an optional provider field. By default the tools read GITHUB_TOKEN and GITLAB_TOKEN from the runtime environment, so they work without extra configuration once a token is present.
To let people supply their own GitHub or GitLab setup (custom token env, self-hosted/Enterprise API base URL, allowed repos, default labels), add an mcp.repoIntegrations block to the local config:
{
"mcp": {
"repoIntegrations": {
"enabled": true,
"github": {
"tokenEnv": "CDP_INDEX_GITHUB_TOKEN",
"apiBaseUrl": "https://github.example.com/api/v3"
},
"gitlab": {
"tokenEnv": "CDP_INDEX_GITLAB_TOKEN",
"apiBaseUrl": "https://gitlab.example.com/api/v4"
},
"allowedRepos": ["cdp-index", "index"],
"defaultLabels": ["feature-request"]
}
}
}allowedRepos is an optional allowlist of registry repo names; when omitted, every registry repo is available. Set enabled: false to disable the repo integration tools while keeping the rest of the MCP server active.
Registry entries that should support issue creation need a url (and optionally provider):
repos:
- name: index
url: https://github.com/bakerstreetco/index
provider: github
- name: cdp-index
url: https://gitlab.com/baker-street/cdp-index
provider: gitlab