diff --git a/.claude/skills/kosli-next-writer/SKILL.md b/.claude/skills/kosli-next-writer/SKILL.md new file mode 100644 index 0000000..62ea731 --- /dev/null +++ b/.claude/skills/kosli-next-writer/SKILL.md @@ -0,0 +1,87 @@ +--- +name: kosli-next-writer +description: Use when writing or editing docs for Kosli Next - the docs surface for forward-looking concepts and preview features. Triggers on mentions of "Kosli Next", "concept docs", "preview feature docs", or any work on files under `kosli_next/`. Covers where files go, required front matter and banners, navigation updates, and tone. +--- + +# Writing for Kosli Next + +Kosli Next is a separate Mintlify Product (alongside "Product") for content that is **not currently available in Kosli**. Use it for concepts (ideas we're considering) and preview features (opt-in pre-GA features). + +If the content describes something shippable today, it does NOT belong in Kosli Next - it goes in the main "Product" surface under `understand_kosli/`, `getting_started/`, etc. + +## Decision flow + +1. **Is the feature available to all customers today?** → Main docs. Stop reading this skill. +2. **Is it an idea or direction we want feedback on, but nothing is built yet?** → Kosli Next → Concepts. +3. **Is it real, usable, but opt-in / pre-GA?** → Kosli Next → Preview. + +## File locations + +| Content type | Directory | +|---|---| +| Concept page | `kosli_next/concepts/.mdx` | +| Preview page | `kosli_next/preview/.mdx` | + +Use lowercase, underscore-separated slugs to match the rest of the repo (`kosli_next/concepts/my_concept.mdx`). + +## Required page template + +Every Kosli Next page starts with this shape: + +```mdx +--- +title: "Short, specific title" +description: "One sentence describing the page purpose." +tag: "Concept" # or "Preview" +--- + +import { ConceptBanner } from '/snippets/kosli-next-banner.mdx'; +{/* or: import { PreviewBanner } from '/snippets/kosli-next-banner.mdx'; */} + + +{/* or: */} + +Page content goes here. +``` + +The banner snippet (`snippets/kosli-next-banner.mdx`) is the single source of truth for the disclaimer + feedback CTA. Do NOT inline a custom disclaimer. + +## Navigation update (required) + +Add the new page path to `config/navigation.json` under the matching tab in the **Kosli Next** product: + +- Concept pages → `products[1].tabs[0].groups[0].pages` +- Preview pages → `products[1].tabs[1].groups[0].pages` + +A page that isn't in `config/navigation.json` won't appear in the sidebar. This is a core repo rule. + +## Tone + +Standard Kosli writing rules from the project `CLAUDE.md` still apply: + +- Sentence case for headings. +- Active voice and imperative mood. +- "Kosli" - not "the Kosli platform" or "KOSLI". +- Root-relative internal links (`/kosli_next/concepts/foo`, not `../foo`). +- No em-dashes. Use hyphens or rewrite the sentence. + +Two Kosli Next-specific additions: + +- **Be honest about status.** Don't write a Concept page in the present tense as if it works ("Kosli reports X..."). Write in the conditional ("Kosli would report X...") so readers aren't misled into thinking the feature exists. +- **Invite feedback.** End each page with a short prompt: "Tell us what you think - email support@kosli.com." (The banner says this too; an end-of-page nudge is fine.) + +## Form + +Diátaxis is NOT enforced inside Kosli Next. Pick whichever shape best explains the idea: + +- A short PR/FAQ-style explainer (problem → proposed approach → open questions) is often a good fit for Concepts. +- A how-to + reference combination tends to fit Previews. + +## Verification + +Before opening a PR: + +1. Run `mint dev` and confirm the page appears under the right tab in the Kosli Next product switcher. +2. Confirm the banner renders. +3. Run `mint broken-links`. + diff --git a/.gitignore b/.gitignore index 6013b4e..6c8a294 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ .claude/settings.local.json tmp/ __pycache__/ +docs/superpowers/ +.DS_Store diff --git a/.mintlify/AGENTS.md b/.mintlify/AGENTS.md new file mode 100644 index 0000000..dbc023c --- /dev/null +++ b/.mintlify/AGENTS.md @@ -0,0 +1,96 @@ +# Kosli docs agent instructions + +These instructions apply to the Mintlify agent across the dashboard, the `@Mintlify` Slack bot, and the docs site assistant. Read them before answering any question or writing any documentation. + +## Project context + +Kosli is a platform for recording changes in software and business processes so customers can prove compliance and maintain security without slowing delivery. The docs site is organised into two Mintlify Products: + +- **`Product`** - documentation for what Kosli does today. This is the default and the authoritative source for "how do I do X" questions. +- **`Kosli Next`** - forward-looking content. Two tabs: + - **Concepts** (`kosli_next/concepts/`) - ideas we're considering. Nothing in here is built. + - **Preview** (`kosli_next/preview/`) - real features available to opt-in customers ahead of general availability. Behaviour can still change. + +## Retrieval rules + +**Default to the `Product` surface.** When a customer asks how to do something, answer from the `Product` Product only. + +**Use Kosli Next only when:** + +1. The user explicitly asks about a future, concept, preview, beta, or roadmap topic, OR +2. No answer exists in the `Product` surface AND a Kosli Next page is directly relevant. + +**Never** answer a "how do I do X today" question using a Kosli Next page without the disclaimer below. + +## Disclaimer when citing Kosli Next + +Every answer that draws on a page under `kosli_next/` must begin with one of: + +- For Concepts: *"This isn't available in Kosli today - it's a concept we're sharing to gather feedback."* +- For Previews: *"This is a preview feature, available to opt-in customers. Behaviour can still change."* + +End the answer with an invitation to share feedback at `support@kosli.com`. + +## When writing documentation + +These rules apply to any documentation you author or edit, including via the `@Mintlify` Slack bot. + +### Where things go + +- Features generally available today → main docs under `understand_kosli/`, `getting_started/`, `administration/`, `integrations/`, `tutorials/`, `troubleshooting/`, `client_reference/`, etc. +- Ideas not built yet → `kosli_next/concepts/.mdx` with `tag: "Concept"` and the `` from `/snippets/kosli-next-banner.mdx`. +- Opt-in pre-GA features → `kosli_next/preview/.mdx` with `tag: "Preview"` and the `` from `/snippets/kosli-next-banner.mdx`. + +Every new page must be registered in `config/navigation.json` under the matching Product and tab. + +### Required Kosli Next page shape + +```mdx +--- +title: "Short, specific title" +description: "One sentence describing the page purpose." +tag: "Concept" # or "Preview" +--- + +import { ConceptBanner } from '/snippets/kosli-next-banner.mdx'; + + + +Page content here. +``` + +Do not inline a custom disclaimer. The banner snippet is the single source of truth so the feedback channel can be swapped later without editing every page. + +For Concept pages, write in the conditional ("Kosli would report X..."), not the present tense, so readers are not misled into thinking the feature exists. + +### Style and tone + +- Refer to the product as **Kosli** - never "the Kosli platform" or "KOSLI". +- Use "audit trail" not "audit log"; "attest" not "certify". +- Active voice and imperative mood for instructions ("Run `kosli attest`", not "You should run"). +- Sentence case for all headings. +- Root-relative internal links only (`/getting_started/install`, not `../install`). +- No em-dashes. Use hyphens or rewrite the sentence. + +### MDX components + +Prefer the components already in use in this repo: + +- `` / `` for sequential procedures. +- `` / `` for platform-specific alternatives. +- `` / `` / `` for navigational tiles. +- `` / `` for progressive disclosure. +- `` / `` / `` / `` for callouts, sparingly. +- `` for the same command in multiple languages. +- `` for wrapping images. + +### Do not + +- Do not edit pages under `essentials/` - they are Mintlify's own content, not Kosli's. +- Do not add new snippets unless the content is genuinely reused in 2+ pages. +- Do not propose changes that bypass `config/navigation.json` - pages not in nav do not appear on the site. + +## Reference + +- Writer skill (for Claude in the repo): `.claude/skills/kosli-next-writer/SKILL.md` +- Project conventions: `CLAUDE.md` diff --git a/CLAUDE.md b/CLAUDE.md index 6d3d64a..7675304 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,11 +4,11 @@ This file governs repo-specific conventions for Claude Code. Skills and system p ## Core rules -These are non-negotiable — follow them regardless of other instructions: +These are non-negotiable - follow them regardless of other instructions: -1. Never commit directly to `main` — always work on a branch and open a PR. +1. Never commit directly to `main` - always work on a branch and open a PR. 2. Never create a page file without also adding it to `navigation` in `config/navigation.json`. -3. Never use relative links — always use root-relative paths (e.g., `/getting_started/install`). +3. Never use relative links - always use root-relative paths (e.g., `/getting_started/install`). 4. Commit messages and PR titles must follow [Conventional Commits](https://www.conventionalcommits.org/): `type: short description` (lowercase, no period). Common types: `feat`, `fix`, `docs`, `style`, `chore`. 5. Run `mint broken-links` before committing navigation or link changes. @@ -31,13 +31,13 @@ Requires Node.js v19+. ## Architecture -- **`docs.json`** — Central config: theme, API settings, logos. Uses `$ref` to compose from files in `config/`. -- **`config/`** — Split config files: `navigation.json` (all page routing), `redirects.json`, `footer.json`. -- **Content directories** — `understand_kosli/`, `getting_started/`, `administration/`, `integrations/`, `implementation_guide/`, `client_reference/`, `api-reference/` -- **`snippets/`** — Reusable MDX content fragments -- **`style.css`** — Custom CSS overrides applied on top of the Mintlify theme -- **`api-reference/openapi.json`** — OpenAPI spec for Kosli API endpoints -- **`essentials/`** — Mintlify's own getting-started guide, kept as a reference. Do not edit or link to these pages in Kosli navigation. +- **`docs.json`** - Central config: theme, API settings, logos. Uses `$ref` to compose from files in `config/`. +- **`config/`** - Split config files: `navigation.json` (all page routing), `redirects.json`, `footer.json`. +- **Content directories** - `understand_kosli/`, `getting_started/`, `administration/`, `integrations/`, `implementation_guide/`, `client_reference/`, `api-reference/` +- **`snippets/`** - Reusable MDX content fragments +- **`style.css`** - Custom CSS overrides applied on top of the Mintlify theme +- **`api-reference/openapi.json`** - OpenAPI spec for Kosli API endpoints +- **`essentials/`** - Mintlify's own getting-started guide, kept as a reference. Do not edit or link to these pages in Kosli navigation. ## Content Conventions @@ -50,13 +50,13 @@ description: One sentence describing the page purpose. --- ``` -- **MUST** Use root-relative paths for internal links: `/understand_kosli/what_is_kosli` ✓ — `../what_is_kosli` ✗ +- **MUST** Use root-relative paths for internal links: `/understand_kosli/what_is_kosli` ✓ - `../what_is_kosli` ✗ - **MUST** Adding a new page: create the file AND add its path to `navigation` in `config/navigation.json`. Both steps are required. - **SHOULD** Follow the [Diátaxis](https://diataxis.fr/) framework when choosing page form: - - **Tutorial** — teaches by doing (e.g., "Get familiar with Kosli") - - **How-to guide** — step-by-step for a specific goal (e.g., "Report AWS environments") - - **Reference** — factual, lookup-oriented (e.g., CLI reference pages) - - **Explanation** — concepts and background (e.g., "What is Kosli?") + - **Tutorial** - teaches by doing (e.g., "Get familiar with Kosli") + - **How-to guide** - step-by-step for a specific goal (e.g., "Report AWS environments") + - **Reference** - factual, lookup-oriented (e.g., CLI reference pages) + - **Explanation** - concepts and background (e.g., "What is Kosli?") - **MAY** Add an `icon` field to front matter using [Font Awesome](https://fontawesome.com/icons) names. ### MDX Components @@ -67,32 +67,34 @@ description: One sentence describing the page purpose. | `` / `` | Platform-specific or alternative content | | `` / `` | Navigational links, feature highlights | | `` / `` | Progressive disclosure, FAQs | -| `` / `` / `` / `` | Callouts — use sparingly | +| `` / `` / `` / `` | Callouts - use sparingly | | `` | Same command in multiple languages/tools | | `` | Wrapping images | ### Writing style - Use active voice and imperative mood for instructions ("Run `kosli attest`", not "You should run"). -- Refer to the product as **Kosli** — not "the Kosli platform" or "KOSLI". +- Refer to the product as **Kosli** - not "the Kosli platform" or "KOSLI". - Use "audit trail" not "audit log"; "attest" not "certify". - Sentence case for all headings. +- No em-dashes. Use hyphens or rewrite the sentence. ## Don'ts -- Don't use relative links — they break when pages move. -- Don't create a page without updating `config/navigation.json` — it won't appear in the site. -- Don't edit files in `essentials/` — they are Mintlify's content, not Kosli's. +- Don't use relative links - they break when pages move. +- Don't create a page without updating `config/navigation.json` - it won't appear in the site. +- Don't edit files in `essentials/` - they are Mintlify's content, not Kosli's. - Don't add content to `snippets/` unless it is genuinely reused in 2+ pages. - Don't commit image files without placing them in an appropriate subdirectory. -- Don't push to `main` directly — always use a PR. +- Don't push to `main` directly - always use a PR. ## Skills When available, prefer skills over ad-hoc approaches: -- **PR creation** — use the `pr-creator` skill if available. -- **Changelog entries** — use the `changelog-creator` skill if available. Follow the existing `` format in `changelog/index.mdx` exactly: +- **Kosli Next writing** - for any docs work under `kosli_next/` (concepts and preview features), use the `kosli-next-writer` skill in `.claude/skills/kosli-next-writer/`. It covers file locations, the required banner snippet, navigation updates, and tone. +- **PR creation** - use the `pr-creator` skill if available. +- **Changelog entries** - use the `changelog-creator` skill if available. Follow the existing `` format in `changelog/index.mdx` exactly: ```mdx diff --git a/config/footer.json b/config/footer.json index 825e68e..c0b26ae 100644 --- a/config/footer.json +++ b/config/footer.json @@ -25,6 +25,10 @@ "label": "Labs", "href": "/labs" }, + { + "label": "Kosli Next", + "href": "/kosli_next/index" + }, { "label": "Blog", "href": "https://kosli.com/blog/" diff --git a/config/navigation.json b/config/navigation.json index d180b07..0ecb059 100644 --- a/config/navigation.json +++ b/config/navigation.json @@ -1,472 +1,505 @@ { - "tabs": [ + "products": [ { - "tab": "Documentation", - "groups": [ - { - "group": "Understand Kosli", - "icon": "book-open", - "pages": [ - "understand_kosli/what_is_kosli", - "understand_kosli/risks", - "understand_kosli/controls", - "understand_kosli/how_kosli_works", - "understand_kosli/glossary", - "understand_kosli/ai_docs_access" - ] - }, - { - "group": "Getting started", - "icon": "rocket", - "pages": [ - "getting_started/install", - "getting_started/service-accounts", - "getting_started/flows", - "getting_started/trails", - "getting_started/artifacts", - "getting_started/attestations", - "getting_started/environments", - "getting_started/policies", - "getting_started/enforce_policies", - "getting_started/approvals" - ] - }, + "product": "Product", + "description": "Documentation for Kosli as it exists today.", + "tabs": [ { - "group": "Administration", - "icon": "cog", - "pages": [ - { - "group": "Managing Users", - "pages": [ - "administration/managing_users/roles_in_kosli" - ] - }, - { - "group": "Managing Environments", - "pages": [ - "administration/managing_environments/overview" - ] - }, + "tab": "Documentation", + "groups": [ { - "group": "Managing Custom Attestation Types", + "group": "Understand Kosli", + "icon": "book-open", "pages": [ - "administration/managing_custom_attestation_types/overview" + "understand_kosli/what_is_kosli", + "understand_kosli/risks", + "understand_kosli/controls", + "understand_kosli/how_kosli_works", + "understand_kosli/glossary", + "understand_kosli/ai_docs_access" ] }, - "administration/managing_tags" - ] - }, - { - "group": "Tutorials", - "icon": "graduation-cap", - "pages": [ { "group": "Getting started", - "pages": [ - "tutorials/try_kosli_locally", - "tutorials/cli_and_http_proxy", - "tutorials/organizing_with_spaces" + "icon": "rocket", + "pages": [ + "getting_started/install", + "getting_started/service-accounts", + "getting_started/flows", + "getting_started/trails", + "getting_started/artifacts", + "getting_started/attestations", + "getting_started/environments", + "getting_started/policies", + "getting_started/enforce_policies", + "getting_started/approvals" ] }, { - "group": "Attesting", + "group": "Administration", + "icon": "cog", "pages": [ - "tutorials/attest_snyk", - "tutorials/custom-attestation-ctrf", - "tutorials/attest_large_documents" - ] - }, - { - "group": "Reporting environments", - "pages": [ - "tutorials/report_aws_envs", - "tutorials/report_k8s_envs", - "tutorials/report_cloud_run_envs" - ] - }, - { - "group": "Querying & tracing", - "pages": [ - "tutorials/querying_kosli", - "tutorials/following_a_git_commit_to_runtime_environments", - "tutorials/tracing_a_production_incident_back_to_git_commits" + { + "group": "Managing Users", + "pages": [ + "administration/managing_users/roles_in_kosli" + ] + }, + { + "group": "Managing Environments", + "pages": [ + "administration/managing_environments/overview" + ] + }, + { + "group": "Managing Custom Attestation Types", + "pages": [ + "administration/managing_custom_attestation_types/overview" + ] + }, + "administration/managing_tags" ] }, { - "group": "Security", + "group": "Tutorials", + "icon": "graduation-cap", "pages": [ - "tutorials/unauthorized_iac_changes" + { + "group": "Getting started", + "pages": [ + "tutorials/try_kosli_locally", + "tutorials/cli_and_http_proxy", + "tutorials/organizing_with_spaces" + ] + }, + { + "group": "Attesting", + "pages": [ + "tutorials/attest_snyk", + "tutorials/custom-attestation-ctrf", + "tutorials/attest_large_documents" + ] + }, + { + "group": "Reporting environments", + "pages": [ + "tutorials/report_aws_envs", + "tutorials/report_k8s_envs", + "tutorials/report_cloud_run_envs" + ] + }, + { + "group": "Querying & tracing", + "pages": [ + "tutorials/querying_kosli", + "tutorials/following_a_git_commit_to_runtime_environments", + "tutorials/tracing_a_production_incident_back_to_git_commits" + ] + }, + { + "group": "Security", + "pages": [ + "tutorials/unauthorized_iac_changes" + ] + }, + { + "group": "Evaluation", + "pages": [ + "tutorials/evaluate_trails_with_opa" + ] + }, + { + "group": "Multi-flow workflows", + "pages": [ + "tutorials/linking_trails_across_branches" + ] + }, + { + "group": "Repositories", + "pages": [ + "tutorials/repositories" + ] + } ] }, { - "group": "Evaluation", + "group": "Troubleshooting", + "icon": "wrench", "pages": [ - "tutorials/evaluate_trails_with_opa" + "troubleshooting/what_do_i_do_if_kosli_is_down", + "troubleshooting/docker_api_version_error", + "troubleshooting/repo_digest_unavailable", + "troubleshooting/zsh_no_such_user", + "troubleshooting/github_kosli_api_token", + "troubleshooting/subshell_stderr", + "troubleshooting/whitespace_path" ] }, { - "group": "Multi-flow workflows", + "group": "FAQ", + "icon": "circle-question", "pages": [ - "tutorials/linking_trails_across_branches" + "faq/faq" ] }, { - "group": "Repositories", + "group": "Integrations", + "icon": "puzzle-piece", "pages": [ - "tutorials/repositories" + "integrations/actions", + "integrations/ci_cd", + "integrations/slack", + "integrations/launchdarkly", + "integrations/sonar" ] } ] }, { - "group": "Troubleshooting", - "icon": "wrench", - "pages": [ - "troubleshooting/what_do_i_do_if_kosli_is_down", - "troubleshooting/docker_api_version_error", - "troubleshooting/repo_digest_unavailable", - "troubleshooting/zsh_no_such_user", - "troubleshooting/github_kosli_api_token", - "troubleshooting/subshell_stderr", - "troubleshooting/whitespace_path" - ] - }, - { - "group": "FAQ", - "icon": "circle-question", - "pages": [ - "faq/faq" - ] - }, - { - "group": "Integrations", - "icon": "puzzle-piece", - "pages": [ - "integrations/actions", - "integrations/ci_cd", - "integrations/slack", - "integrations/launchdarkly", - "integrations/sonar" - ] - } - ] - }, - { - "tab": "Labs", - "groups": [ - { - "group": "Kosli Learning Labs", - "pages": [ - "labs/index", - "labs/lab-01-get-ready", - "labs/lab-02-flows-and-trails", - "labs/lab-03-build-controls", - "labs/lab-04-release-controls", - "labs/lab-05-runtime-controls" - ] - } - ] - }, - { - "tab": "Implementation Guide", - "groups": [ - { - "group": "Phase 1: Initial Discovery", - "icon": "lightbulb", - "pages": [ + "tab": "Labs", + "groups": [ { - "group": "Roles & Responsibilities", + "group": "Kosli Learning Labs", "pages": [ - "implementation_guide/phase_1/roles_and_responsibilities/overview", - "implementation_guide/phase_1/roles_and_responsibilities/platform_engineers", - "implementation_guide/phase_1/roles_and_responsibilities/app_developers", - "implementation_guide/phase_1/roles_and_responsibilities/security_compliance", - "implementation_guide/phase_1/roles_and_responsibilities/sponsors" + "labs/index", + "labs/lab-01-get-ready", + "labs/lab-02-flows-and-trails", + "labs/lab-03-build-controls", + "labs/lab-04-release-controls", + "labs/lab-05-runtime-controls" ] } ] }, { - "group": "Phase 2: Configure Kosli", - "icon": "gear", - "pages": [ + "tab": "Implementation Guide", + "groups": [ { - "group": "Plan Organizational Structure", + "group": "Phase 1: Initial Discovery", + "icon": "lightbulb", "pages": [ { - "group": "Naming Conventions", + "group": "Roles & Responsibilities", "pages": [ - "implementation_guide/phase_2/plan_organizational_structure/naming_conventions/overview", - "implementation_guide/phase_2/plan_organizational_structure/naming_conventions/attestation_types", - "implementation_guide/phase_2/plan_organizational_structure/naming_conventions/flows_and_trails" + "implementation_guide/phase_1/roles_and_responsibilities/overview", + "implementation_guide/phase_1/roles_and_responsibilities/platform_engineers", + "implementation_guide/phase_1/roles_and_responsibilities/app_developers", + "implementation_guide/phase_1/roles_and_responsibilities/security_compliance", + "implementation_guide/phase_1/roles_and_responsibilities/sponsors" ] } ] - } - ] - } - ] - }, - { - "tab": "Reference", - "menu": [ - { - "item": "CLI Reference", - "icon": "terminal", - "groups": [ - { - "group": "General", - "pages": [ - "client_reference/overview", - "client_reference/kosli", - "client_reference/kosli_attach-policy", - "client_reference/kosli_completion", - "client_reference/kosli_config", - "client_reference/kosli_detach-policy", - "client_reference/kosli_fingerprint", - "client_reference/kosli_search", - "client_reference/kosli_status", - "client_reference/kosli_tag", - "client_reference/kosli_version" - ] - }, - { - "group": "kosli allow", - "pages": [ - "client_reference/kosli_allow_artifact" - ] - }, - { - "group": "kosli archive", - "pages": [ - "client_reference/kosli_archive_attestation-type", - "client_reference/kosli_archive_environment", - "client_reference/kosli_archive_flow" - ] - }, - { - "group": "kosli assert", - "pages": [ - "client_reference/kosli_assert_artifact", - "client_reference/kosli_assert_pullrequest_azure", - "client_reference/kosli_assert_pullrequest_bitbucket", - "client_reference/kosli_assert_pullrequest_github", - "client_reference/kosli_assert_pullrequest_gitlab", - "client_reference/kosli_assert_snapshot", - "client_reference/kosli_assert_status" - ] - }, - { - "group": "kosli attest", - "pages": [ - "client_reference/kosli_attest_artifact", - "client_reference/kosli_attest_custom", - "client_reference/kosli_attest_generic", - "client_reference/kosli_attest_jira", - "client_reference/kosli_attest_junit", - "client_reference/kosli_attest_pullrequest_azure", - "client_reference/kosli_attest_pullrequest_bitbucket", - "client_reference/kosli_attest_pullrequest_github", - "client_reference/kosli_attest_pullrequest_gitlab", - "client_reference/kosli_attest_snyk", - "client_reference/kosli_attest_sonar" - ] }, { - "group": "kosli begin", + "group": "Phase 2: Configure Kosli", + "icon": "gear", "pages": [ - "client_reference/kosli_begin_trail" - ] - }, - { - "group": "kosli create", - "pages": [ - "client_reference/kosli_create_attestation-type", - "client_reference/kosli_create_environment", - "client_reference/kosli_create_flow", - "client_reference/kosli_create_policy" - ] - }, - { - "group": "kosli diff", - "pages": [ - "client_reference/kosli_diff_snapshots" - ] - }, - { - "group": "kosli disable / enable", - "pages": [ - "client_reference/kosli_disable_beta", - "client_reference/kosli_enable_beta" - ] - }, - { - "group": "kosli evaluate", - "pages": [ - "client_reference/kosli_evaluate_input", - "client_reference/kosli_evaluate_trail", - "client_reference/kosli_evaluate_trails" - ] - }, - { - "group": "kosli get", - "pages": [ - "client_reference/kosli_get_artifact", - "client_reference/kosli_get_attestation-type", - "client_reference/kosli_get_attestation", - "client_reference/kosli_get_environment", - "client_reference/kosli_get_flow", - "client_reference/kosli_get_policy", - "client_reference/kosli_get_snapshot", - "client_reference/kosli_get_trail" + { + "group": "Plan Organizational Structure", + "pages": [ + { + "group": "Naming Conventions", + "pages": [ + "implementation_guide/phase_2/plan_organizational_structure/naming_conventions/overview", + "implementation_guide/phase_2/plan_organizational_structure/naming_conventions/attestation_types", + "implementation_guide/phase_2/plan_organizational_structure/naming_conventions/flows_and_trails" + ] + } + ] + } ] - }, + } + ] + }, + { + "tab": "Reference", + "menu": [ { - "group": "kosli join", - "pages": [ - "client_reference/kosli_join_environment" + "item": "CLI Reference", + "icon": "terminal", + "groups": [ + { + "group": "General", + "pages": [ + "client_reference/overview", + "client_reference/kosli", + "client_reference/kosli_attach-policy", + "client_reference/kosli_completion", + "client_reference/kosli_config", + "client_reference/kosli_detach-policy", + "client_reference/kosli_fingerprint", + "client_reference/kosli_search", + "client_reference/kosli_status", + "client_reference/kosli_tag", + "client_reference/kosli_version" + ] + }, + { + "group": "kosli allow", + "pages": [ + "client_reference/kosli_allow_artifact" + ] + }, + { + "group": "kosli archive", + "pages": [ + "client_reference/kosli_archive_attestation-type", + "client_reference/kosli_archive_environment", + "client_reference/kosli_archive_flow" + ] + }, + { + "group": "kosli assert", + "pages": [ + "client_reference/kosli_assert_artifact", + "client_reference/kosli_assert_pullrequest_azure", + "client_reference/kosli_assert_pullrequest_bitbucket", + "client_reference/kosli_assert_pullrequest_github", + "client_reference/kosli_assert_pullrequest_gitlab", + "client_reference/kosli_assert_snapshot", + "client_reference/kosli_assert_status" + ] + }, + { + "group": "kosli attest", + "pages": [ + "client_reference/kosli_attest_artifact", + "client_reference/kosli_attest_custom", + "client_reference/kosli_attest_generic", + "client_reference/kosli_attest_jira", + "client_reference/kosli_attest_junit", + "client_reference/kosli_attest_pullrequest_azure", + "client_reference/kosli_attest_pullrequest_bitbucket", + "client_reference/kosli_attest_pullrequest_github", + "client_reference/kosli_attest_pullrequest_gitlab", + "client_reference/kosli_attest_snyk", + "client_reference/kosli_attest_sonar" + ] + }, + { + "group": "kosli begin", + "pages": [ + "client_reference/kosli_begin_trail" + ] + }, + { + "group": "kosli create", + "pages": [ + "client_reference/kosli_create_attestation-type", + "client_reference/kosli_create_environment", + "client_reference/kosli_create_flow", + "client_reference/kosli_create_policy" + ] + }, + { + "group": "kosli diff", + "pages": [ + "client_reference/kosli_diff_snapshots" + ] + }, + { + "group": "kosli disable / enable", + "pages": [ + "client_reference/kosli_disable_beta", + "client_reference/kosli_enable_beta" + ] + }, + { + "group": "kosli evaluate", + "pages": [ + "client_reference/kosli_evaluate_input", + "client_reference/kosli_evaluate_trail", + "client_reference/kosli_evaluate_trails" + ] + }, + { + "group": "kosli get", + "pages": [ + "client_reference/kosli_get_artifact", + "client_reference/kosli_get_attestation-type", + "client_reference/kosli_get_attestation", + "client_reference/kosli_get_environment", + "client_reference/kosli_get_flow", + "client_reference/kosli_get_policy", + "client_reference/kosli_get_snapshot", + "client_reference/kosli_get_trail" + ] + }, + { + "group": "kosli join", + "pages": [ + "client_reference/kosli_join_environment" + ] + }, + { + "group": "kosli list", + "pages": [ + "client_reference/kosli_list_artifacts", + "client_reference/kosli_list_attestation-types", + "client_reference/kosli_list_environments", + "client_reference/kosli_list_flows", + "client_reference/kosli_list_policies", + "client_reference/kosli_list_snapshots", + "client_reference/kosli_list_trails" + ] + }, + { + "group": "kosli log", + "pages": [ + "client_reference/kosli_log_environment" + ] + }, + { + "group": "kosli rename", + "pages": [ + "client_reference/kosli_rename_environment", + "client_reference/kosli_rename_flow" + ] + }, + { + "group": "kosli snapshot", + "pages": [ + "client_reference/kosli_snapshot_azure", + "client_reference/kosli_snapshot_cloud-run", + "client_reference/kosli_snapshot_docker", + "client_reference/kosli_snapshot_ecs", + "client_reference/kosli_snapshot_k8s", + "client_reference/kosli_snapshot_lambda", + "client_reference/kosli_snapshot_path", + "client_reference/kosli_snapshot_paths", + "client_reference/kosli_snapshot_s3" + ] + }, + { + "group": "Deprecated", + "pages": [ + "client_reference/kosli_assert_approval", + "client_reference/kosli_get_approval", + "client_reference/kosli_list_approvals", + "client_reference/kosli_report_approval", + "client_reference/kosli_report_artifact", + "client_reference/kosli_request_approval", + "client_reference/kosli_snapshot_server" + ] + } ] }, { - "group": "kosli list", - "pages": [ - "client_reference/kosli_list_artifacts", - "client_reference/kosli_list_attestation-types", - "client_reference/kosli_list_environments", - "client_reference/kosli_list_flows", - "client_reference/kosli_list_policies", - "client_reference/kosli_list_snapshots", - "client_reference/kosli_list_trails" + "item": "Template Reference", + "icon": "file-code", + "groups": [ + { + "group": "Templates", + "pages": [ + "template-reference/flow_template" + ] + } ] }, { - "group": "kosli log", - "pages": [ - "client_reference/kosli_log_environment" + "item": "Policy Reference", + "icon": "scroll", + "groups": [ + { + "group": "Policies", + "pages": [ + "policy-reference/environment_policy", + "policy-reference/rego_policy" + ] + } ] }, { - "group": "kosli rename", - "pages": [ - "client_reference/kosli_rename_environment", - "client_reference/kosli_rename_flow" - ] + "item": "API Reference", + "icon": "code", + "openapi": "https://app.kosli.com/api/v2/openapi.json" }, { - "group": "kosli snapshot", - "pages": [ - "client_reference/kosli_snapshot_azure", - "client_reference/kosli_snapshot_cloud-run", - "client_reference/kosli_snapshot_docker", - "client_reference/kosli_snapshot_ecs", - "client_reference/kosli_snapshot_k8s", - "client_reference/kosli_snapshot_lambda", - "client_reference/kosli_snapshot_path", - "client_reference/kosli_snapshot_paths", - "client_reference/kosli_snapshot_s3" + "item": "Helm Reference", + "icon": "layer-group", + "groups": [ + { + "group": "Helm Charts", + "pages": [ + "helm/k8s_reporter" + ] + } ] }, { - "group": "Deprecated", - "pages": [ - "client_reference/kosli_assert_approval", - "client_reference/kosli_get_approval", - "client_reference/kosli_list_approvals", - "client_reference/kosli_report_approval", - "client_reference/kosli_report_artifact", - "client_reference/kosli_request_approval", - "client_reference/kosli_snapshot_server" + "item": "Terraform Reference", + "icon": "cubes", + "groups": [ + { + "group": "Provider", + "pages": [ + "terraform-reference/index" + ] + }, + { + "group": "Resources", + "pages": [ + "terraform-reference/resources/environment", + "terraform-reference/resources/logical_environment", + "terraform-reference/resources/flow", + "terraform-reference/resources/custom_attestation_type", + "terraform-reference/resources/action", + "terraform-reference/resources/policy", + "terraform-reference/resources/policy_attachment" + ] + }, + { + "group": "Data Sources", + "pages": [ + "terraform-reference/data-sources/environment", + "terraform-reference/data-sources/logical_environment", + "terraform-reference/data-sources/flow", + "terraform-reference/data-sources/custom_attestation_type", + "terraform-reference/data-sources/action", + "terraform-reference/data-sources/policy" + ] + } ] } ] }, { - "item": "Template Reference", - "icon": "file-code", + "tab": "Changelog", + "icon": "clock", "groups": [ { - "group": "Templates", + "group": "Changelog", "pages": [ - "template-reference/flow_template" + "changelog/index" ] } ] - }, + } + ] + }, + { + "product": "Kosli Next", + "description": "Concepts and preview features we're exploring with customers.", + "groups": [ { - "item": "Policy Reference", - "icon": "scroll", - "groups": [ - { - "group": "Policies", - "pages": [ - "policy-reference/environment_policy", - "policy-reference/rego_policy" - ] - } + "group": "Kosli Next", + "icon": "compass", + "pages": [ + "kosli_next/index" ] }, { - "item": "API Reference", - "icon": "code", - "openapi": "https://app.kosli.com/api/v2/openapi.json" - }, - { - "item": "Helm Reference", - "icon": "layer-group", - "groups": [ - { - "group": "Helm Charts", - "pages": [ - "helm/k8s_reporter" - ] - } + "group": "Concepts", + "icon": "lightbulb", + "pages": [ + "kosli_next/concepts/controls" ] }, { - "item": "Terraform Reference", - "icon": "cubes", - "groups": [ - { - "group": "Provider", - "pages": [ - "terraform-reference/index" - ] - }, - { - "group": "Resources", - "pages": [ - "terraform-reference/resources/environment", - "terraform-reference/resources/logical_environment", - "terraform-reference/resources/flow", - "terraform-reference/resources/custom_attestation_type", - "terraform-reference/resources/action", - "terraform-reference/resources/policy", - "terraform-reference/resources/policy_attachment" - ] - }, - { - "group": "Data Sources", - "pages": [ - "terraform-reference/data-sources/environment", - "terraform-reference/data-sources/logical_environment", - "terraform-reference/data-sources/flow", - "terraform-reference/data-sources/custom_attestation_type", - "terraform-reference/data-sources/action", - "terraform-reference/data-sources/policy" - ] - } - ] - } - ] - }, - { - "tab": "Changelog", - "icon": "clock", - "groups": [ - { - "group": "Changelog", + "group": "Preview", + "icon": "flask", "pages": [ - "changelog/index" + "kosli_next/preview/mcp_server" ] } ] diff --git a/images/kosli_next/controls/controls-compliance-coverage.png b/images/kosli_next/controls/controls-compliance-coverage.png new file mode 100644 index 0000000..e67dbe1 Binary files /dev/null and b/images/kosli_next/controls/controls-compliance-coverage.png differ diff --git a/images/kosli_next/controls/controls-compliance-deployments.png b/images/kosli_next/controls/controls-compliance-deployments.png new file mode 100644 index 0000000..db50bc6 Binary files /dev/null and b/images/kosli_next/controls/controls-compliance-deployments.png differ diff --git a/images/kosli_next/controls/controls-decisions.png b/images/kosli_next/controls/controls-decisions.png new file mode 100644 index 0000000..d559013 Binary files /dev/null and b/images/kosli_next/controls/controls-decisions.png differ diff --git a/images/kosli_next/controls/controls-list.png b/images/kosli_next/controls/controls-list.png new file mode 100644 index 0000000..0145238 Binary files /dev/null and b/images/kosli_next/controls/controls-list.png differ diff --git a/images/kosli_next/index/kosli-next-dark.png b/images/kosli_next/index/kosli-next-dark.png new file mode 100644 index 0000000..91686f7 Binary files /dev/null and b/images/kosli_next/index/kosli-next-dark.png differ diff --git a/images/kosli_next/index/kosli-next-light.png b/images/kosli_next/index/kosli-next-light.png new file mode 100644 index 0000000..8ce2c00 Binary files /dev/null and b/images/kosli_next/index/kosli-next-light.png differ diff --git a/kosli_next/concepts/controls.mdx b/kosli_next/concepts/controls.mdx new file mode 100644 index 0000000..c61b82c --- /dev/null +++ b/kosli_next/concepts/controls.mdx @@ -0,0 +1,184 @@ +--- +title: "Controls" +description: "A proposed model for representing governance controls as first-class entities in Kosli, with decisions recorded against them." +tag: "Concept" +--- + +import { ConceptBanner } from '/snippets/kosli-next-banner.mdx'; + + + +## The problem + +Today, Kosli can tell you _that_ an attestation was made on a trail, but not _which governance requirement it satisfies_. Auditors, compliance teams, and governance engineers think in terms of named controls - "source code review", "no hard-coded credentials", "vulnerability scan passed" - and they want to answer questions like: + +- Which of our controls have evidence recorded against them, and which don't? +- For this release, which controls passed and which failed? +- How much of our production estate is covered by control `RCTL-1866`? + +Right now, those questions are hard to answer in Kosli without bespoke reporting on top of raw attestations. + +## The proposed approach + +We are considering adding **controls** as first-class entities in Kosli. A control would be a stable, named governance requirement - mirrored from your existing controls catalog in ServiceNow, a GRC system, or a policy document. Pipelines would record **decisions** against controls, and environment policies would reference controls by identifier. + +Three new building blocks would sit alongside the existing data model: + +- **Raw fact attestations** (unchanged) are the evidence you collect in pipelines: test results, vulnerability scans, pull request approvals. +- **Decisions** are recorded outcomes of a Policy Decision Point (PDP) - the moment a judgement is reached about a specific control for a specific artifact. A decision would be an attestation that references a control. +- **Controls** are the named governance requirements that decisions are recorded against. They would have a stable identifier, a human-readable name, and an optional description and source URL pointing back to the authoritative definition. + +Raw facts would continue to exist independently of controls. A JUnit report is a fact. Whether it satisfies a "test coverage" control would be a decision. The decision references the fact; the fact would not need to know about the control. + +Kosli would hold a mirror to your existing control definitions - it would not replace your GRC system. The catalog in Kosli would be a lightweight copy that enables querying and coverage visibility. + +## How it would work + +The walkthrough below is **illustrative**. CLI flags, YAML schema, and UI shown here are sketches to make the proposal concrete - they are not implemented and the shapes will change based on feedback. + +### Defining a control + +A control would be created from the Kosli app or the CLI, mirroring an entry in your existing catalog: + +```bash +kosli create control \ + --identifier RCTL-043 \ + --name "Source code review" \ + --description "All commits included in a release must have been reviewed by at least one person other than the author." \ + --source-url https://your-grc-system.example.com/controls/RCTL-043 +``` + +The **identifier** would be the stable identity (immutable once created); name, description, and source URL would be mutable and versioned, so the audit trail stays precise as controls evolve. + +The catalog view would surface a **coverage indicator** per control: + +| Status | Meaning | +|--------|---------| +| **Active** | A passing decision has been recorded within the last 28 days. | +| **Stale** | Decisions in the past, but none in the last 28 days - pipelines may have stopped recording against this control. | +| **No decisions** | Defined in the catalog, but no decision ever recorded. A dark control. | + + + Controls catalog showing Active, Stale, and No decisions coverage indicators alongside version badges and an expanded version history for RCTL-043 + + +### Recording a decision + +A decision would record the outcome of a PDP against a named control, scoped to a specific artifact: + +```bash +kosli attest decision \ + --flow my-release-flow \ + --trail my-release-trail \ + --fingerprint "$ARTIFACT_FINGERPRINT" \ + --control RCTL-043 \ + --compliant true \ + --name "source-code-review-decision" \ + --description "All 14 commits in this release have been reviewed by a second developer." +``` + +The decision attestation would land on a trail like any other attestation and affect trail compliance. The PDP itself - whether you run `kosli evaluate` with a Rego policy, a bespoke script, or a third-party tool - would remain entirely yours. `kosli attest decision` would record the outcome; it would not make the decision for you. + +A natural pairing is `kosli evaluate`, which already runs Rego policies against trail evidence. Its JSON output could be captured and recorded as the decision, with the policy and report attached as evidence: + +```bash +kosli evaluate trail "$TRAIL_NAME" \ + --policy supply-chain-policy.rego \ + --org "$KOSLI_ORG" \ + --flow "$FLOW_NAME" \ + --output json > eval-report.json + +is_compliant=$(jq -r '.allow' eval-report.json) + +kosli attest decision \ + --flow "$FLOW_NAME" \ + --trail "$TRAIL_NAME" \ + --fingerprint "$ARTIFACT_FINGERPRINT" \ + --control RCTL-1866 \ + --compliant="$is_compliant" \ + --name supply-chain-integrity-decision \ + --attachments supply-chain-policy.rego,eval-report.json +``` + +### Referencing controls in environment policies + +Environment policies would gain a `controls` key. Instead of expressing requirements in tooling-specific terms ("has a Snyk attestation with zero criticals"), the policy would express the governance outcome ("control `RCTL-1866` has been satisfied"). The decision attestation would carry the evidence of how that judgement was reached. + +```yaml prod-policy.yaml +_schema: https://docs.kosli.com/schemas/policy/v1 +artifacts: + provenance: + required: true + controls: + - RCTL-043 + - RCTL-1866 +``` + +An artifact deployed to this environment would be marked non-compliant if a passing decision is missing for any listed control. The Policy Enforcement Point (PEP) would be `kosli assert artifact --environment`, used in a pipeline step to gate promotion on control compliance. + +### The end-to-end flow + +The sequence below shows how a single artifact would move through a build trail and a release trail, with the decision made at release time and enforced when the release controller checks the environment policy. + +```mermaid +sequenceDiagram + participant P as Pipeline + participant K as Kosli + + rect rgb(220,235,255) + Note over P,K: Build trail + P->>K: kosli begin trail build-123 --flow my-app + P->>K: kosli attest pullrequest github ... + P->>K: kosli attest artifact artifact-a ... + end + + rect rgb(255,235,215) + Note over P,K: Release trail + P->>K: kosli begin trail release-456 --flow my-release + Note right of P: PDP - evaluate RCTL-043 + P->>K: kosli evaluate trail release-456 --policy rctl-043.rego --output json + K-->>P: eval-report.json + P->>K: kosli attest decision --control RCTL-043 --compliant $IS_COMPLIANT ... + end + + rect rgb(220,255,220) + Note over P,K: Release controller + Note right of P: PEP - assert against environment policy + P->>K: kosli assert artifact --fingerprint $FP_A --environment production + K-->>P: exit 0 + end +``` + +### Viewing compliance + +A per-control detail view would show three perspectives: + +**Decisions** - every decision attestation recorded against this control, with artifact, flow, trail, environment, recorded-by, date, outcome, and which version of the control definition was in effect. + + + Decisions tab for RCTL-043 listing decision attestations with artifact, flow, trail, environment, recorder, date, and compliant/non-compliant outcome + + +**Deployments** - where artifacts with decisions against this control have been deployed, with compliant/non-compliant status per deployment. + + + Deployments tab for RCTL-043 showing deployments with compliant and non-compliant decisions + + +**Coverage** - the ratio of deployments where a decision was recorded vs. those where it was not. Controls without decisions would be the blind spots auditors will ask about. + + + Coverage tab for RCTL-043 showing decision recorded vs. no decision recorded deployments and a 78% coverage rate + + +## Open questions + +We would love feedback on: + +- **Identifier conventions.** Should Kosli enforce a format for control identifiers, or accept whatever your GRC system uses (`RCTL-043`, `peer-review`, `vuln-scan-production`)? +- **Catalog sync.** Should Kosli pull from your GRC system, or is a one-way mirror managed via CLI/API enough? +- **Versioning behavior.** Decisions would reference the control version current at decision time. Is that the right default, or should the latest version always win for reporting? +- **Coverage windows.** "Active" within 28 days - is that the right window, or should it be configurable per control? +- **Policy gating.** Should missing decisions block deployments by default, or only when explicitly asserted via `kosli assert`? + +Tell us what you think - email [support@kosli.com](mailto:support@kosli.com). diff --git a/kosli_next/index.mdx b/kosli_next/index.mdx new file mode 100644 index 0000000..399f143 --- /dev/null +++ b/kosli_next/index.mdx @@ -0,0 +1,34 @@ +--- +title: "Kosli Next" +description: "Forward-looking concepts and preview features we're exploring with our customers." +sidebarTitle: "Overview" +--- + + + Kosli Next + Kosli Next + + +Kosli Next is where we share what we're working on next, so customers can shape it before it ships. + +It contains two kinds of content: + +- **Concepts** - ideas and directions we're considering. Nothing here is built yet. We publish them to gather feedback on the problem and the proposed approach. +- **Preview** - real features available to opt-in customers ahead of general availability. Behaviour can still change. + +Nothing in Kosli Next is part of Kosli's current product surface. To learn what Kosli does today, switch to the **Product** view. + +## How to give feedback + +Email [support@kosli.com](mailto:support@kosli.com) with the page name and your thoughts. We read every message. + +## Explore + + + + Ideas we're considering. Tell us what resonates and what doesn't. + + + Opt-in features close to general availability. + + diff --git a/kosli_next/preview/mcp_server.mdx b/kosli_next/preview/mcp_server.mdx new file mode 100644 index 0000000..18e214c --- /dev/null +++ b/kosli_next/preview/mcp_server.mdx @@ -0,0 +1,107 @@ +--- +title: "Kosli MCP Server" +description: "Expose the Kosli API to LLM clients like Claude Code and Claude Desktop via the Model Context Protocol." +tag: "Preview" +--- + +import { PreviewBanner } from '/snippets/kosli-next-banner.mdx'; + + + +The Kosli MCP Server is a [Model Context Protocol](https://modelcontextprotocol.io) server that exposes the Kosli API to LLM clients. Once installed, you can ask Claude things like _"which artifacts are running in prod-aws and which are non-compliant?"_ and it will call the relevant Kosli endpoints for you. + +It is published from [`kosli-dev/mcp-server`](https://github.com/kosli-dev/mcp-server) and distributed as both an npm package (`@kosli/mcp-server`) and a `.mcpb` desktop bundle. + +## How it works + +Rather than ship a tool per Kosli endpoint, the server generates a catalog from Kosli's OpenAPI spec and exposes three generic tools: + +| Tool | Purpose | +|------|---------| +| `search_actions` | Fuzzy-search the catalog for relevant actions by natural-language query. | +| `execute_read_action` | Invoke any GET action by ID. Auto-allowed in MCP clients. | +| `execute_write_action` | Invoke any POST/PUT/PATCH/DELETE action by ID. Gated behind user approval. | + +The typical flow is: the LLM calls `search_actions` to discover the right action ID and its parameter schema, then calls `execute_read_action` or `execute_write_action` with the chosen ID. Both execute tools accept an optional `fields` array to request only specific top-level fields in the response, which keeps token usage down. + +## Prerequisites + +- Node.js v20 or higher +- A [Kosli API token](/getting_started/service-accounts) +- An MCP-capable client (Claude Code, Claude Desktop, or any other) + +## Install + + + + Run from your project directory, or add `--scope user` to install globally: + + ```bash + claude mcp add kosli \ + -e KOSLI_API_TOKEN=your-token \ + -e KOSLI_ORG=your-org \ + -- npx -y @kosli/mcp-server + ``` + + + Download the latest `.mcpb` file from the [releases page](https://github.com/kosli-dev/mcp-server/releases) and drag it into Claude Desktop (or double-click to install). Claude Desktop will prompt for your API token and organization, and store secrets in the OS keychain. + + + Sideloaded extensions show an "unverified by Anthropic" warning and do not auto-update. These limitations will go away once the extension is listed in Anthropic's Connectors Directory. + + + + Edit `claude_desktop_config.json` via **Settings → Developer → Edit Config**: + + ```json + { + "mcpServers": { + "kosli": { + "command": "npx", + "args": ["-y", "@kosli/mcp-server"], + "env": { + "KOSLI_API_TOKEN": "your-token", + "KOSLI_ORG": "your-org" + } + } + } + } + ``` + + This method auto-updates via `npx` on each restart, but stores secrets in plain text. + + + The server communicates over stdio. Point any MCP-compatible client at the package via `npx -y @kosli/mcp-server` and set the required environment variables. + + + +## Configuration + +The server reads configuration from environment variables. + +| Variable | Required | Default | Notes | +|----------|----------|---------|-------| +| `KOSLI_API_TOKEN` | yes | - | Preferred. `KOSLI_API_KEY` is accepted as a fallback. | +| `KOSLI_ORG` | yes | - | Default org used when a path parameter `org` is not supplied. | +| `KOSLI_BASE_URL` | no | `https://app.kosli.com` | Use `https://app.us.kosli.com` for US, or your single-tenant endpoint. | + +## Example prompts + +Once connected, try prompts like: + +- "List the environments in my org and tell me which are compliant." +- "Show me the last 5 deployments to prod-aws." +- "What attestations are on trail `release-456` in flow `my-release`?" +- "Create a new flow called `payments-api`." + +Read prompts run without confirmation. Write prompts (create, update, delete) require an approval step in the MCP client. + +## Limitations + +- The catalog is generated from a snapshot of the OpenAPI spec. New endpoints land when the catalog is regenerated and a new package is published. +- LLM clients may need several `search_actions` calls before settling on the right action ID for ambiguous queries. +- Response shapes are whatever the Kosli API returns. Use the `fields` parameter on execute calls to trim large responses. + +## Feedback + +Tell us what you think - email [support@kosli.com](mailto:support@kosli.com) or open an issue at [`kosli-dev/mcp-server`](https://github.com/kosli-dev/mcp-server/issues). diff --git a/snippets/kosli-next-banner.mdx b/snippets/kosli-next-banner.mdx new file mode 100644 index 0000000..6c0febe --- /dev/null +++ b/snippets/kosli-next-banner.mdx @@ -0,0 +1,15 @@ +export const ConceptBanner = () => ( + + This is a concept and not available in Kosli today. We're sharing it to gather your feedback.

+ Email{' '} + support@kosli.com with your thoughts. + +); + +export const PreviewBanner = () => ( + + This is a preview feature, available to opt-in customers.

+ Share feedback at{' '} + support@kosli.com. + +); diff --git a/style.css b/style.css index f8bd7fe..50f3529 100644 --- a/style.css +++ b/style.css @@ -15,3 +15,20 @@ background-color: #CFD8FF !important; color: #111A26 !important; } + +/* ─── Kosli Next page tags ─────────────────────────────────────────────────── */ +/* + * Recolor the sidebar "Concept" and "Preview" tag pills to match the + * Kosli Next callout colour, so the future-state signal is consistent + * between the sidebar tag and the on-page banner. + */ +[data-nav-tag="Concept"] { + background-color: #FFB4AA !important; + color: #111A26 !important; +} + +[data-nav-tag="Preview"] { + background-color: #B4C5FF !important; + color: #111A26 !important; +} +