Skip to main content
Glama
SplitHub

SplitHub

Official

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
SPLITHUB_API_KEYNoSplitHub Cloud API key (sk_...). Optional: without it the tools read the local project config.

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": true
}

Tools

Functions exposed to the LLM to take actions

NameDescription
splithub_statusA

Every experiment of this project with status, visitors, days, the verdict headline, sample (verdict.sample.quality: small | ok | good), stars (verdict.sample.stars, data quality 0..5) and daysToVerdict (days until a verdict at the current traffic: schedule the next check then, do not poll). verdict guardrail_breached = do not ship that variant. The __holdout row is the project holdout (long-term impact). properties[] (SplitHub Cloud) is each analytics property's last 7 days against the 7 before (visitors, change, goal conversions): mention a big move; splithub_analytics has the details. Start here. A finished experiment is over but its variants are still in the code: report its verdict, ask the user which variant to keep and whether to remove the experiment, then call splithub_ship. display { label, lines, next } is ready to show; voice.line is the friendly line for humans; voice.advice move_on means suggest finishing the experiment and starting the next one. If analysis.available is false the project is self-hosted: report the raw numbers as they are, say verdicts come with SplitHub Cloud (analysis.url), and never call a winner from raw rates. The loop: splithub_plan → splithub_experiment_create → wire the code → splithub_doctor → splithub_push (cloud) → splithub_results (re-check after daysToVerdict days) → splithub_experiment_status finished → splithub_ship.

splithub_resultsA

Results of one experiment. SplitHub Cloud gives the full verdict: sample per variant, lift, P(beat), SRM, winner; mvt adds factors[]. verdict.status guardrail_breached means do not ship: a variant made a guardrail metric worse (verdict.guardrailBreached[]); say what broke. verdict.metrics[] has secondary metrics and guardrails. The experiment __holdout is the project holdout (long-term impact of all experiments). Verdicts are sequential (always-valid, safe to check any time) and depend on sample size, not days. verdict.sample.quality is small (below the minimums), ok, or good (every variant has its share of verdict.sample.goodSample, default 5000 visitors): say it next to the verdict; it never changes the decision. verdict.sample.stars (0..5) is a data-quality score from verdict.sample.checks[] (minimum, split, goodSample, power, week; each { met, label }): report the stars and the unmet labels, never as a reason to override the verdict. Quote verdict.message verbatim, use comparisons[].sequential.pValue / sequential.ci (the plain pValue is fixed-horizon, display only: p = 0.01 there can be not significant) and relay verdict.notes[]. daysToVerdict says when to check again. Facts are in verdict.message; voice.line is the friendly line for humans (voice.advice move_on = suggest finishing the experiment and starting the next one); display { label, lines, next } is ready to show. If analysis.available is false the project is self-hosted: report the raw numbers as they are, say verdicts come with SplitHub Cloud (analysis.url), and never call a winner from raw rates. If finished, ask which variant to keep, then splithub_ship. SLICE (SplitHub Cloud): from / to (YYYY-MM-DD, project time zone) keep the visitors first exposed on those days, filters keep visitors by country, device, platform (ios, android, web…), app_version, source, channel, landing page, UTM…; the answer carries scope and the verdict is computed on that slice only: say so and quote scope.note, the decision stays with the unfiltered verdict. A slice carries no voice and no advice (numbers only): never suggest shipping or finishing from one. VIEWS (one at a time, same from / to / filters; the answer has view set): by splits visitors by a dimension, segments[] each with cells per variant (order[] = variants, control first) and comparisons[] (lift vs the control inside the segment, pValue, significant, better; small = too few visitors); timeline gives exposures[] and conversions[] per day and variant (a day = visitors first seen that day, conversions whenever they happened); engagement gives bounce rate, pages per visit and avgVisit (ms) per variant from the analytics property on the same visitors (property null = no analytics there); events gives rows[] for every goal (measured goal / metric / guardrail first) and event of these visitors, each with perVariant visitors and rate and comparisons[] against the control (property null = goals only, other events need analytics on the same site). Segments, engagement and events are for exploring: never call a winner from one segment or one event.

splithub_experiment_eventsA

The latest raw events of one experiment (SplitHub Cloud, newest first): exposures (type exposure, the variant a visitor saw) and goals (type goal) with time, visitor, url, country. Same from / to / filters as splithub_results; type keeps one kind; nextBefore pages to older ones (pass it as before). Raw events stay 7 days (30 on Pro); the key needs events:read. Use to check that exposures and goals arrive after wiring code.

splithub_planA

Before creating an experiment: visitors per variant (and in all) to detect a relative lift mde on a baseline conversion rate, sized by SplitHub Cloud for its sequential verdict (no account needed; fails with UNREACHABLE offline). With an experiment id, also the days left at its current traffic when its numbers are readable. If it takes months, suggest a bigger change or a busier page.

splithub_experiment_createA

Add an experiment to splithub.config.ts (checked by reloading the file). It is written as running: it goes live when the code is deployed (and pushed in cloud mode). Tell the user that, and that splithub_experiment_status paused holds it. Pass status draft only when the user asks to hold it. kind: value (text/number/URL read with useValue), component (/ markup), redirect (match path + per-variant destination), mvt (factors instead of variants, every combination compared, read with useValue as { factor: value }). First variant / first level is the control. In an app (React Native, Expo) redirect does nothing, and the config ships inside the build: the variants' code needs a release, then starting, pausing and weights apply live from the cloud; target new builds with an app_version gte condition in the flow. goodSample: total visitors at which the sample counts as good (default 5000). minDays: opt-in fewest days before a verdict (default 0 = none). Then wire the returned snippet, call splithub_doctor and splithub_refs. The loop: splithub_plan → splithub_experiment_create → wire the code → splithub_doctor → splithub_push (cloud) → splithub_results (re-check after daysToVerdict days) → splithub_experiment_status finished → splithub_ship.

splithub_create_experimentA

Old name of splithub_experiment_create, kept for one release: call splithub_experiment_create instead.

splithub_experiment_statusA

Start, pause or finish an experiment. The config file is updated (and checked); in cloud mode it applies live within a minute. After finishing, the variants are still in the code: ask the user which variant to keep, then call splithub_ship.

splithub_set_statusA

Old name of splithub_experiment_status, kept for one release: call splithub_experiment_status instead.

splithub_analyticsA

Analytics properties (pageviews or app screens, and custom events, no variants). A property is kind site or app; in an app a screen is a page (url /ScreenName) and platform / app_version are dimensions for by and filters. Without property: every property with visitors, visits, pageviews and bounce for the last 30 days. With property: totals (visitors, newVisitors, sessions = visits, pageviews, events, bounces, duration in ms; bounce rate = bounces / sessions), goals (conversions = unique visitors who reached it in the range, completions = how many times, revenue), topPages and topSources (value "(none)" = direct). With by: rows grouped by a visit dimension, page, event or goal; goal adds that goal's conversions per row; variant (needs experiment) splits visits by the variant each visitor saw, trait (needs key) by an identify() trait. Range: days (last N days) or from / to (YYYY-MM-DD, project time zone). filters narrow the visits, e.g. { country: "DE,FR", source: "(none)" }. Self-hosted projects get raw counts only (analysis.available false): report them as they are and say full reports come with SplitHub Cloud. compare adds previous (the compared range, with its dates in previous.range) for change against it: 'previous' (the same-length range right before), 'year' (the same days a year earlier) or 'YYYY-MM-DD..YYYY-MM-DD'. segment applies a saved segment (splithub_segments) by name or id. These are counts, not experiments: no verdicts, never call a winner from them.

splithub_analytics_funnelA

Funnel of an analytics property (SplitHub Cloud): visitors who reached each step in order. Steps: page:/path (patterns like page:/blog/* work), event:, goal:; 2 to 8. Or funnel: a saved funnel's name or id (splithub_analytics_funnels), which brings its steps and within. within: visit (same visit, default), 7d or 30d (from the first step). Answers steps[] with visitors, conversion (share of the first step) and dropoff (share lost since the step before); by splits it by a visit dimension. rolledUp: days older than 90 count nothing. Counts, not an experiment: never call a winner from it.

splithub_analytics_funnelsA

Saved funnels of an analytics property (SplitHub Cloud), shown on its Funnels tab for the whole team. Without save or delete: the list (id, name, steps, within). save + steps: save one under that name (a name already saved updates it; steps and within as in splithub_analytics_funnel). delete: remove one by id or name. Run one with splithub_analytics_funnel { funnel }.

splithub_analytics_pathsC

Where visits went right after a page (or, with direction prev, where they came from), within the visit (SplitHub Cloud). rows[] { value, visits }; (exit) = left the site, (entrance) = landed on the page.

splithub_analytics_retentionA

Retention cohorts of an analytics property (SplitHub Cloud), the key report for apps: users grouped by the day or week they started (start: visit, event: or goal:), and how many came back (return: visit or event:) in period 0, 1, 2… cohorts[] { start, users, retained[] }; retained[0] is the cohort period itself, retained[i] / users is the share. Ranges longer than 90 days / 26 weeks are cut (clamped: true). Default: start visit, return visit, period week. filters take platform (ios, android, web…) and app_version too. Counts, not an experiment.

splithub_analytics_realtimeB

Who is on an analytics property right now (SplitHub Cloud): activeVisitors5m, pageviews and events per minute over the last 30 minutes, top pages and sources. Use to confirm tracking works after a deploy.

splithub_segmentsA

Saved segments: named report filters every report can apply (segment on splithub_analytics, funnel, paths, retention). Without arguments: the list. save + filters: save one (filters like { country: "DE,FR", channel: "Paid Search" }; property limits it to one property). delete: remove one by id or name. SplitHub Cloud.

splithub_notesA

Notes: what happened on a day (a launch, an outage, a campaign), shown on experiment timelines and analytics charts (SplitHub Cloud). action list (default): newest first; experiment or property narrows it (project-wide notes come too), kind filters, days / from / to set the range. add: text (day defaults to today in the project time zone; kind note | issue | win; experiment or property ties it to one, none = the whole project). edit: id + text / kind / day. delete: id. Add one when you ship something that may move the numbers.

splithub_linksA

Short links (SplitHub Cloud): one short URL that redirects to one or more destinations split by weight (split visitors between landing pages without code), clicks counted. action list (default): every link with totalClicks. stats: one link (id or slug): clicks per day (30 days), per destination, country, device, referrer, unique visitors. create: urls (one or more full http(s) URLs), slug (3-32 letters, digits, - _; random when omitted), name, weights (one per URL). edit: name / slug / description. pause, resume, delete: by id or slug. Targeting by country, device or a flow is done in the dashboard.

splithub_alertsC

Alert rules (SplitHub Cloud; they fire on Pro, a rule added on another plan is saved switched off). action list (default): rules with condition, params (params.progress { total, fired, month? } on usage and event_count is read-only), enabled; channels; history (recent alerts). add: condition + params. Experiment conditions (experiment = one key, omit for every running one): srm (broken split), winner (minVisitors?), loser (lift %, minVisitors?), exposures (visitors), conversions (conversions), duration (days), no_events (hours). Account: quota (percent of the monthly allowance), usage (every: alert each time this month's billed events cross another multiple, e.g. 1000). Analytics (property required): traffic_drop / traffic_spike (percent vs the same 24 hours a week before), goal_silent (goal, hours), event_count (event, any event when omitted; count; repeat = every count instead of once). Experiment rules may also pause, finish or dropLoser (winner / loser). enable, disable, delete, test (dry run: what would fire now, nothing sent): rule = id, the start of it, or the name. Where alerts go (email, Slack, Discord, webhook) is set in the dashboard.

splithub_analytics_connectA

Set up analytics in this app: use a property (id), create one (name, or nothing when the project has none), then name it on the one / in the code (property="sh-…"). Answers property, created, wired { status: added | already | other | none | many, file, line }, snippets { provider, script (sh.js tag with data-property), track, identify } and next. status none or many: add the provider snippet yourself (or the sh.js tag on a site without React). other: the provider names another property; ask before calling again with force. Pageviews are sent for you; events are track(name, props). In an app, script is empty and snippets.screen shows useScreen for screens the navigation tracker does not see. In cloud mode a new property is created in the cloud at once (live: applied), so no push: deploy.

splithub_analytics_eventsB

The latest raw pageviews and custom events of an analytics property (cloud: the raw tail, 7 days free / 30 Pro; self-hosted: the user's database). Use to check that tracking works after wiring track() or sh.js.

splithub_property_createA

Add an analytics property to splithub.config.ts, checked by reloading the file. Its id is generated (sh-x1h78w) unless given; it comes back as property. Events go only to a property named explicitly: wire (pageviews on load and every route change, and every track() call) or data-property="" on the sh.js script tag. Every goal of the project counts as a conversion unless goals narrows them. In cloud mode it is created in the cloud at once (live: applied), so no push is needed: tell the user to deploy. If live names a missing API key, log in and call again (or push). In an app (React Native, Expo) screens are page events: the screen tracker or useScreen(name) sends them.

splithub_create_propertyA

Old name of splithub_property_create, kept for one release: call splithub_property_create instead.

splithub_property_statusA

Pause or resume an analytics property (paused: its pageviews and events are dropped and not billed). Updates splithub.config.ts; in cloud mode it applies live within a minute. archived (SplitHub Cloud) stops collecting and hides it like the dashboard Archive, numbers kept; restored brings it back paused. removed takes it out of the config (a dashboard-made property is deleted in the cloud with its numbers).

splithub_set_property_statusA

Old name of splithub_property_status, kept for one release: call splithub_property_status instead.

splithub_domainsA

Allowed domains, per experiment and per analytics property (SplitHub Cloud). Without arguments: every allowed domain with where it applies, which experiments / properties accept any origin, and the origins seen sending events. With kind + id + hosts: replace that experiment's or property's list (subdomains included; an empty list accepts any origin again). Events from an origin outside the list are dropped (403 when nothing in the batch is allowed).

splithub_refsA

Files and lines that use an experiment id or its goal. Use after wiring code (is it referenced?) and after splithub_ship (count should be 0 for the experiment).

splithub_shipA

Keep one variant and take the experiment out: archives it in the cloud (numbers stay readable), removes it from splithub.config.ts and rewrites the code ( → the kept , useValue → the kept literal, useVariant branches folded, unused imports dropped). Ask the user which variant to keep first (recommend verdict.winner; never a variant listed in verdict.guardrailBreached). Call with dryRun: true, show the diff, then without. Fix leftovers[] by hand, then follow next[] (push, doctor, tests).

splithub_removeA

Remove an experiment from splithub.config.ts (and archive it in the cloud when connected) without touching the code. Prefer splithub_ship, which also cleans the code. Returns refs still in the code.

splithub_reviewB

AI reviews of an experiment stored in SplitHub Cloud (Pro): written at the start, when the verdict changes while it runs, when it finishes, or on demand in the dashboard. Newest first. Quote them as an opinion; the verdict stays the source of truth.

splithub_pushA

Upload splithub.config.ts to SplitHub Cloud (cloud mode). Also returns kept: experiments the cloud has from an earlier push that this file lacks, left as they are. prune removes those: only when the user asked for it. Returns experiments created in the dashboard that were written into the file. dryRun: only check the config and show what would change. A key that already belonged to another experiment fails with KEY_CONFLICT: ask the user, then push with replace (new experiment, old numbers cleared) or same (same experiment, numbers stay).

splithub_pullB

Fetch the cloud config and write dashboard-created experiments into splithub.config.ts.

splithub_doctorA

Check the installation: config, provider, middleware, routes, code references, endpoint; in a React Native / Expo app also the package, its storage module and redirect experiments; in a native iOS / Android project the SDK in the build files. Run after wiring code; ok: false lists what to fix.

splithub_whoamiC

Which cloud project this folder is connected to, and its public key.

splithub_projectsA

Every folder on this machine connected to a SplitHub Cloud project, the current one marked (current).

splithub_loginA

Connect this folder to SplitHub Cloud. Returns a sign-in link and a code: show them to the user, who approves in the browser (and can create a project there). The CLI then stores a project API key for this folder. Call splithub_whoami afterwards.

splithub_initA

Set up SplitHub in this project: config file, framework files, agent skills; React Native / Expo apps also get @splithub/react-native and their entry (App.tsx, app/_layout.tsx) wrapped in with screen tracking (app.entry.status added | already | manual: wire nextStep by hand); native iOS / Android get install lines and a quick start (app.install, app.quickStart) and no config file; in cloud mode see splithub_login to connect. Use once per project. githubAction: also write a GitHub workflow (checks on PRs, results comment on a schedule).

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

TDQS

B3.4/5.0

Scored across 36 tools

Disambiguation3/5

Most tools target distinct resources and the descriptions carefully differentiate them (e.g. splithub_status vs splithub_experiment_status vs splithub_results), but there are several overlap traps: four deprecated alias tools (splithub_create_experiment, splithub_set_status, splithub_create_property, splithub_set_property_status) duplicate existing tools with reversed-word names, splithub_remove overlaps splithub_ship, and splithub_property_create overlaps splithub_analytics_connect. An agent can disambiguate with careful reading, but the aliases and near-duplicates are real misselection risk.

Naming Consistency3/5

There is a consistent splithub_ prefix and mostly snake_case, but the convention is mixed: bare-noun tools (status, results, plan, ship, refs, domains, links, notes, alerts) sit alongside noun_noun tools (experiment_create, analytics_funnel), and verb placement is inconsistent — splithub_property_create and splithub_create_property both exist, one deprecated. Multi-action tools (links, notes, alerts, analytics) pack CRUD into an action parameter, further diverging from the verb_noun pattern.

Tool Count2/5

36 tools is above the 25+ threshold and feels heavy, especially since 4 of them are deprecated one-release aliases that should not inflate the surface. The domain is genuinely broad (experiments plus a full analytics suite), but the set could be consolidated (e.g. links/notes/alerts/se gems action multiplexing is already used elsewhere).

Completeness5/5

Coverage is exceptional: full experiment lifecycle (plan → create → doctor/refs → push → results → status → ship/remove → review), full analytics suite (properties, funnel, paths, retention, realtime, events, segments), plus links, alerts, notes, domains, and cloud connection/init tooling. Obvious dead ends are rare — remaining gaps (alert channel config, link targeting) are explicitly dashboard-only and documented.

Maintenance

ActivityNo data
ResponsivenessSyncing