Skip to main content
Glama

create_storyline

Create a storyline draft. After creating, self-check with validate_storyline, then publish_storyline.

user_visibility — what the end user sees of their own run: "invisible" (default, no UI),
"named" (a banner with the storyline name only), "trail" (banner + read-only view where
untaken branches and future steps are redacted grey blocks), "full" (banner with step x/y +
full read-only map). `learner_visibility` is the deprecated old name (legacy values
hidden/completed_only still accepted and mapped).

concurrency — who the progress follows: "user" (default) = progress belongs to the person, all
of that user's sessions share one run — fits curricula / onboarding / KYC; "session" =
progress belongs to the case, each session gets its own run, a new conversation = a new
application — fits licence applications / tickets / per-product flows. Case state goes to the
blackboard (travels with the run); facts about the person go to profile dimensions (shared
across runs).

graph = {"nodes":[Node,...], "edges":[]} (edges are derived from exits, may be left empty).
Node = {
  node_key: stable uuid (unchanged across edits; exits/funnels reference it), title,
  task (may interpolate {dimension}/{blackboard.key}),
  type: "task"(default) | "document_review"(visual pre-review of uploads) |
        "export"(structured report) | "parallel"(parallel branches / AND-join),
  review: {"checkpoints":[str]}   — type=document_review: per-item visual checkpoints,
  export: {"sections":[str]}      — type=export: report sections,
  parallel: {"branches":[{"key":str,"label":str,"to_node_key":str},...]}
    — type=parallel: declares required branches, each pointing at a sub-flow entry; the user
      may do them in any order, the engine tracks completion, and only when ALL are done does
      the node take its single join exit (put it at exits[0]). A branch sub-flow's last step
      just exits back to this parallel node — no hand-written completion flags.
  flags: {"is_entry":bool, "is_terminal":bool},
  on_enter_opening: something to say proactively on entry (empty = silent transition),
  ai_eval_trigger: natural-language condition for when to run AI evaluation (empty = every turn),
  callback: {"mode":"none"|"backend"|"ui_redirect", "wait_timeout_secs":int, "signal_name":str},
  profile_writes: [{"dim":str, "source":"ai"|"rule"|"callback"}]  — dimensions this node writes,
  resources: {"skills":[str],"knowledge_bases":[str],"tools":[str],
              "resource_mode":"additive"|"replace"},
  exits: [Exit,...] (list order = priority; deterministic rule/callback/user_choice are
  evaluated first, ai last)
}
Exit = {"kind":..., "label":str, "to_node_key":str,
  "ai_criteria":str            — kind=ai: one natural-language criterion,
  "user_choice":{"button_text":str} — kind=user_choice,
  "rule_ast":RuleAst           — kind=rule (see below; an AST, not a string),
  "callback_signal":"done"|"timeout"|"canceled" — kind=callback,
  "target_storyline_id":str,   — kind=goto_storyline
  "writes":[{"ref":"dim"|"blackboard","key":str,"op":"set"|"inc","value":<num|str|bool>},...]}
    — deterministic state writes when this exit is taken (this is how profile_writes with
      source='rule' actually land): set = assign (completion flags / branch flags),
      inc = increment (loop/retry counters, value defaults to 1). dim writes are constrained
      by profile_schema.
kind ∈ ai|user_choice|rule|callback|goto_storyline.
Common control flow composes deterministically (never bet on the LLM): if/else/switch = several
rule exits on one node (order = priority); loop/retry = a back-edge + an inc counter in writes
+ a rule cap gate; AND-join = a parallel node, or hub + completion flags + an "and" rule.
RuleAst is one of:
  comparison {"op":">="|">"|"<="|"<"|"=="|"!=",
        "left":{"ref":"dim"|"blackboard","key":str}, "right":{"value":<num|str|bool>}}
  boolean {"op":"and"|"or", "clauses":[RuleAst,...]}
profile_schema = dimension definitions, e.g.
{"listening":{"type":"int","min":0,"max":100,"visible_to_user":true}}.
on_complete="goto_next" requires next_storyline_id (validate/publish reject otherwise).
Enrolment (who enters this line, when): is_default=true auto-enrols on first conversation (at
most one per agent); allow_agent_enroll=true lets the agent enrol users mid-conversation — in
that case ALWAYS write enroll_trigger (one natural-language "enter when", e.g. "the visitor
says they want to apply for a loan"), otherwise the agent has no trigger basis and almost never
enrols; takes effect after publishing, independent of is_default and manual assignment.
See /docs/tenant-guide/storylines.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
keyYes
nameNo
entryNoauto
graphNo
agent_nameYes
allow_exitNo
is_defaultNo
concurrencyNouser
descriptionNo
on_completeNoend
display_nameNo
show_profileNo
enroll_triggerNo
profile_schemaNo
user_visibilityNoinvisible
next_storyline_idNo
allow_agent_enrollNo
learner_visibilityNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, but the description fully compensates. It discloses nuanced behaviors: concurrency semantics (progress belongs to user vs session), user_visibility levels and their UI implications, how parallel nodes manage completion, enrollment behavior (is_default, allow_agent_enroll) and the critical note that without enroll_trigger the agent 'almost never enrols'. It also explains that control flow composes deterministically and that case state vs profile dimensions are handled differently.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is lengthy but well-structured with line breaks, code formatting, and distinct sections for graph, Node, Exit, RuleAst, enrollment, etc. Every sentence carries technical value. It is not a terse summary, but the density is justified for a tool with 18 parameters. A slight deduction for verbosity; it could be split into bullet points or headers, but the inline code and grouping make it navigable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity, the description is remarkably complete. It covers graph schema, node types, exit kinds, rule AST, control flow patterns (if/else, loops, AND-joins), enrollment behavior, and even provides a documentation link. It includes all major parameter explanations and accounts for the output schema by not needing to describe return values. It leaves little ambiguity for an agent to invoke this correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the full burden. It provides deep meaning for many parameters: user_visibility and learner_visibility with legacy mapping, concurrency with examples of use cases, graph structure with full Node and Exit schemas, profile_schema, on_complete/next_storyline_id relationship, is_default, allow_agent_enroll, and enroll_trigger. This goes far beyond the bare schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a clear, specific action: 'Create a storyline draft.' It also differentiates from sibling tools by prescribing the next steps: 'After creating, self-check with validate_storyline, then publish_storyline.' This makes the tool's role distinct from validation and publishing, and it clearly targets creation of a new storyline.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly states the workflow after creation (validate and publish), which implies this tool is for the initial draft. It also gives detailed guidance on when enrollment parameters matter (e.g., 'in that case ALWAYS write enroll_trigger'). However, it does not explicitly contrast with update_storyline or clone_storyline, so it lacks a direct exclusion for alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

TDQS

A3.6/5.0
Disambiguation4/5

Tools are mostly distinct by domain and action. A few pairs like add_knowledge_file vs add_knowledge_text or build_knowledge_index vs patch_knowledge_index could cause confusion, but descriptions clearly differentiate them.

Naming Consistency4/5

The vast majority follow a consistent verb_noun snake_case pattern (create_*, list_*, get_*, update_*). A few outliers like tenant_info, usage_stats, and page_context_stats are noun-first, deviating slightly from the otherwise uniform scheme.

Tool Count1/5

With 50 tools, this is a very large surface that exceeds typical well-scoped server sizes. Even for a broad platform management API, the sheer number makes it heavy and potentially overwhelming, matching the '50+' extreme mismatch category.

Completeness2/5

The server covers creation, reading, updating, and listing for most resources but lacks any delete operations (no delete_agent, delete_knowledge_base, delete_skill, delete_share, delete_storyline, delete_page_context). This is a significant gap in lifecycle coverage that will force agents to work around missing functionality.

Resources