Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,38 +1,38 @@
# Changelog

## [0.5.0](https://github.com/CodelyTV/typescript-mcp-test-client/compare/v0.4.0...v0.5.0) (2025-08-18)
## [0.5.0](https://github.com/CodelyTV/typescript-mcp-client/compare/v0.4.0...v0.5.0) (2025-08-18)


### Features

* export in one level ([c37fe6f](https://github.com/CodelyTV/typescript-mcp-test-client/commit/c37fe6ff8c1c81fc9e9c734dbe8793695e4cbda2))
* export in one level ([c37fe6f](https://github.com/CodelyTV/typescript-mcp-client/commit/c37fe6ff8c1c81fc9e9c734dbe8793695e4cbda2))

## [0.4.0](https://github.com/CodelyTV/typescript-mcp-test-client/compare/v0.3.0...v0.4.0) (2025-08-18)
## [0.4.0](https://github.com/CodelyTV/typescript-mcp-client/compare/v0.3.0...v0.4.0) (2025-08-18)


### Features

* disable provenance while the repo is private ([42f75a7](https://github.com/CodelyTV/typescript-mcp-test-client/commit/42f75a7ed8aab71725f620d056a6a02f5b0125a8))
* disable provenance while the repo is private ([42f75a7](https://github.com/CodelyTV/typescript-mcp-client/commit/42f75a7ed8aab71725f620d056a6a02f5b0125a8))

## [0.3.0](https://github.com/CodelyTV/typescript-mcp-test-client/compare/v0.2.0...v0.3.0) (2025-08-18)
## [0.3.0](https://github.com/CodelyTV/typescript-mcp-client/compare/v0.2.0...v0.3.0) (2025-08-18)


### Features

* export using subfolders ([2f57fa6](https://github.com/CodelyTV/typescript-mcp-test-client/commit/2f57fa6a1739b5a1cac82ff2fa9a29a1599e92e4))
* export using subfolders ([2f57fa6](https://github.com/CodelyTV/typescript-mcp-client/commit/2f57fa6a1739b5a1cac82ff2fa9a29a1599e92e4))

## [0.2.0](https://github.com/CodelyTV/typescript-mcp-test-client/compare/v0.1.0...v0.2.0) (2025-08-18)
## [0.2.0](https://github.com/CodelyTV/typescript-mcp-client/compare/v0.1.0...v0.2.0) (2025-08-18)


### Features

* add initial version ([e1366aa](https://github.com/CodelyTV/typescript-mcp-test-client/commit/e1366aaba676d3a29ec14a5a2a880d9e1fb8bf2a))
* add initial version ([e1366aa](https://github.com/CodelyTV/typescript-mcp-client/commit/e1366aaba676d3a29ec14a5a2a880d9e1fb8bf2a))

## [0.1.0](https://github.com/CodelyTV/typescript-mcp-test-client/compare/v0.0.1...v0.1.0) (2025-08-18)
## [0.1.0](https://github.com/CodelyTV/typescript-mcp-client/compare/v0.0.1...v0.1.0) (2025-08-18)


### Features

* add initial version ([e1366aa](https://github.com/CodelyTV/typescript-mcp-test-client/commit/e1366aaba676d3a29ec14a5a2a880d9e1fb8bf2a))
* add initial version ([e1366aa](https://github.com/CodelyTV/typescript-mcp-client/commit/e1366aaba676d3a29ec14a5a2a880d9e1fb8bf2a))

## Changelog
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
# @codelytv/mcp-test-client
# @codelytv/mcp-client

A TypeScript test client for Model Context Protocol (MCP) servers that provides a convenient way to test MCP functionality in your test suites.

## Installation

```bash
npm install --save-dev @codelytv/mcp-test-client
npm install --save-dev @codelytv/mcp-client
```

## Usage

### Basic Example

```typescript
import { McpTestClient } from '@codelytv/mcp-test-client';
import { McpClient } from '@codelytv/mcp-client';

const mcpClient = new McpTestClient("stdio", [
const mcpClient = new McpClient("stdio", [
"npx",
"ts-node",
"./src/app/mcp/server.ts",
Expand Down Expand Up @@ -43,18 +43,18 @@ await mcpClient.disconnect();
### HTTP Transport

```typescript
const mcpClient = new McpTestClient("http", ["http://localhost:3000/mcp"]);
const mcpClient = new McpClient("http", ["http://localhost:3000/mcp"]);
```

## API

### McpTestClient
### McpClient

The main client class for interacting with MCP servers.

#### Constructor

- `new McpTestClient(transport: "stdio" | "http", args: string[])`
- `new McpClient(transport: "stdio" | "http", args: string[])`

#### Methods

Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "@codelytv/mcp-test-client",
"name": "@codelytv/mcp-client",
"version": "0.5.0",
"description": "A TypeScript test client for Model Context Protocol (MCP) servers",
"keywords": [
Expand All @@ -23,9 +23,9 @@
"author": "codelytv",
"license": "GPL-3.0",
"bugs": {
"url": "https://github.com/CodelyTV/typescript-mcp-test-client/issues"
"url": "https://github.com/CodelyTV/typescript-mcp-client/issues"
},
"homepage": "https://github.com/CodelyTV/typescript-mcp-test-client#readme",
"homepage": "https://github.com/CodelyTV/typescript-mcp-client#readme",
"dependencies": {
"@codelytv/primitives-type": "^3.1.0",
"@modelcontextprotocol/sdk": "^1.17.2"
Expand Down
62 changes: 27 additions & 35 deletions src/McpTestClient.ts → src/McpClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp";
import { Transport } from "@modelcontextprotocol/sdk/shared/transport";

import { McpTestPromptGetResponse } from "./prompts/McpTestPromptGetResponse";
import { McpTestPromptsListResponse } from "./prompts/McpTestPromptsListResponse";
import { McpTestResourceTemplatesListResponse } from "./resource-templates/McpTestResourceTemplatesListResponse";
import { McpTestResourcesListResponse } from "./resources/McpTestResourcesListResponse";
import { McpTestResourcesReadResponse } from "./resources/McpTestResourcesReadResponse";
import { McpTestToolCallResponse } from "./tools/McpTestToolCallResponse";
import { McpTestToolsListResponse } from "./tools/McpTestToolsListResponse";

export class McpTestClient {
import { McpPromptGetResponse } from "./prompts/McpPromptGetResponse";
import { McpPromptsListResponse } from "./prompts/McpPromptsListResponse";
import { McpResourceTemplatesListResponse } from "./resource-templates/McpResourceTemplatesListResponse";
import { McpResourcesListResponse } from "./resources/McpResourcesListResponse";
import { McpResourcesReadResponse } from "./resources/McpResourcesReadResponse";
import { McpToolCallResponse } from "./tools/McpToolCallResponse";
import { McpToolsListResponse } from "./tools/McpToolsListResponse";

export class McpClient {
private readonly client: Client;
private readonly transport: Transport;

Expand All @@ -23,7 +23,7 @@ export class McpTestClient {
) {
this.client = new Client(
{
name: "mcp-test-client",
name: "mcp-client",
version: "1.0.0",
},
{
Expand Down Expand Up @@ -53,27 +53,25 @@ export class McpTestClient {
await this.client.close();
}

async listTools(): Promise<McpTestToolsListResponse> {
async listTools(): Promise<McpToolsListResponse> {
const response = await this.client.listTools();

return McpTestToolsListResponse.fromPrimitives(
response as Primitives<McpTestToolsListResponse>,
);
return McpToolsListResponse.fromPrimitives(response as Primitives<McpToolsListResponse>);
}

async listResources(): Promise<McpTestResourcesListResponse> {
async listResources(): Promise<McpResourcesListResponse> {
const response = await this.client.listResources();

return McpTestResourcesListResponse.fromPrimitives(
response as Primitives<McpTestResourcesListResponse>,
return McpResourcesListResponse.fromPrimitives(
response as Primitives<McpResourcesListResponse>,
);
}

async listResourceTemplates(): Promise<McpTestResourceTemplatesListResponse> {
async listResourceTemplates(): Promise<McpResourceTemplatesListResponse> {
const response = await this.client.listResourceTemplates();

return McpTestResourceTemplatesListResponse.fromPrimitives(
response as Primitives<McpTestResourceTemplatesListResponse>,
return McpResourceTemplatesListResponse.fromPrimitives(
response as Primitives<McpResourceTemplatesListResponse>,
);
}

Expand All @@ -96,30 +94,27 @@ export class McpTestClient {
return response.completion.values;
}

async readResource(uri: string): Promise<McpTestResourcesReadResponse> {
async readResource(uri: string): Promise<McpResourcesReadResponse> {
const response = await this.client.readResource({ uri });

return McpTestResourcesReadResponse.fromPrimitives(
response as Primitives<McpTestResourcesReadResponse>,
return McpResourcesReadResponse.fromPrimitives(
response as Primitives<McpResourcesReadResponse>,
);
}

async callTool(
name: string,
args: Record<string, unknown> = {},
): Promise<McpTestToolCallResponse> {
async callTool(name: string, args: Record<string, unknown> = {}): Promise<McpToolCallResponse> {
const response = await this.client.callTool({
name,
arguments: args,
});

return McpTestToolCallResponse.fromPrimitives(response as Primitives<McpTestToolCallResponse>);
return McpToolCallResponse.fromPrimitives(response as Primitives<McpToolCallResponse>);
}

async listPrompts(): Promise<McpTestPromptsListResponse> {
async listPrompts(): Promise<McpPromptsListResponse> {
const response = await this.client.listPrompts();

return McpTestPromptsListResponse.fromPrimitives({
return McpPromptsListResponse.fromPrimitives({
prompts: response.prompts.map((prompt: any) => ({
name: prompt.name,
title: prompt.title ?? "",
Expand All @@ -129,18 +124,15 @@ export class McpTestClient {
});
}

async getPrompt(
name: string,
args: Record<string, unknown> = {},
): Promise<McpTestPromptGetResponse> {
async getPrompt(name: string, args: Record<string, unknown> = {}): Promise<McpPromptGetResponse> {
const response = await this.client.getPrompt({
name,
arguments: Object.fromEntries(
Object.entries(args).map(([key, value]) => [key, String(value)]),
),
});

return McpTestPromptGetResponse.fromPrimitives({
return McpPromptGetResponse.fromPrimitives({
messages: response.messages.map((message: any) => ({
role: message.role,
content:
Expand Down
30 changes: 15 additions & 15 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
export { McpTestClient } from "./McpTestClient";
export { McpTestPromptGetResponse } from "./prompts/McpTestPromptGetResponse";
export { McpTestPromptListResponse } from "./prompts/McpTestPromptListResponse";
export { McpTestPromptMessage } from "./prompts/McpTestPromptMessage";
export { McpTestPromptsListResponse } from "./prompts/McpTestPromptsListResponse";
export { McpTestResourceTemplateListResponse } from "./resource-templates/McpTestResourceTemplateListResponse";
export { McpTestResourceTemplatesListResponse } from "./resource-templates/McpTestResourceTemplatesListResponse";
export { McpTestResourceListResponse } from "./resources/McpTestResourceListResponse";
export { McpTestResourcesListResponse } from "./resources/McpTestResourcesListResponse";
export { McpTestResourcesReadResponse } from "./resources/McpTestResourcesReadResponse";
export { McpTestResourcesReadResponseContent } from "./resources/McpTestResourcesReadResponseContent";
export { McpTestToolCallResponse } from "./tools/McpTestToolCallResponse";
export { McpTestToolContent } from "./tools/McpTestToolContent";
export { McpTestToolListResponse } from "./tools/McpTestToolListResponse";
export { McpTestToolsListResponse } from "./tools/McpTestToolsListResponse";
export { McpClient } from "./McpClient";
export { McpPromptGetResponse } from "./prompts/McpPromptGetResponse";
export { McpPromptListResponse } from "./prompts/McpPromptListResponse";
export { McpPromptMessage } from "./prompts/McpPromptMessage";
export { McpPromptsListResponse } from "./prompts/McpPromptsListResponse";
export { McpResourceTemplateListResponse } from "./resource-templates/McpResourceTemplateListResponse";
export { McpResourceTemplatesListResponse } from "./resource-templates/McpResourceTemplatesListResponse";
export { McpResourceListResponse } from "./resources/McpResourceListResponse";
export { McpResourcesListResponse } from "./resources/McpResourcesListResponse";
export { McpResourcesReadResponse } from "./resources/McpResourcesReadResponse";
export { McpResourcesReadResponseContent } from "./resources/McpResourcesReadResponseContent";
export { McpToolCallResponse } from "./tools/McpToolCallResponse";
export { McpToolContent } from "./tools/McpToolContent";
export { McpToolListResponse } from "./tools/McpToolListResponse";
export { McpToolsListResponse } from "./tools/McpToolsListResponse";
23 changes: 23 additions & 0 deletions src/prompts/McpPromptGetResponse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Primitives } from "@codelytv/primitives-type";

import { McpPromptMessage } from "./McpPromptMessage";

export class McpPromptGetResponse {
constructor(public readonly messages: McpPromptMessage[]) {}

static fromPrimitives(primitives: Primitives<McpPromptGetResponse>): McpPromptGetResponse {
return new McpPromptGetResponse(
primitives.messages.map((message) => McpPromptMessage.fromPrimitives(message)),
);
}

toPrimitives(): Primitives<McpPromptGetResponse> {
return {
messages: this.messages.map((message) => message.toPrimitives()),
};
}

firstPromptText(): string {
return this.messages[0].content.text;
}
}
14 changes: 14 additions & 0 deletions src/prompts/McpPromptListResponse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Primitives } from "@codelytv/primitives-type";

export class McpPromptListResponse {
constructor(
public readonly name: string,
public readonly title: string,
public readonly description: string,
public readonly args: object,
) {}

static fromPrimitives(prompt: Primitives<McpPromptListResponse>): McpPromptListResponse {
return new McpPromptListResponse(prompt.name, prompt.title, prompt.description, prompt.args);
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { Primitives } from "@codelytv/primitives-type";

export class McpTestPromptMessage {
export class McpPromptMessage {
constructor(
public readonly role: "user" | "assistant",
public readonly content: { type: string; text: string },
) {}

static fromPrimitives(message: Primitives<McpTestPromptMessage>): McpTestPromptMessage {
return new McpTestPromptMessage(message.role, message.content);
static fromPrimitives(message: Primitives<McpPromptMessage>): McpPromptMessage {
return new McpPromptMessage(message.role, message.content);
}

toPrimitives(): Primitives<McpTestPromptMessage> {
toPrimitives(): Primitives<McpPromptMessage> {
return {
role: this.role,
content: this.content,
Expand Down
17 changes: 17 additions & 0 deletions src/prompts/McpPromptsListResponse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Primitives } from "@codelytv/primitives-type";

import { McpPromptListResponse } from "./McpPromptListResponse";

export class McpPromptsListResponse {
constructor(public readonly prompts: McpPromptListResponse[]) {}

static fromPrimitives(primitives: Primitives<McpPromptsListResponse>): McpPromptsListResponse {
return new McpPromptsListResponse(
primitives.prompts.map((prompt) => McpPromptListResponse.fromPrimitives(prompt)),
);
}

names(): string[] {
return this.prompts.map((prompt) => prompt.name);
}
}
25 changes: 0 additions & 25 deletions src/prompts/McpTestPromptGetResponse.ts

This file was deleted.

Loading