Skip to main content
This page restates every rule that mikting.schema.json and tools/mikting-lint.mjs enforce, so a model can write a correct script without the repository, npm, or a terminal. If you do have the tools, run node tools/mikting-lint.mjs --strict <file> as a second check, but do not depend on it.

If you are a model, do this in order

  1. Pick the triggers: value from the trigger table. Every top-level action needs one, unless the script is only called as a follow-up, include, or command.
  2. Choose actions only from the action table below, and use only the args listed for that action. Unknown arg names are rejected at runtime.
  3. Put follow-up-actions inside args. It is never a top-level field.
  4. Put not-met-actions only on a condition, never on an action.
  5. Declare the capabilities the script uses under permissions:.
  6. Check the result against Before you answer.

Where a script lives

Settings such as storage:, secrets.prefix, logging:, libs:, server:, http:, and safety: belong to the addon configuration, not to a script. A script that contains them fails schema validation, because the root object allows only the keys below.

Root object

Five keys, and nothing else:
actions: is required even when empty, so an on-demand-only script still needs actions: [].

Rules that get a script rejected

Text substitution

Order matters: secrets, then placeholders, then variables. A missing secret fails the action with missing_secret:NAME and sets mikting_error. Strings are interpolated inside URLs, headers, query values, JSON bodies, form bodies, and text bodies.

Actions

Args are exhaustive: an unlisted arg name is an error.

HTTP

auth is { type: bearer, tokenSecret: NAME } or { type: basic, userSecret: U, passSecret: P }. responseCheck is one of openai-moderation, openai-policy, groq-policy, jev-policy. miktingHttp sets mikting_status, mikting_ok, mikting_body, mikting_json, flattened JSON paths, mikting_headers_<name>, and mikting_error. With storeAs: probe, the same values use the probe_ prefix, and a JSON field at results.0.flagged becomes [[probe_json_results_0_flagged]].

Variables

miktingMath evaluates a filtrex expression, not JavaScript. A missing key sets mikting_error.

Text and data

miktingRandom with kind: int is inclusive and defaults to min: 0, max: 100. miktingJson.query uses a dot path such as users.0.name.

Flow control

These take no follow-up-actions. then, else, actions, try, and catch are action lists. miktingForEach defaults to 100 iterations, miktingWhile to 25, both clamped to 1000. miktingCallFunction copies back only result, under storeAs when given.

Discord

miktingModerate.op is ban, unban, kick, addRole, removeRole, nickname, or slowmode. user defaults to the context member; slowmode instead needs a text channel context. Ban caps deleteMessagesSec at 604800, slowmode caps slowmodeSec at 21600. miktingPoll takes 2 to 10 options and durationH from 1 to 336. miktingWaitFor.type is message or reaction. Polls, voice, scheduled events, and automod need the primary guild context.

Store

scope is global, guild, user, channel, or message. A missing key sets mikting_error to missing_key:<k>. miktingStoreRemove with key: '*' clears the scope. Values default to a 64 KiB cap.

Conditions

A condition returns true or false. Prefix its id with ! to invert it. not-met-actions runs when the result is false and holds an action list. miktingExpr provides len(x) and num(x) and is evaluated by filtrex, not JavaScript.

Triggers

Core ItsMyBot triggers such as messageCreate also work. HTTP failures set [[mikting_error]] and [[mikting_ok]] = false, and follow-ups still run. There is no miktingHttpError trigger.

Placeholders

Permissions

Declare the capabilities a script uses. Enforcement is warn-first, but strict lint reports a missing declaration.

Command block

A script can register a slash command instead of, or in addition to, event actions.
Options are limited to 25 per command and to 25 choices each. Names must be unique and lowercase.

Debug block

debug.actions runs on /mikting-debug <script-name>. Root actions stay the event path.
debug.input.title and label are 1 to 45 characters, placeholder at most 100. storeAs in response-check must match the HTTP action’s namespace.

Libraries

Function names match ^[A-Za-z0-9_.-]{1,64}$, at most 20 params. A file without version: 1 is skipped with a warning. Call it with miktingCallFunction and name:.

Canonical examples

Minimal event script:
HTTP call with failure handling. Note where follow-up-actions sits:
Condition with a failure path:
Counter in the store:

Wrong and right

Before you answer

  • Root has actions: and nothing outside the five allowed keys.
  • Every action’s args appear in that action’s row above.
  • follow-up-actions appears only inside args, and not on the eight flow actions.
  • not-met-actions appears only on conditions.
  • Every storeAs name matches ^[A-Za-z_][A-Za-z0-9_]*$ and is read with [[that_name]].
  • Each miktingHttp has one body (json, form, or text) and a url.
  • miktingBranch.when is a single-quoted filtrex expression.
  • permissions: lists every capability the script touches.
  • No literal credentials and no MIKTING_*=value lines.
  • The file is valid YAML: two-space indentation, no tabs, and quotes around values that YAML could misread such as true, null, numbers, or strings containing : or #.