CLI to Query Open Models with Together Link

A minimal Node.js CLI that calls the free Together API to run open‑source language models

Welcome to another official UVF IT guide! In this short tutorial we’ll build a tiny command‑line tool that talks to the Together Link service and returns model completions, just like the official product but stripped down to the essentials.

You’ll finish a working clone in about 45 minutes using only Node ≥ 18, npm, and the free tier of the Together API – no paid services, no databases, just pure HTTP.

Before you start

Architecture Overview
YOUR MACHINE EXTERNAL SERVICES read API key call helper HTTP POST /v1/completions JSON reply print text CLI App (Node.js) Env Config (.env) Fetch Wrapper Together API (open models) Model Response
1

Phase 1: Scaffold the project

We start by creating a fresh npm project so we have a package.json to track dependencies. The helper script also adds a .gitignore and installs dotenv – a tiny library that lets us load the API key from a local .env file without committing it.

Running this script once gives you a ready‑to‑code directory with Node’s native fetch available (Node ≥ 18) and a place to store secrets safely.

setup.sh

#!/usr/bin/env bash
set -e
# Create project folder if not already there
mkdir -p together-cli && cd together-cli
# Initialise npm with defaults
npm init -y > /dev/null
# Install dotenv for env file handling
npm install dotenv@latest > /dev/null
# Create .gitignore to keep .env private
cat <<'EOF' > .gitignore
node_modules/
.env
EOF
# Add starter .env template
cat <<'EOF' > .env
# Paste your free Together API key here
TOGETHER_API_KEY=YOUR_KEY_HERE
EOF
echo "Setup complete. Run 'node fetch.js' after adding your API key."
2

Phase 2: Core request logic

Now we write the heart of the CLI: a small wrapper that reads the API key from the environment and posts a prompt to Together’s /v1/completions endpoint. The function returns the raw text so the CLI can simply console.log it.

We keep the code under 25 lines, use native fetch, and handle basic error cases so beginners can see what’s happening under the hood.

fetch.js

import { config } from 'dotenv';
config(); // load .env into process.env

const API_KEY = process.env.TOGETHER_API_KEY;
if (!API_KEY) {
  console.error('❌ Missing TOGETHER_API_KEY in .env');
  process.exit(1);
}

/**
 * Calls Together's completions endpoint.
 * @param {string} prompt - The text you want the model to continue.
 * @param {string} model - Model identifier, e.g., 'togethercomputer/llama-2-7b-chat'.
 * @returns {Promise<string>} - The generated completion.
 */
export async function getCompletion(prompt, model = 'togethercomputer/llama-2-7b-chat') {
  const response = await fetch('https://api.together.xyz/v1/completions', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${API_KEY}`,
    },
    body: JSON.stringify({
      model,
      prompt,
      max_tokens: 64,
    }),
  });

  if (!response.ok) {
    const err = await response.text();
    throw new Error(`API error ${response.status}: ${err}`);
  }
  const data = await response.json();
  return data.choices?.[0]?.text?.trim() || '';
}

// Simple CLI usage when run directly
if (import.meta.url === process.argv[1]) {
  const userPrompt = process.argv.slice(2).join(' ') || 'Hello, world!';
  getCompletion(userPrompt)
    .then((txt) => console.log('🤖', txt))
    .catch((e) => console.error('❗', e.message));
}
3

Phase 3: CLI argument handling

In this step we turn our Node script into a real command‑line tool. We read the prompt the user typed, fall back to a helpful usage message when nothing is supplied, and then hand the prompt off to the helper that talks to the Together API. Finally we print the model’s reply so the user sees the answer right in the terminal.

The code stays tiny—about fifteen lines—so it’s easy to follow and modify. By keeping the API call in a separate helper module we keep the CLI focused on input/output concerns, which makes future extensions (like adding flags) straightforward.

index.js

#!/usr/bin/env node
const { callModel } = require('./helper')

// Grab the prompt from the command line arguments
const args = process.argv.slice(2)
if (args.length === 0) {
  console.error('Usage: ./index.js "your prompt"')
  process.exit(1)
}
const prompt = args.join(' ')

// Optional: allow overriding the model via an env var
const model = process.env.TOGETHER_MODEL || 'togethercomputer/llama-2-7b'

callModel({ model, prompt })
  .then(response => {
    console.log('🤖', response)
  })
  .catch(err => {
    console.error('Error:', err.message)
    process.exit(1)
  })
4

Phase 4: Run locally

Now that the CLI is wired up, give it a spin. Make sure the script is executable, export your Together API key, and invoke the file with a short prompt. The script will contact the free Together endpoint, wait for the response, and print it prefixed with a robot emoji for clarity.

If everything is set up correctly you’ll see a one‑line answer from the model almost instantly. This demonstrates that the minimal clone works end‑to‑end without any extra tooling.

chmod +x index.js
export TOGETHER_API_KEY=YOUR_KEY_HERE
./index.js "What is the capital of France?"
5

Phase 5: Verify and extend

Check the output you just got – it should start with the 🤖 emoji followed by a sensible answer. Once you’ve confirmed the basic flow, try swapping the model or tweaking parameters like temperature to see how the response changes.

You can experiment by setting TOGETHER_MODEL to another open model name or by editing the helper to pass additional JSON fields. These small tweaks let you explore the full power of the Together API while keeping the CLI minimal.

export TOGETHER_MODEL=togethercomputer/mpt-7b
./index.js "Tell me a short joke."

Verifying the Stack

CheckCommand / Why it matters
npm init succeeded and index.js is executablels -l index.js shows -rwx permissions
CLI prints usage when no argument is given./index.js outputs "Usage: ./index.js \"your prompt\""
A real model response appears for a valid promptTOGETHER_API_KEY=... ./index.js "Hello" prints a line starting with 🤖

What’s next?

You now have a functional clone of Together Link’s core feature. From here you can add streaming output, support multiple models, or publish the CLI as an npm package for easy reuse.