
Install Skene
Start with the TUI or CLI to analyze your codebase locally. When you are ready to connect agents or CI, add MCP or GitHub Actions on top.
| Surface | Best for |
|---|---|
| Skene TUI & CLI | Local journey mapping, growth analysis, and pushing artifacts to your workspace |
| MCP server | Agents that need journey context and event-tracking drift checks while they code |
| GitHub Actions | CI pipelines that verify journey-planned tracking events are present in code |
1. Skene TUI & CLI
The open-source toolkit lives in SkeneTechnologies/skene. This is the fastest way to go from zero to a journey.yaml in your repo.
| Component | Language | Distribution | Role |
|---|---|---|---|
| TUI | Go (Bubble Tea) | GitHub Releases via tui/install.sh | Interactive wizard (start here) |
| CLI | Python 3.11+ | PyPI (pip / uvx) | Analysis engine the TUI orchestrates |
The TUI does not run analysis itself. It auto-provisions uv/uvx and calls the Python CLI in the background.
Terminal UI (recommended)
No Python install required upfront. The installer puts the skene binary on your PATH.
curl -fsSL https://raw.githubusercontent.com/SkeneTechnologies/skene/main/tui/install.sh | bash
skene
The wizard walks you through:
- LLM provider and model selection
- Authentication (Skene Cloud magic link, API key, or local LLM)
- Project directory selection
- Analysis (journey and/or growth manifest)
- Tabbed results with a local journey visualizer
Python CLI
If you prefer the command line, use uvx (no global install) or pip:
# Install uv (if needed)
curl -LsSf https://astral.sh/uv/install.sh | sh
# Journey analysis (primary path) — writes ./skene-context/journey.yaml
uvx skene analyse-journey .
# Growth workflow — manifest, plan, build
uvx skene analyze .
uvx skene plan
uvx skene build
Or install globally:
pip install skene
skene analyse-journey .
Useful analyse-journey flags:
--schema-dir <dir>— include exported*.sqlfiles for schema-aware evidence-o <path>— override output (default./skene-context/journey.yaml)--no-specialize— keep canonical stage names instead of product-specific labels
What it produces
Both the TUI and CLI write artifacts under ./skene-context/ in your project root (override with output_dir in .skene.config or -o / --output).
| Artifact | Command | Purpose |
|---|---|---|
journey.yaml | analyse-journey | Seven-stage user journey with evidence-backed milestones |
growth-manifest.json | analyze | Tech stack, growth features, opportunities |
growth-plan.md | plan | Prioritized growth plan |
growth-template.json | analyze | Growth template for your business type |
Journey analysis uses two parallel agents (codebase + optional SQL schemas), merges milestones, and classifies them into discovery → onboarding → activation → engagement → retention → expansion → virality.
Push to Skene Cloud
After local analysis, sync artifacts to your workspace:
uvx skene login --upstream https://www.skene.ai/workspace/your-workspace
uvx skene push .
Configure the provider first with uvx skene config --init if you have not set up an LLM.
Supported LLM providers
OpenAI, Gemini, Claude (Anthropic), LM Studio, Ollama, and any OpenAI-compatible endpoint. Configure via uvx skene config or environment variables (SKENE_API_KEY, SKENE_PROVIDER).
Verify installation
uvx skene --version
2. MCP server (Cursor, Claude Code, Codex)
Plug Skene into your coding agent when it needs journey context (stages, milestones, expected events) and event-tracking drift checks before changes land. The agent scans your repo, compares tracked events against the journey, and flags removed, renamed, or altered instrumentation in the same panel it uses to write code.
Skene MCP is a hosted endpoint over HTTPS. No local MCP binary to install.
Endpoint: https://www.skene.ai/api/mcp
Authentication: pass a workspace API key using any of these headers:
X-API-Key(recommended for IDEmcp.jsonconfigs)Authorization: Bearer <token>X-Skene-Token
Create a key in the dashboard under Settings → API keys.
Example for Cursor (~/.cursor/mcp.json):
{
"mcpServers": {
"skene": {
"url": "https://www.skene.ai/api/mcp",
"headers": {
"X-API-Key": "your-workspace-api-key"
}
}
}
}
Restart the agent, then call skene_workspace_info to verify credentials and scopes.
Journey context
skene_get_journey— customer journey canvas: stages, milestones, levers, and usage overlays for the workspace
Event-tracking drift checks
skene_check— start an analytics audit; returns ascan_spec(grep patterns and file rules) for the agent to run locallyskene_gap— pass scannedtracked_eventsand get a gap report (missing events, drift vs the journey)skene_users— manage audit personas (create,list,update)
Other tools (deploy status, growth intelligence, push validation, playbooks) are available depending on API key scopes. See What Skene catches for the failure modes drift checks target.
For setup details (scopes, OAuth, discovery manifest), see MCP Server.
Local stdio MCP (advanced): the open-source Python package can also run a local stdio MCP server for repo-only workflows. That mode is separate from the hosted endpoint above. See skene CLI docs.
3. GitHub Actions (analytics drift CI)
Use CI to verify that tracking events planned on your cloud journey are still present in the checked-out repository.
The workflow:
- fetches the canonical scan spec from Skene Cloud
- scans the repository with those grep patterns
- posts tracked events back for a deterministic compare against the journey
- on pull requests, posts a comment with missing events and recommendations
- fails the check when required journey events are missing
- optionally runs a full LLM gap report on pull requests (powers the recommendations in the PR comment)
Set up SKENE_API_KEY in GitHub
The workflow authenticates with a workspace API key. The workspace is inferred from the key; you do not need a separate workspace ID secret.
1. Create the key in Skene
- Open your workspace in the Skene dashboard.
- Go to Settings → API keys.
- Create a new key (or reuse an existing CI key).
- Enable scopes:
analysis:read— required (fetch scan spec and run the deterministic drift check)analysis:write— required on pull requests if you want LLM gap recommendations in the PR comment (include_llm_gap: true)
Copy the key value when shown. You will not be able to view it again.
2. Add the key as a GitHub Actions secret
- In your GitHub repository, open Settings → Secrets and variables → Actions.
- Click New repository secret.
- Name:
SKENE_API_KEY - Value: paste the workspace API key from step 1.
- Save.
Optional: add a repository variable named SKENE_API_BASE_URL (for example https://staging.skene.ai) if the workflow should call a non-production Skene API. When unset, workflows use https://www.skene.ai.
API endpoints
POST /api/v1/analytics-audit/scan-spec(analysis:read)POST /api/v1/analytics-audit/check(analysis:readfor deterministic mode;analysis:writewheninclude_llm_gap: true)
Add .github/workflows/skene-analytics-drift.yml:
name: Skene analytics drift
on:
pull_request:
push:
branches: [main]
jobs:
analytics-drift:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
issues: write
steps:
- uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
- name: Fetch scan spec
env:
SKENE_API_KEY: ${{ secrets.SKENE_API_KEY }}
SKENE_API_BASE_URL: ${{ vars.SKENE_API_BASE_URL }}
run: |
if [ -z "$SKENE_API_KEY" ]; then
echo "SKENE_API_KEY repository secret is required."
exit 1
fi
BASE="${SKENE_API_BASE_URL:-https://www.skene.ai}"
curl --fail --show-error \
"${BASE}/api/v1/analytics-audit/scan-spec" \
-H "Authorization: Bearer ${SKENE_API_KEY}" \
-H "Content-Type: application/json" \
-X POST \
-d '{}' > scan-spec-response.json
jq '.data.scan_spec' scan-spec-response.json > scan-spec.json
- name: Download Skene CI scan script
run: |
curl -fsSL \
"https://www.skene.ai/ci/scan-tracking-events.mjs" \
-o scan-tracking-events.mjs
- name: Scan repo tracking events
run: |
node scan-tracking-events.mjs \
--scan-spec scan-spec.json \
--output scan-result.json
- name: Compare journey vs code
env:
SKENE_API_KEY: ${{ secrets.SKENE_API_KEY }}
SKENE_API_BASE_URL: ${{ vars.SKENE_API_BASE_URL }}
run: |
BASE="${SKENE_API_BASE_URL:-https://www.skene.ai}"
INCLUDE_LLM_GAP=false
if [ "${{ github.event_name }}" = "pull_request" ]; then
INCLUDE_LLM_GAP=true
fi
jq -n \
--argjson scan "$(cat scan-result.json)" \
--arg include "$INCLUDE_LLM_GAP" \
'{
tracked_events: $scan.tracked_events,
detected_providers: $scan.detected_providers,
codebase_index: $scan.codebase_index,
include_llm_gap: ($include == "true")
}' > audit-check.json
curl --fail --show-error \
"${BASE}/api/v1/analytics-audit/check" \
-H "Authorization: Bearer ${SKENE_API_KEY}" \
-H "Content-Type: application/json" \
-X POST \
--data @audit-check.json > audit-result.json
cat audit-result.json | jq .
OK=$(cat audit-result.json | jq -r '.data.ok')
if [ "$OK" = "true" ]; then
echo "DRIFT_FAILED=false" >> "$GITHUB_ENV"
else
echo "DRIFT_FAILED=true" >> "$GITHUB_ENV"
fi
- name: Build PR comment body
if: ${{ github.event_name == 'pull_request' }}
run: |
cat > skene-pr-comment.md <<'EOF'
## Skene analytics drift report
EOF
jq -r '
.data as $d |
if ($d.ok == true) then
"- Status: ✅ Pass\n\nNo missing required journey events were detected."
else
"- Status: ❌ Drift detected\n"
+ "\n### Missing Events\n"
+ (
if (($d.missing_events // []) | length) > 0 then
(($d.missing_events // [])
| map("- `" + (.event // "unknown") + "`"
+ (if (.stage_id // "" | length) > 0 then " (stage: `" + .stage_id + "`)" else "" end)
+ (if (.milestone_label // "" | length) > 0 then " - " + .milestone_label else "" end)
)
| join("\n"))
else
"- None listed"
end
)
+ "\n\n### Recommendations\n"
+ (
if (($d.llm_gap.result.recommendations // []) | length) > 0 then
(($d.llm_gap.result.recommendations // [])
| map("- " + tostring)
| join("\n"))
else
"- No recommendations returned."
end
)
end
' audit-result.json >> skene-pr-comment.md
- name: Comment on pull request
if: ${{ github.event_name == 'pull_request' }}
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const fs = require('fs');
const body = fs.readFileSync('skene-pr-comment.md', 'utf8');
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body,
});
- name: Fail workflow on drift
if: ${{ env.DRIFT_FAILED == 'true' }}
run: |
echo "Skene analytics drift check failed."
exit 1
On pull requests, the job posts a comment with Missing Events and Recommendations, then fails the check if drift was detected. On branch pushes, you get pass/fail only (no PR comment).
The scan script uses the same pattern registry as hosted MCP skene_check. Dynamic event names (non-literal first arguments) are not detected, which matches MCP behavior.
For the agent-side equivalent, see MCP Server.
What is next
- CLI reference — every command and flag
- MCP Server — hosted MCP setup and tools
- What Skene catches — instrumentation drift failure modes
- Skene on GitHub — source, issues, TUI releases