ProvenPin Install

ollama.js with a mocked fetch: working versions (tested 2026-10-18)

Drive the ollama npm client with an injected fake fetch to exercise chat, streamed chat over NDJSON, and embed, all offline with no server.

passed3 passed · 0 failed2026-10-18 03:58 UTC
Status
passed
Last passed
2026-10-18 03:58 UTC
Tests
3 / 3
Language
TypeScript
Runtime
node v22.23.3
pinned versions3
ollama@0.6.4@types/node@26.6.5tsx@4.23.15
run it
npm install --no-audit --no-fund --ignore-scripts=false
npm test
test environment
node v22.23.3
linux 6.17.0-1022-azure
x64
runner: github-actions 39095442401

The code

Exactly the files that passed. Your agent can pull them with get_recipe("ollama-js-mocked-fetch") (install), or see them on GitHub.

package.json
{
  "name": "ollama-js-mocked-fetch",
  "private": true,
  "type": "module",
  "scripts": {
    "test": "node --import tsx --test test/*.test.ts"
  },
  "dependencies": {
    "ollama": "0.6.4"
  },
  "devDependencies": {
    "@types/node": "26.6.5",
    "tsx": "4.23.15"
  }
}
src/client.ts
import { Ollama } from "ollama";

export const DEFAULT_HOST = "http://127.0.0.1:11434";

export type OllamaOptions = NonNullable<ConstructorParameters<typeof Ollama>[0]>;
export type OllamaFetch = NonNullable<OllamaOptions["fetch"]>;

export function createOllama(options: OllamaOptions = {}): Ollama {
  return new Ollama({ host: DEFAULT_HOST, ...options });
}

export async function collectChat(
  ollama: Ollama,
  model: string,
  prompt: string,
): Promise<string> {
  const stream = await ollama.chat({
    model,
    messages: [{ role: "user", content: prompt }],
    stream: true,
  });

  let text = "";
  for await (const part of stream) {
    text += part.message.content;
  }
  return text;
}
test/ollama.test.ts
import { test } from "node:test";
import assert from "node:assert/strict";
import {
  createOllama,
  collectChat,
  DEFAULT_HOST,
  type OllamaFetch,
} from "../src/client.ts";

type RecordedCall = {
  url: string;
  method: string | undefined;
  contentType: string | null;
  body: any;
};

type RouteHandler = (body: any) => Response;

type FetchLike = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;

function createFetch(routes: Record<string, RouteHandler>) {
  const calls: RecordedCall[] = [];

  const fetchImpl: FetchLike = async (input, init) => {
    const url =
      typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
    const headers = new Headers(init?.headers);
    const body = typeof init?.body === "string" ? JSON.parse(init.body) : undefined;

    calls.push({
      url,
      method: init?.method,
      contentType: headers.get("content-type"),
      body,
    });

    const route = routes[new URL(url).pathname];
    assert.ok(route, `unexpected request to ${url}`);
    return route!(body);
  };

  return { fetchImpl, calls };
}

function ollamaWith(fetchImpl: FetchLike) {
  return createOllama({ fetch: fetchImpl as unknown as OllamaFetch });
}

function jsonResponse(data: unknown): Response {
  return new Response(JSON.stringify(data), {
    status: 200,
    headers: { "content-type": "application/json" },
  });
}

function ndjsonResponse(chunks: unknown[]): Response {
  const encoder = new TextEncoder();
  const body = new ReadableStream<Uint8Array>({
    start(controller) {
      for (const chunk of chunks) {
        controller.enqueue(encoder.encode(`${JSON.stringify(chunk)}\n`));
      }
      controller.close();
    },
  });
  return new Response(body, {
    status: 200,
    headers: { "content-type": "application/x-ndjson" },
  });
}

test("chat posts the request body and parses the reply", async () => {
  const { fetchImpl, calls } = createFetch({
    "/api/chat": () =>
      jsonResponse({
        model: "llama3.2",
        created_at: "2026-01-01T00:00:00Z",
        message: { role: "assistant", content: "Hello from the fake server" },
        done: true,
      }),
  });

  const ollama = ollamaWith(fetchImpl);
  const reply = await ollama.chat({
    model: "llama3.2",
    messages: [{ role: "user", content: "Say hello" }],
  });

  assert.equal(reply.message.content, "Hello from the fake server");
  assert.equal(calls.length, 1);
  assert.equal(calls[0].url, `${DEFAULT_HOST}/api/chat`);
  assert.equal(calls[0].method, "POST");
  assert.equal(calls[0].contentType, "application/json");
  assert.notEqual(calls[0].body.stream, true);
  assert.equal(calls[0].body.model, "llama3.2");
  assert.deepEqual(calls[0].body.messages, [{ role: "user", content: "Say hello" }]);
});

test("streamed chat concatenates NDJSON chunks in order", async () => {
  const { fetchImpl, calls } = createFetch({
    "/api/chat": () =>
      ndjsonResponse([
        { model: "llama3.2", created_at: "t", message: { role: "assistant", content: "Hel" }, done: false },
        { model: "llama3.2", created_at: "t", message: { role: "assistant", content: "lo, " }, done: false },
        { model: "llama3.2", created_at: "t", message: { role: "assistant", content: "world" }, done: false },
        { model: "llama3.2", created_at: "t", message: { role: "assistant", content: "" }, done: true },
      ]),
  });

  const ollama = ollamaWith(fetchImpl);
  const text = await collectChat(ollama, "llama3.2", "Say hello");

  assert.equal(text, "Hello, world");
  assert.equal(calls.length, 1);
  assert.equal(calls[0].url, `${DEFAULT_HOST}/api/chat`);
  assert.equal(calls[0].method, "POST");
  assert.equal(calls[0].body.stream, true);
  assert.deepEqual(calls[0].body.messages, [{ role: "user", content: "Say hello" }]);
});

test("embed posts input and returns vectors", async () => {
  const { fetchImpl, calls } = createFetch({
    "/api/embed": () =>
      jsonResponse({
        model: "nomic-embed-text",
        embeddings: [[0.1, 0.2, 0.3]],
      }),
  });

  const ollama = ollamaWith(fetchImpl);
  const result = await ollama.embed({ model: "nomic-embed-text", input: "hello world" });

  assert.deepEqual(result.embeddings, [[0.1, 0.2, 0.3]]);
  assert.equal(calls.length, 1);
  assert.equal(calls[0].url, `${DEFAULT_HOST}/api/embed`);
  assert.equal(calls[0].method, "POST");
  assert.equal(calls[0].body.model, "nomic-embed-text");
  assert.equal(calls[0].body.input, "hello world");
});

Connect to ProvenPin

Add the free MCP server so your agent can pull this recipe and others like it. Same setup as the docs.

terminal
claude mcp add --transport http provenpin https://mcp.provenpin.com/mcp

Any other MCP client: Streamable HTTP at https://mcp.provenpin.com/mcp. No API key, no signup.