---
name: basic-create-test
reference: test-direct-client
level: basic
description: 'Test tools in-memory without any HTTP overhead using the `create()` function from `@frontmcp/sdk`.'
tags: [testing, sdk, direct-client]
features:
  - 'Using `create()` to spin up an in-memory `DirectMcpServer` with no HTTP transport'
  - 'Defining tools as classes with the `@Tool` decorator and Zod schemas'
  - 'Calling tools directly via `server.callTool()` and checking the structured output'
  - 'Proper cleanup with `server.dispose()` in each test'
---

# Basic In-Memory Testing with create()

Test tools in-memory without any HTTP overhead using the `create()` function from `@frontmcp/sdk`.

## Code

```typescript
// src/__tests__/direct-client.spec.ts
// Real API:
//   libs/sdk/src/direct/create.ts — `create(config)` returns a DirectMcpServer
//   libs/sdk/src/index.ts — exports `Tool`, `ToolContext`, `z` (no `tool()` factory)
import { create, Tool, ToolContext, z } from '@frontmcp/sdk';

@Tool({
  name: 'add',
  description: 'Add numbers',
  inputSchema: { a: z.number(), b: z.number() },
  outputSchema: { sum: z.number() },
})
class AddTool extends ToolContext {
  async execute(input: { a: number; b: number }) {
    return { sum: input.a + input.b };
  }
}

describe('Direct Client Testing', () => {
  it('calls a tool via create()', async () => {
    const server = await create({
      info: { name: 'test', version: '1.0.0' },
      tools: [AddTool],
      cacheKey: 'test-direct',
    });

    const result = await server.callTool('add', { a: 2, b: 3 });
    // The framework wraps the tool's `{ sum: 5 }` return into a CallToolResult
    // with `structuredContent` set to the typed output.
    expect(result.structuredContent).toEqual({ sum: 5 });

    await server.dispose();
  });

  it('handles multiple tool calls', async () => {
    const server = await create({
      info: { name: 'test', version: '1.0.0' },
      tools: [AddTool],
      cacheKey: 'test-direct-multi',
    });

    const r1 = await server.callTool('add', { a: 10, b: 20 });
    expect(r1.structuredContent).toEqual({ sum: 30 });

    const r2 = await server.callTool('add', { a: -5, b: 5 });
    expect(r2.structuredContent).toEqual({ sum: 0 });

    await server.dispose();
  });
});
```

## What This Demonstrates

- Using `create()` to spin up an in-memory `DirectMcpServer` with no HTTP transport
- Defining tools as classes with the `@Tool` decorator and Zod schemas
- Calling tools directly via `server.callTool()` and checking the structured output
- Proper cleanup with `server.dispose()` in each test

## Related

- See `test-direct-client` for the full direct client testing reference
