GC-301f · Module 1

REST Client Tools

3 min read

REST client tools turn Gemini CLI into an API integration layer. Each tool wraps a single API operation — GET a resource, POST a payload, PATCH an update. The tool definition specifies input parameters with JSON Schema types, and the implementation function makes the HTTP call using Node's fetch or a lightweight client like undici. Keep tools atomic: one endpoint per tool. A "create_issue" tool should not also list issues. Separate concerns map to separate tools.

Request handling follows a strict contract. Parse input parameters from the tool call, validate required fields before the request fires, construct the URL with path parameters and query strings, set headers including Content-Type and Authorization, and send the request. The response path mirrors it: check the HTTP status code, parse the response body, extract the fields Gemini needs, and return a structured result. Never return raw API responses — they waste context tokens. Extract the 3-5 fields that matter and return those.

import { z } from "zod";

const CreateTicketInput = z.object({
  title: z.string().describe("Ticket title"),
  priority: z.enum(["low", "medium", "high"]),
  assignee: z.string().optional(),
});

async function createTicket(input: z.infer<typeof CreateTicketInput>) {
  const res = await fetch(`${process.env.API_BASE}/tickets`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${process.env.API_TOKEN}`,
    },
    body: JSON.stringify(input),
  });

  if (!res.ok) {
    const err = await res.text();
    return { error: `${res.status}: ${err}` };
  }

  const ticket = await res.json();
  return {
    id: ticket.id,
    url: ticket.html_url,
    status: ticket.status,
  };
}