ProvenPin Install

MCP server with in-memory tools: working versions (tested 2026-10-17)

Build an McpServer from @modelcontextprotocol/sdk that registers two zod-typed tools and one resource, then exercise it offline through a Client linked by InMemoryTransport.createLinkedPair().

passed4 passed · 0 failed2026-10-17 05:58 UTC
Status
passed
Last passed
2026-10-17 05:58 UTC
Tests
4 / 4
Language
TypeScript
Runtime
node v22.23.3
pinned versions4
@modelcontextprotocol/sdk@1.32.1zod@4.6.7@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 39008163431

The code

Exactly the files that passed. Your agent can pull them with get_recipe("mcp-sdk-inmemory-tools") (install), or see them on GitHub.

package.json
{
  "name": "mcp-sdk-inmemory-tools",
  "private": true,
  "type": "module",
  "scripts": {
    "test": "node --import tsx --test test/*.test.ts"
  },
  "dependencies": {
    "@modelcontextprotocol/sdk": "1.32.1",
    "zod": "4.6.7"
  },
  "devDependencies": {
    "@types/node": "26.6.5",
    "tsx": "4.23.15"
  }
}
src/server.ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";

export function createServer(): McpServer {
  const server = new McpServer({ name: "inmemory-tools", version: "1.0.0" });

  server.registerTool(
    "add",
    {
      title: "Add",
      description: "Add two numbers together",
      inputSchema: { a: z.number(), b: z.number() },
    },
    async ({ a, b }) => ({
      content: [{ type: "text", text: `${a + b}` }],
    }),
  );

  server.registerTool(
    "greet",
    {
      title: "Greet",
      description: "Greet a person by name",
      inputSchema: { name: z.string() },
    },
    async ({ name }) => ({
      content: [{ type: "text", text: `Hello, ${name}!` }],
    }),
  );

  server.registerResource(
    "greeting",
    "greeting://hello",
    {
      title: "Greeting",
      description: "A static greeting resource",
      mimeType: "text/plain",
    },
    async (uri) => ({
      contents: [{ uri: uri.href, text: "Hello from the resource" }],
    }),
  );

  return server;
}
test/server.test.ts
import { test } from "node:test";
import assert from "node:assert/strict";
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { InMemoryTransport } from "@modelcontextprotocol/sdk/inMemory.js";
import { createServer } from "../src/server.ts";

async function connect() {
  const server = createServer();
  const [clientTransport, serverTransport] =
    InMemoryTransport.createLinkedPair();
  const client = new Client({ name: "test-client", version: "1.0.0" });
  await server.connect(serverTransport);
  await client.connect(clientTransport);
  return { client, server };
}

test("lists the two registered tools", async () => {
  const { client, server } = await connect();
  const { tools } = await client.listTools();
  const names = tools.map((tool) => tool.name).sort();
  assert.deepEqual(names, ["add", "greet"]);
  await client.close();
  await server.close();
});

test("callTool returns text content", async () => {
  const { client, server } = await connect();
  const result = await client.callTool({
    name: "add",
    arguments: { a: 2, b: 3 },
  });
  assert.ok(!result.isError);
  const [first] = result.content as Array<{ type: string; text: string }>;
  assert.equal(first.type, "text");
  assert.equal(first.text, "5");
  await client.close();
  await server.close();
});

test("readResource returns the registered resource", async () => {
  const { client, server } = await connect();
  const result = await client.readResource({ uri: "greeting://hello" });
  const [first] = result.contents as Array<{ uri: string; text?: string }>;
  assert.equal(first.uri, "greeting://hello");
  assert.equal(first.text, "Hello from the resource");
  await client.close();
  await server.close();
});

test("callTool reports an error result for invalid input", async () => {
  const { client, server } = await connect();
  const result = await client.callTool({
    name: "greet",
    arguments: { name: 123 },
  });
  assert.equal(result.isError, true);
  await client.close();
  await server.close();
});

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.