MCP Client REPL

MCP Client REPL
“What has been will be again, what has been done will be done again; there is nothing new under the sun.”
- Ecclesiastes 1:9

I love time looping stories. Groundhog Day is not only the best romantic comedy ever made—that being a reasonably low bar to hurdle—but ranks as one of my all-time favourite movies.

Looping is equally awesome in code. Remember the sparks that flew the day your young naive self discovered that instead of writing the same code out 10 times, you could create a loop and just do it once! Game changing!

For the trifecta of looping awesome, I'd like to throw in the CLI (Command Line Interface). The amazing experience of a loop of waiting for input, running a command, producing output, and waiting for input again (most often for me in the form of the bash shell) has occupied such a significant proportion of my life that I am really scared to even attempt to quantify it.

The CLI falls into a broader category of a REPL (Read-Eval-Print Loop)—an interactive environment where you can input commands and see instant results as output. Wash, rinse, repeat. If you've ever typed node and seen this:

mark@hope:~$ node
Welcome to Node.js v20.12.0.
Type ".help" for more information.
> 

Then welcome to the Node REPL! There are many others...

The MCP client loop: Where Is It?

In developing a Model Context Protocol (MCP) server, one of the not-so-pleasant surprises I discovered was the apparent lack of a simple client REPL-style tool for quick, manual MCP server testing.

Existing MCP client apps often weren't clear on the state of an MCP server interaction, and didn't clearly identify tools or expose tool call results. So I found myself testing my MCP server by chatting through an MCP-client-enabled agent to an LLM determine if my tool calls worked, and then had to guess the MCP response based on the LLM's output. At the testing stage, I didn't want any LLM interaction; I just wanted to hit my MCP server to make sure it responded correctly to tool listings, calls, etc.

So I made an MCP client REPL. Not rocket surgery—just a thin wrapper around an existing library to quickly verify MCP server functions.

The result was a lightweight, standalone Node.js MCP client that connects to an MCP server using either Server-Sent Events (SSE) or Streamable HTTP, with optional authentication via an x-api-key header (that's what I was using for authentication, so I supported this only).


Goal

I wanted a quick, reliable way to:

  • Connect to an MCP server I’m developing (e.g. http://localhost:8206/mcp)
  • Use either Server-Sent Events (SSE) or Streamable HTTP transport
  • Pass in an API key header
  • Run quick protocol-level commands e.g. list available tools, invoke one, or check connection status
  • Avoid any LLM involvement—this is a pure protocol client

And maybe you do too?!? If so...


Usage

The MCP client REPL code is available on github here:

GitHub - markabrahams/mcp-client-repl
Contribute to markabrahams/mcp-client-repl development by creating an account on GitHub.

To get started with it:

git clone git@github.com:markabrahams/mcp-client-repl.git
cd mcp-client-repl
npm start

Use "help" to list the available commands, and see below for an example of usage.


Building the REPL

The Model Context Protocol SDK is the standard Node.js MCP library, so I used that to build the REPL:

npm install @modelcontextprotocol/sdk

Specifically, within the library:

  • Client — the base MCP client class that handles the protocol
  • SSEClientTransport — the client "transport" for SSE-based servers
  • StreamableHTTPClientTransport — the client "transport" for HTTP-based streaming

Minimal HTTP MCP Client Example

Thankfully, the library does all the hard work. Here’s a minimal working TypeScript MCP client:

// minimal-http-client.ts

import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';

async function main() {
    const MCP_URL = "http://localhost:8206/mcp";
    const transport = new StreamableHTTPClientTransport(
        new URL(MCP_URL),
        {
            requestInit: {
                headers: { 'x-api-key': '<api-key>' },
            }
        }
    );
    const client = new Client({
        name: "minimal-test",
        version: "1.0.0"
    });
    await client.connect(transport);
    console.log(`Client connected successfully to ${MCP_URL}`);
    const toolsResult = await client.listTools();
    console.log("Tools:");
    toolsResult.tools.forEach(
        (t) => console.log(`- ${t.name}: ${t.description}`)
    );
    await client.close();
    console.log("Client closed");
}

main();

Run it using:

npx tsx minimal-http-client.ts

You should see a list of tools offered by the MCP server, e.g.:

mark@hope:~/mcp-client-repl$ npx tsx src/mcp-client-minimal.ts
Client connected successfully to http://localhost:8206/mcp
Tools:
- getArchitectureByProductId: Get architecture by associated product ID
- getArchitectureElementTree: Get the architecture element tree for a given architecture
- getArchitectureList: Get a list of architectures
- createProduct: Create a new product for the authenticated user
- deleteProduct: Delete a product by ID for the authenticated user
- getProduct: Get a single product by ID for the authenticated user
- getProductList: Get a list of all products for the authenticated user
- patchProduct: Apply a JSON Patch to a product
Client closed

Extending to a Simple MCP Client REPL

I extended the minimal MCP client to a small interactive client REPL.

The MCP client REPL supports:

  • SSE or Streamable HTTP transports
  • Optional API key authentication
  • Optional initial automatic connection via .env variables
  • connect and disconnect commands to manage MCP server connections
  • status to check the status of the current connection
  • tools to list available tools
  • call to call a tool with parameters
  • help and exit commands

Here's an example of the REPL in action:

mark@hope:~/mcp-client$ npm start

> mcp-client-repl@1.0.0 start
> tsx src/mcp-client-repl.ts

mcp> help

Commands:
  connect sse|http|stdio <url_or_script> [apiKey]  Connect to MCP server
  disconnect                                       Disconnect from server
  status                                           Show connection status
  tools [full]                                     List available tools
  call <toolName> <JSON>                           Call a tool
  help                                             Show this help
  exit  

mcp> connect http http://localhost:8206/mcp <api-key>
Connecting via HTTP to http://localhost:8206/mcp
Connected via HTTP to http://localhost:8206/mcp

mcp> status
Connected via http to http://localhost:8206/mcp

mcp> tools
Available tools:

- getArchitectureByProductId: Get architecture by associated product ID
- getArchitectureElementTree: Get the architecture element tree for a given architecture
- getArchitectureList: Get a list of architectures
- createProduct: Create a new product for the authenticated user
- deleteProduct: Delete a product by ID for the authenticated user
- getProduct: Get a single product by ID for the authenticated user
- getProductList: Get a list of all products for the authenticated user
- patchProduct: Apply a JSON Patch to a product

mcp> call getProduct {"productId":"PRODUCT-72488419-827e-4c0a-a3dd-4a0830a722df"}
Invoking tool: getProduct with arguments: {"productId":"PRODUCT-72488419-827e-4c0a-a3dd-4a0830a722df"}
Tool result: [
  {
    type: 'text',
    text: '{\n' +
      '  "_id": "PRODUCT-72488419-827e-4c0a-a3dd-4a0830a722df",\n' +
      '  "createdAt": "2025-05-27T14:12:24.769Z",\n' +
      '  "name": "DefProd 1",\n' +
      '  "status": "draft",\n' +
      '  "updatedAt": "2025-06-24T16:58:39.080Z",\n' +
      '  "userId": "USER-36db5402-eadc-44ea-b5b0-ec1d3b27b746",\n' +
      '  "brief": {\n' +
      '    "_id": "BRIEF-0b4122a9-d93e-4060-97a9-e4ffa55c87d9",\n' +
      '    "aesthetics": {\n' +
      '      "tone": "Slight military vibe",\n' +
      '      "visualStyle": "Minimalist",\n' +
      '      "interactionPrinciples": [\n' +
      '        "Remote management",\n' +
      '        "Keyboard shortcuts",\n' +
      '        "One more principle"\n' +
      '      ]\n' +
      '    },\n' +
      '    "createdAt": "2025-05-27T14:12:24.782Z",\n' +
      '    "description": "A context management app for agent-based coding, providing a permanent software product definition for persistent vibe code context, selectively fed to a coding agent.",\n' +
      '    "outOfScope": [\n' +
      '      "AI coding agent",\n' +
      '      "LLM training",\n' +
      '      "Anything not in scope"\n' +
      '    ],\n' +
      '    "problem": {\n' +
      '      "summary": "Coding agents lack persistent context, leading to inconsistent or misaligned code generation.",\n' +
      '      "context": "Current coding agents operate in a limited context window, losing track of the overall product vision and specific requirements over time. This results in duplicated effort, feature creep, and difficulty maintaining consistency.",\n' +
      '      "impact": "Without a persistent product definition, coding agents produce code that deviates from the intended product vision, increasing development time, maintenance costs, and user dissatisfaction."\n' +
      '    },\n' +
      '    "productId": "PRODUCT-72488419-827e-4c0a-a3dd-4a0830a722df",\n' +
      '    "references": [\n' +
      '      {\n' +
      '        "name": "Context Management in AI",\n' +
      '        "url": "https://example.com/context-management",\n' +
      '        "description": "Article on context management techniques for AI agents"\n' +
      '      },\n' +
      '      {\n' +
      '        "name": "Agent-Based Coding",\n' +
      '        "url": "https://example.com/agent-based-coding",\n' +
      '        "description": "Overview of agent-based coding methodologies"\n' +
      '      }\n' +
      '    ],\n' +
      '    "requirements": [\n' +
      '      {\n' +
      '        "id": "REQ-01",\n' +
      '        "title": "Manage Product Definitions",\n' +
      '        "description": "The application must allow users to create, update, and delete product definitions.",\n' +
      '        "priority": "must"\n' +
      '      },\n' +
      '      {\n' +
      '        "id": "REQ-02",\n' +
      '        "title": "Provide Context to Coding Agents",\n' +
      '        "description": "The application must provide a mechanism for selectively feeding product definition context to coding agents.",\n' +
      '        "priority": "must"\n' +
      '      }\n' +
      '    ],\n' +
      '    "successCriteria": [\n' +
      '      "AI agent can access all product information",\n' +
      '      "Human can define product"\n' +
      '    ],\n' +
      '    "updatedAt": "2025-10-29T10:39:30.468Z",\n' +
      '    "userId": "USER-36db5402-eadc-44ea-b5b0-ec1d3b27b746",\n' +
      '    "users": [\n' +
      '      {\n' +
      '        "persona": "Product Manager",\n' +
      '        "goals": [\n' +
      '          "Effectively communicate the product vision to the development team",\n' +
      '          "Ensure the product aligns with user needs",\n' +
      '          "Manage product backlog and prioritize features"\n' +
      '        ],\n' +
      '        "painPoints": [\n' +
      '          "Difficulty in maintaining a consistent product vision",\n' +
      '          "Managing changing requirements and priorities",\n' +
      '          "Balancing user needs with technical constraints"\n' +
      '        ]\n' +
      '      },\n' +
      '      {\n' +
      '        "persona": "AI",\n' +
      '        "goals": [\n' +
      '          "Effectively utilize product definition for code generation"\n' +
      '        ],\n' +
      '        "painPoints": [\n' +
      '          "Ambiguity in product definition",\n' +
      '          "Incompleteness in product definition"\n' +
      '        ]\n' +
      '      },\n' +
      '      {\n' +
      '        "persona": "Developer",\n' +
      '        "goals": [\n' +
      '          "Understand the product requirements",\n' +
      '          "Efficiently implement features",\n' +
      '          "Write high-quality, maintainable code"\n' +
      '        ],\n' +
      '        "painPoints": [\n' +
      '          "Unclear or incomplete requirements",\n' +
      '          "Difficulty in understanding the product architecture",\n' +
      '          "Lack of clear coding standards and guidelines"\n' +
      '        ]\n' +
      '      }\n' +
      '    ],\n' +
      '    "versionHistory": [],\n' +
      '    "version": "1.1"\n' +
      '  }\n' +
      '}'
  }
]

mcp> exit
Disconnected from http://localhost:8206/mcp

Conclusion

So that helped a great deal in testing my MCP server. It was sufficiently small to give up my search for such a tool after a while and quickly build it myself. Perhaps, it wasn't so much the about client, but the journey along the way. Did such an MCP client REPL already exist somewhere else in the public domain waiting for me to discover? Almost certainly, but since I couldn't easily find it, I'm not sure...