Use gtme from Claude Code

Install the gtme plugin in Claude Code, describe a goal in plain words, and take the pipeline it writes from plan to an armed run

What you'll learn

You use Claude Code and want it to build and run a gtme pipeline for you, and you want to know which parts stay yours.

  • how to add the gtme plugin and which skill fires when
  • what a session looks like from your goal to an armed run
  • what you say to Claude Code, and where you step in

Goal: you give Claude Code this request, and you end with for-sdr.csv, one opening line per senior signup. Claude Code turns it into a pipeline file and runs it:

Every Monday I export trial signups to signups.csv. Keep the VPs, heads,
and directors, write each one a line our SDR can open with, and put
them in a CSV for the SDR.

Before you start

You need Claude Code, a terminal, and gtme installed. For agents has the rules Claude Code follows. This guide is what the session looks like from your side of the chat.

This guide needs no keys and spends $0. The pipeline reads a CSV and writes a CSV, with no vendor and no model. The only thing it sends is a file on your machine, for-sdr.csv.

You do steps 1 to 3 yourself. From step 4 on, Claude Code runs every command shown and reads the output back to you; the blocks show what it ran. We describe what Claude Code says in plain words, because its wording changes from run to run. Every gtme output on the page is real.

Where you step in:

  • Say yes to the plan. The skill reads its plan back before it builds anything.
  • Read the dry-run. It shows exactly what would be written or sent. On a pipeline with a vendor or a model step, the dry-run is also the first command that costs money, and the agent tells you what it will spend before it runs it.
  • Say send. On a vendor target, such as an Instantly campaign, nothing arms until you reply to "Send it?" after reading the dry-run.
  • Enter keys yourself. When plan names a missing key, run gtme secret set KEY_NAME in your own terminal and paste the key there, never in the chat.

These are the agent's rules plus your read; gtme itself can't tell who ran a command.

Steps

  1. Install gtme. Follow Install, then check it:

    gtme version
    

    The output is similar to the following:

    gtme v0.6.1
    

    If gtme isn't found, finish Install before going on, because every skill calls it.

  2. Add the plugin. In Claude Code, enter these two lines:

    /plugin marketplace add gtme-run/gtme
    /plugin install gtme@gtme-run
    

    Claude Code now has four skills, and it picks one from what you say, so you rarely call one by name:

    You say something likeSkill that fires
    "Find the senior people in this signup list"/gtme:create-pipeline
    "Run it," "does this work," "send it"/gtme:run-pipeline
    "gtme doesn't have Hunter"/gtme:create-adapter
    "What did last week's run cost?"/gtme:analyze

    The skills read what gtme can do from the gtme you installed, so they match your version (ADR-007, the decision record behind that).

  3. Say what you want, in your words. Save this as signups.csv in an empty folder, and start Claude Code in that folder:

    First Name,Email,Job Title,Company Website
    Jane,jane.doe@acme.com,VP Marketing,acme.com
    Bob,bob@globex.io,Head of Growth,globex.io
    Carol,carol@initech.dev,Software Engineer,initech.dev
    Dev,dev@umbrella.co,Director of Sales,umbrella.co
    Erin,erin.wu@hooli.com,Marketing Intern,hooli.com
    

    Then enter the request from the goal. The create-pipeline skill asks what it can't infer, such as which tools you use and how many people a run should cover. Then it reads its plan back in one paragraph and waits for your yes. It doesn't ask you to read YAML.

  4. Let it build and plan, one step at a time. The skill writes a file and runs gtme plan after each step it adds. Plan spends nothing and calls no network. Here's the file it ends with, trial-signups.yaml:

    name: trial-signups
    version: 1
    source:
      use: csv/source
      with:
        path: signups.csv
        columns: { title: Job Title }
    steps:
      - id: senior
        use: sql/filter
        with:
          query: >
            SELECT identity_id FROM current_values
            WHERE field = 'title'
              AND (value LIKE 'VP%' OR value LIKE 'Head of%' OR value LIKE 'Director%')
      - id: opener
        use: text/compose
        uses: [first_name, title]
        provides: [opener]
        with:
          template: >
            {{ record.first_name | default: "Hi there" }}, thanks for trying us.
            Most teams with a {{ record.title }} start with the weekly report, so that's where I'd look first.
      - id: out
        use: csv/deliver
        with:
          path: for-sdr.csv
        variables:
          email: email
          first_name: first_name
          opener: trial-signups.opener
        idempotency: email
    
    Pipeline trial-signupsPipeline trial-signups: source csv/source, then senior (sql/filter), then opener (text/compose), then delivers with out (csv/deliver), once per email. Every step writes to the ledger, and cached, AI, and deliver steps read it first.ledgersourcecsv/sourceseniorsql/filteropenertext/composeoutcsv/deliveridempotency: email
    Pipeline trial-signups: source csv/source, then senior (sql/filter), then opener (text/compose), then delivers with out (csv/deliver), once per email. Every step writes to the ledger, and cached, AI, and deliver steps read it first.

    You don't need to read it; it's here so you recognize it later. senior keeps rows by title, opener fills in a sentence per person with text/compose, and out writes the file. Those are the filter, compose, and deliver roles.

    If the draft leaves out the columns: line, plan stops on it:

    gtme plan trial-signups.yaml
    
    gtme: step "opener": needs title, which no earlier step provides (available: company_website, csv.job_title, email, first_name)
    

    The error names the fix: your header Job Title came in as csv.job_title, so the agent maps it to title and plans again. The output ends with the following:

    ...
    send surface: 1 deliver step(s)
      out → csv/deliver (touch scope: trial-signups)
    
    available fields after the last step: company_website, email, first_name, title, trial-signups.opener
    plan ok — nothing has been spent
    

    send surface is the list of places this pipeline can write to. Here there's one, and it's a local file.

  5. Rehearse it with --simulate. When plan is clean, Claude Code says it's built and moves on by itself, without waiting for you. The run-pipeline skill runs the whole file offline, the lowest rung of the gate ladder:

    gtme run trial-signups.yaml --simulate
    

    The output is similar to the following:

    simulate: recorded responses only — no network, no spend, nothing sends, nothing persists
    ...
    step    adapter       in  out  empty  cached  filtered  failed  cost  avoided
    source  csv/source    0   5    -      0       -         -       $0    -
    senior  sql/filter    5   3    -      0       2         -       $0    -
    opener  text/compose  3   3    -      0       -         -       $0    -
    out     csv/deliver   3   0    -      0       -         -       $0    -
    ...
    total: $0 spent
    

    Five came in, senior filtered Carol and Erin, and three were held at out. Nothing persists, so for-sdr.csv doesn't exist yet.

  6. Read the dry-run. A dry-run runs every step for real except delivery, and prints what each delivery would carry:

    gtme run trial-signups.yaml --dry-run
    

    The output is similar to the following:

    dry run: deliver steps will resolve and receipt their variables, but nothing sends
    ...
    out: resolved variables for 3 record(s) — review, then run again without --dry-run to arm:
      jane.doe@acme.com
        email: "jane.doe@acme.com"
        first_name: "Jane"
        opener: "Jane, thanks for trying us. Most teams with a VP Marketing start with the weekly report, so that's where I'd look first."
    ...
    total: $0 spent
    

    The agent reads these lines back to you. This is the moment to say "make the opener shorter" or "drop the directors," and Claude Code edits the file, plans again, and brings you a new dry-run.

  7. Arm it. Arming, the run that writes and sends for real, is the same command with no flag:

    gtme run trial-signups.yaml
    

    The output is similar to the following:

    ...
    step    adapter       in  out  empty  cached  filtered  failed  cost  avoided
    source  csv/source    0   5    -      0       -         -       $0    -
    senior  sql/filter    5   3    -      0       2         -       $0    -
    opener  text/compose  3   0    -      3       -         -       $0    ?
    out     csv/deliver   3   3    -      0       -         -       $0    -
    total: $0 spent, $0.0000+? avoided via cache (3 records skipped)
    

    out wrote 3 rows. opener shows cached 3 because the dry-run already wrote those lines to the ledger, and the armed run read them back. The ? means text/compose has no price to report, and because it calls nothing, the skip saved $0.

    The target here is a file on your machine, so the agent can arm it after you've seen the dry-run's total line, here $0. On a vendor target, it stops and asks "Send it?" first, and an earlier "go ahead, don't ask again" doesn't count as that reply.

What you have now

You have trial-signups.yaml, and a for-sdr.csv your SDR can work from. It holds Jane, Bob, and Dev, each with an opener. The first column, identity_key, is how gtme recognizes each person across runs, here their email (Identity keys).

identity_key,email,first_name,opener
jane.doe@acme.com,jane.doe@acme.com,Jane,"Jane, thanks for trying us. Most teams with a VP Marketing start with the weekly report, so that's where I'd look first."
...

To check it, ask Claude Code to run it again. The receipt shows out with 0 out and out: 3 already delivered, because idempotency: email means nobody gets written twice:

...
out     csv/deliver   3   0    -      0       -         -       $0    -
out: 3 already delivered
...

Next Monday, replace signups.csv with the new export, start Claude Code in the same folder, and say "run the trial signups." New rows get openers, and last week's people are skipped.

Next

  • Your CSV swaps the SQL rule and the fill-in sentence for a model that judges and writes, with one key you enter.
  • Your stack delivers to a vendor, where the arm gate is yours.
  • gtme secret stores the keys a vendor pipeline asks for, from your own terminal.