Skip to content

Releases

v0.24.0

Choose a tag to compare

@github-actions github-actions released this 06 Nov 14:56
  • Leave a step out of one run: run --skip. The step that deletes what you want to look at, a slow sleep, a step against a service that is down today: skip it for this run, and the file stays as it is, so a step never stays out by mistake in CI. A step is named as with --to, by its number as inspect lists it or by its name, and the option can be repeated (spec 0021).

    tinyprobe run tinyprobe/workflows/users.yaml -e tinyprobe/env.local.yaml --skip 11 --skip "Deleted user is gone"
      ✓ Patch the user          PATCH  200      397µs  /api/users/56
      – Delete the user         skipped (--skip)
      – Deleted user is gone    skipped (--skip)
    
      steps...............: 10/10 passed  2 skipped
    

    Skipped steps are not counted: the run passes when the steps that ran passed. A later step that needs a value only a skipped step saves fails and says why: Variable 'userId' is not defined: step 7 (Create a user), which saves it, was skipped. With --to, skipped steps after the target are ignored. --skip takes one workflow file.

  • For tools. run_started lists the skipped steps in skipped and the summary counts them in skipped_steps (new keys, protocol 1); in the JUnit report they are <skipped message="Skipped with --skip"/>. The MCP run tool takes skip, so an agent can explore a flow without the step that would delete what it looks at. tinyprobe-app uses it for ⊘ Skip on the steps of a workflow.

Update: tinyprobe update, or run the install command again.

What's Changed

  • Spec 0021: skip steps in a run (--skip) by @kikutano in #41
  • Add run --skip: leave steps out of one run (spec 0021) by @kikutano in #42

Full Changelog: v0.23.0...v0.24.0

v0.23.0

Choose a tag to compare

@github-actions github-actions released this 05 Nov 08:42
  • A sequence once per item: for_each on use. A case made of several steps (create, read back, delete) is a sequence; give its use a for_each, a written list or a data file, and the sequence runs once per item. Each item's keys are params of the sequence, checked like with, and each item saves and reads its own values (spec 0020).

    - use: ../sequences/user-lifecycle.yaml
      for_each:
        - { firstName: Ada, city: Bari }
        - { firstName: Grace, city: Lecce }
      ✓ User lifecycle [1/2] › Create     POST   201     1.08ms  /api/users
      ✓ User lifecycle [1/2] › Read it …  GET    200      554µs  /api/users/35
      ✓ User lifecycle [1/2] › Delete     DELETE 204      665µs  /api/users/35
      ✓ User lifecycle [2/2] › Create     POST   201      674µs  /api/users
      ...
    

    The workflow stops at the first failing step. A variable as the items (for_each: ${users}) is not supported on a use: it stays for call steps. inspect --json gives each step's sequence its item and items.

  • Faster inspect and call. The YAML of a workflow is parsed once instead of twice, and the default names of steps no longer recompute their endpoint's placeholders: inspect of 2000 steps went from 443 to 321 ms, of 8000 from 1917 to 1235 ms. The VS Code extension and tinyprobe-app run inspect on every save, so editors get faster too.

  • The README is rewritten around what makes tinyprobe different; the command-line reference moved to docs/cli.md, and docs/comparison.md compares tinyprobe with Postman, Bruno and Hurl.

Update: tinyprobe update, or run the install command again.

What's Changed

  • Parse a workflow once in inspect and call by @kikutano in #37
  • Rewrite the README around what makes tinyprobe different by @kikutano in #38
  • A comparison with Postman, Bruno and Hurl by @kikutano in #39
  • for_each over a sequence: a use step runs it once per item by @kikutano in #40

Full Changelog: v0.22.0...v0.23.0

v0.22.0

Choose a tag to compare

@github-actions github-actions released this 04 Nov 18:13
  • A call shows its status, not a verdict. tinyprobe call checks nothing, so its line no longer starts with a green ✓ for any response, a 401 or a 500 included. It starts with → (> without Unicode) and the colored status; a ✗ now means only that no response arrived. tinyprobe run, the exit codes and the ndjson events don't change (spec 0019).

    $ tinyprobe call docs/example/api/testserver.yaml status --with code=404 -e docs/environment.yaml
      → status code=404  GET    404    64.41ms  /api/status/404
    
      HTTP 404 Not Found
    
  • License: GPL-3.0. From this version tinyprobe is licensed under the GNU General Public License, version 3 (GPL-3.0-only): it stays free and open source, and a changed version can be shared only under the same license, with its source code. Releases up to 0.21.0 stay under the MIT License.

Update: tinyprobe update, or run the install command again.

What's Changed

  • Show a call's status without a verdict by @kikutano in #36

Full Changelog: v0.21.0...v0.22.0

v0.21.0

Choose a tag to compare

@github-actions github-actions released this 31 Oct 10:47

The file as written, for editors.

tinyprobe inspect tinyprobe/api/shop.yaml --json --source

adds two keys to the inspect --json document:

  • source: the file as written, as JSON — keys in order, scalars typed as YAML reads them, placeholders unresolved. The headers written in an endpoint, its auth set, the auth sets, checks as operator and value, use steps, import, variables.
  • blocks: where every top-level key, auth set, endpoint and step starts and ends, so an editor rewrites one block and keeps the rest of the file, comments included.
{ "kind": "endpoint", "name": "login", "start": { "line": 7, "column": 3 }, "end": { "line": 10, "column": 57 } }

Without --source nothing changes, the MCP tool inspect included. The protocol stays 1: new keys only (docs/protocol.md).

tinyprobe-app 0.3.0 builds its visual editor on it: endpoints, auth sets, workflows and their steps edited with forms, and tinyprobe checks every change before it is kept.

What's Changed

  • inspect --source: the file as written, for editors (spec 0018) by @kikutano in #35

Full Changelog: v0.20.1...v0.21.0

v0.20.1

Choose a tag to compare

@github-actions github-actions released this 31 Oct 08:34

tinyprobe mcp is now listed in the official MCP Registry as io.github.kikutano/tinyprobe, with the Docker image ghcr.io/kikutano/tinyprobe as its package: clients that read the registry can add the tinyprobe tools (guide, inspect, call, run) from there. Each stable release updates the listing.

The image has the label the registry checks (io.modelcontextprotocol.server.name). Nothing else changes: the binary is the same as 0.20.0.

Full Changelog: v0.20.0...v0.20.1

v0.20.0

Choose a tag to compare

@github-actions github-actions released this 30 Oct 07:31

Two new operators for expect and until: regular expressions, and JSON Schema. No breaking change.

matches: a regular expression

On a body value, a header or a cookie. It searches the value, like JavaScript's RegExp.test; anchor it with ^...$ for the whole value, (?i) ignores case. Numbers and booleans are matched as their JSON text. Placeholders work: '^${prefix}-'.

expect:
  headers:
    Location: { matches: '^/api/orders/[0-9]+$' }
  cookies:
    sid: { matches: '^[0-9a-f]{32}$' }
  body:
    $.id: { matches: '^ORD-[0-9]{8}-[0-9]{4}$' }
    $.email: { matches: '(?i)@example\.com$' }

An invalid pattern is an error before any request, with the reason. A pattern that takes more than 1 s on a value fails the step instead of hanging the run.

schema: check a value against a JSON Schema

The whole body ($) or a part of it, against a JSON or YAML schema file, a schema inside your OpenAPI document (after #, a JSON Pointer), or a schema written in the step:

expect:
  body:
    $: { schema: ../openapi/openapi.yaml#/components/schemas/User }
    $.address: { schema: ../schemas/address.json }
    $.id: { schema: { type: integer, minimum: 1 } }
      ✗ $.nickname schema required  actual (missing)
      ✗ $.id schema type "string"  actual 1
  • JSON Schema drafts 4 to 2020-12 and the schemas of OpenAPI 3.0 and 3.1 (nullable, boolean exclusiveMinimum), $ref within a document and to other files, and the common formats (date-time, date, time, email, uuid, uri, ipv4, ipv6).
  • Schemas are read and checked when the workflow is loaded: a missing file, a pointer that leads nowhere, a misspelled keyword (requird) or an unsupported one is an error with its location, before any request.
  • One failed check per problem, at the path of the value, at most 20, then a count.

The guide for coding agents (tinyprobe guide) maps Postman's jsonSchema, tv4.validate and .to.be.a("string"), and Bruno's type checks, to schema, and tells agents that start from an OpenAPI document to point at components/schemas instead of copying them.

Also

  • docs/example uses both operators, so CI and the test server image exercise them.
  • Strings in the report keep characters such as + as they are, instead of +.
  • The binary is 165 KB larger (9.3 MB) and starts in the same 5 ms.

What's Changed

  • matches: regular expressions on body values, headers and cookies (spec 0015) by @kikutano in #33
  • schema: check a body value against a JSON Schema (spec 0016) by @kikutano in #34

Full Changelog: v0.19.0...v0.20.0

v0.19.0

Choose a tag to compare

@github-actions github-actions released this 29 Oct 10:29

Examples anyone can run: the test server as a Docker image, and a guided tour of every feature.

Highlights

The test server in Docker

The complete example project, docs/example, runs against a small test server: bearer and API-key auth, Basic, OAuth2, cookie sessions, forms and uploads, slow responses and async jobs. It used to need the .NET SDK. It is now an image:

docker run --rm -p 127.0.0.1:5122:5122 ghcr.io/kikutano/tinyprobe-testserver:0.19.0
tinyprobe run docs/example/workflows -e docs/environment.yaml

The server accepts fixed credentials and fake tokens on purpose: keep the 127.0.0.1: in -p so only your machine reaches it. Images for linux/amd64 and linux/arm64, tagged like the tinyprobe image (0.19.0, 0.19, latest).

A guided tour of docs/example

docs/example/README.md walks through the format one workflow at a time: what each one shows, and the commands to try (call, --to, --junit, inspect, a validation error on purpose, init), and the Postman and OpenAPI files to try a migration with your agent.

The suite now covers the whole format. A new workflow, jobs.yaml, starts a report and waits for it with until, with generated values and workflow variables:

variables:
  reportName: "report-${$uuid}"      # resolved once per run: every step sees the same name
  requestedAt: ${$now}

steps:
  - call: start_report
    with: { name: "${reportName}", requestedAt: "${requestedAt}" }
    save: { reportId: $.id }
  - call: get_report
    with: { id: "${reportId}" }
    until:
      body: { $.status: done }
      every: 100ms
      timeout: 10s

catalog.yaml adds AND and OR (any) checks.

Also

  • No change in the format, the CLI or the protocol: the tinyprobe binary does what 0.18.0 did.
  • The VS Code extension 0.8.0 follows, with sequence files, go to definition and the items of for_each steps.

No breaking changes.

What's Changed

  • Examples anyone can run: test server image and guided docs/example (M4-12) by @kikutano in #32

Full Changelog: v0.18.0...v0.19.0

v0.18.0

Choose a tag to compare

@github-actions github-actions released this 28 Oct 13:38

Cookies, Basic and OAuth2, tables of cases, shared steps, named imports, and run to here.

Highlights

Cookies

Every workflow run keeps the cookies the server sets, redirects included, and sends them with the next requests. Each workflow starts with none; tinyprobe call keeps none between calls. Cookies can be checked, and saved for a CSRF header:

- call: login
  expect:
    cookies:
      sid: { exists: true }
  save:
    csrf: { cookie: XSRF-TOKEN }

The recorded request (ndjson, the VS Code extension) now shows the Cookie header as sent.

Basic auth and OAuth2 client credentials

Two keys of an auth set, next to its headers:

auth:
  admin:
    basic: { username: ${username}, password: ${password} }
  service:
    oauth2:
      token_url: ${authUrl}/oauth/token
      client_id: ${clientId}
      client_secret: ${clientSecret}
      scope: [orders:read]
  • tinyprobe computes the Basic header.
  • It gets the OAuth2 token on first use and reuses it for the run until it expires, so tinyprobe call works on protected endpoints with only the environment file.

for_each: tables of cases

One step, one call per item. Each item's keys are arguments, and in a for_each step the expected status can come from the item. The list is written in the workflow, held by a variable, or read from a CSV or JSON file, which is how Postman data files translate.

- name: Invalid users are rejected
  call: create_user
  for_each:
    - { email: "", error: email_required }
    - { email: not-an-email, error: email_invalid }
  expect:
    status: 422
    body: { $.code: ${error} }

Every item runs, even after a failing one, and the console and JUnit show one line per item.

Sequences: steps shared by several workflows

A login written once, in tinyprobe/sequences/, and run with use. Its params are local to it; what it saves is visible after it.

steps:
  - use: ../sequences/log-in.yaml
    with: { password: "${adminPassword}" }
  - call: list_orders

Named imports

Two services with the same endpoint names can be imported together:

import:
  - ../api/shop.yaml
  - billing: ../api/billing.yaml    # billing.login, billing.create_invoice

Run to here

tinyprobe run tinyprobe/workflows/orders.yaml --to 4 -v

This runs a workflow up to a step, given by its number or its name, and stops. The steps after it are not counted, so the run exits 0 when everything up to it passed. The MCP run tool takes to as well. The VS Code extension's ▶ Run to here follows in its next release.

Also

  • Protocol 1, new keys only:
    • basic_auth, oauth2, for_each, source_location, sequence, import_name, imports, kind: sequence;
    • iterations on step_completed;
    • to and stopped_after on the run events.
  • Guide: tinyprobe guide now translates Postman, Insomnia and Bruno cookies, Basic, OAuth2 client credentials and data files, and the same from OpenAPI, HAR and curl.
  • Size and speed budgets in CI: the binary is 9.2 MB, starts in under 10 ms, and runs 500 requests with their checks in about 300 ms against a local server.
  • tinyprobe init also creates tinyprobe/sequences/.

No breaking changes.

What's Changed

  • Cookies: a jar per workflow, expect.cookies, save from a cookie by @kikutano in #25
  • Basic auth and OAuth2 client credentials in auth sets by @kikutano in #26
  • for_each: repeat a step over a list of items by @kikutano in #27
  • Sequences: steps shared by several workflows, run with use by @kikutano in #28
  • Performance guard in CI: size and speed budgets by @kikutano in #29
  • Named imports: call billing.login by @kikutano in #30
  • run --to: run a workflow up to a step by @kikutano in #31

Full Changelog: v0.17.0...v0.18.0

v0.17.0

Choose a tag to compare

@github-actions github-actions released this 28 Oct 06:28

Form and multipart bodies, with file uploads.

Highlights

form: urlencoded bodies, encoded for you

An endpoint can send application/x-www-form-urlencoded with form. Names and values are encoded after placeholders are resolved, so a password with &, + or = is sent as written. A list repeats the field.

endpoints:
  token:
    method: POST
    path: /oauth/token
    params: { client_id:, client_secret: }
    form:
      grant_type: client_credentials
      client_id: ${client_id}
      client_secret: ${client_secret}

multipart: text fields and file uploads

multipart sends multipart/form-data: text fields, files (file, with optional filename and content_type), and lists, in the order written.

endpoints:
  upload_avatar:
    method: PUT
    path: /api/users/${id}/avatar
    auth: bearer
    params: { id:, avatar: }
    multipart:
      description: Profile picture
      avatar:
        file: ${avatar}
      tags: [profile, public]
steps:
  - call: upload_avatar
    with:
      id: ${userId}
      avatar: ../fixtures/avatar.png
    expect:
      status: 204
  • A relative file path is relative to the file tinyprobe was given: the workflow for run, the API file for call. A workflow runs the same from any directory.
  • Content-Type is set by tinyprobe. A Content-Type in the endpoint's own headers is an error, reported with its location.
  • Recorded requests (-v, ndjson, the VS Code extension) show each file as one line, (file ../fixtures/avatar.png, 79 B), instead of its bytes.
  • Under tinyprobe mcp, files must be inside the server's working directory.
  • inspect --json has form and multipart for each endpoint (new keys, protocol 1). tinyprobe schema describes the new keys, so the extension completes them with no update.

Imports by your AI

tinyprobe guide now translates Postman formdata and urlencoded, OpenAPI multipart/form-data and form bodies, Insomnia, Bruno, HAR form parameters, and curl -F and --data-urlencode, where it used to list them as not translated. Files go in tinyprobe/fixtures/. In the OpenAPI bench, Sonnet converted 11 operations of 11, the avatar upload included.

No breaking changes.

What's Changed

  • Add form and multipart bodies, with file uploads by @kikutano in #24

Full Changelog: v0.16.0...v0.17.0

v0.16.0

Choose a tag to compare

@github-actions github-actions released this 27 Oct 11:40

Docker image

docker run --rm -v "$PWD:/work" ghcr.io/kikutano/tinyprobe:0.16.0 run tinyprobe/workflows -e tinyprobe/env.local.yaml

ghcr.io/kikutano/tinyprobe, for linux/amd64 and linux/arm64, tagged 0.16.0, 0.16 and latest: the Alpine binary of this release on Microsoft's .NET runtime-deps Alpine base, about 20 MB. It has a shell, so GitLab CI and other CIs that run jobs in a container can use it as the job image:

api-tests:
  image:
    name: ghcr.io/kikutano/tinyprobe:0.16.0
    entrypoint: [""]
  script:
    - tinyprobe run tinyprobe/workflows -e tinyprobe/env.ci.yaml --junit reports/tinyprobe.xml
  artifacts:
    when: always
    reports:
      junit: reports/tinyprobe.xml

Alpine binaries

New release assets: tinyprobe-linux-musl-x64.tar.gz and tinyprobe-linux-musl-arm64.tar.gz. install.sh picks them on Alpine and other musl systems. tinyprobe update keeps an Alpine install on the Alpine build.

What's Changed

  • Add a Docker image and Alpine binaries by @kikutano in #23

Full Changelog: v0.15.0...v0.16.0