@aiconnect/mcpo-client
v0.5.0
Published
TypeScript/Node client for interacting with MCPO servers and CLI tool
Maintainers
Readme
@aiconnect/mcpo-client
TypeScript/Node client for interacting with MCPO servers (MCP OpenAPI Proxy) and a small helper CLI.
- Repository: aiconnect-cloud/mcpo-client
- NPM: @aiconnect/mcpo-client
- MCPO: https://github.com/open-webui/mcpo
Installation
Library (for Node projects):
npm i @aiconnect/mcpo-clientCLI (global):
npm i -g @aiconnect/mcpo-client
mcpo-client --helpOr via npx:
npx @aiconnect/mcpo-client --helpLibrary Overview
Main surface:
- createClient(opts): creates an HTTP-only client for MCPO
- client.describe(tool, { mount }): returns a ToolSpec (OpenAPI → parameters/body/response)
- client.call(tool, args, { mount, skipSpec? }): executes the tool via HTTP
- client.buildOpenAITool(tool, { mount }): generates an OpenAI-compatible tool (function) definition
- discover(baseUrl, opts): mount-wide discovery — lists every tool exposed by the server (single or multi-mount), returning ServerTools
- discoverMountTools(baseUrl, mount, opts): single-download mount expansion — exactly one request to /<mount>/openapi.json, returning full OpenAI-compatible tool definitions for every uniquely-named tool the mount exposes (duplicate final path segments: first occurrence wins — later collisions are unreachable by name-based calling and are skipped, never mis-emitted)
- buildOpenAIToolFromDocument(oas, tool, ctx) / buildOpenAIToolsFromDocument(oas, ctx): pure transforms over an already-fetched OpenAPI document (no network) — same conversion client.buildOpenAITool applies after fetching
- HttpError: error thrown for non-2xx responses or timeouts (includes status and body when available)
- ResponseTooLargeError: error thrown when a response body exceeds maxResponseBytes — the transfer is aborted before parsing (includes bytesRead, limit, and contentLength when available)
- InvalidJsonError: error thrown by call() when requireJson is set and a 2xx tool body is not valid JSON (includes the 2xx status and rawBody); subclass of HttpError — check it before the generic HttpError since it carries a 2xx status
Both createClient and discover accept maxResponseBytes to cap response body size in bytes; unset means unlimited. A Content-Length above the limit rejects the response without reading the body; otherwise the body is streamed and aborted as soon as the limit is crossed, before any JSON parsing.
createClient and call accept requireJson (default false). When true, call() throws InvalidJsonError on a 2xx tool response whose non-empty body is not valid JSON — letting callers distinguish a legitimate JSON-string result (e.g. "ok") from a non-JSON body (e.g. an HTML error page served with 200). It applies to tool calls only; OpenAPI discovery/describe stay lenient. A per-call requireJson overrides the client-level default.
Requirements:
- Node 18+
- MCPO started with --api-key (if protected)
Quick Example (Call)
import { createClient } from '@aiconnect/mcpo-client';
const client = createClient({
baseUrl: 'https://mcpo.example.com',
apiKey: process.env.MCPO_API_KEY,
});
// Call time/get_current_time
const data = await client.call(
'get_current_time',
{ timezone: 'Europe/Lisbon' },
{ mount: 'time', skipSpec: true }
);
console.log(data);Example (Describe → OpenAI Tool)
import { createClient } from '@aiconnect/mcpo-client';
const client = createClient({ baseUrl: 'https://mcpo.example.com', apiKey: process.env.MCPO_API_KEY });
const toolDef = await client.buildOpenAITool('get_current_time', { mount: 'time' });
// toolDef -> { type: 'function', function: { name, description, parameters } }Errors and Timeouts
- Throws HttpError for non-2xx responses or timeouts (includes status and body when available)
- Throws ResponseTooLargeError (subclass of HttpError) when maxResponseBytes is set and the response body exceeds it — aborted before parsing, with bytesRead/limit/contentLength for diagnostics
- Throws InvalidJsonError (subclass of HttpError) when requireJson is set and a 2xx tool body is not valid JSON — carries the 2xx status and rawBody
- skipSpec: true avoids downloading the OpenAPI spec and calls POST /<mount>/<tool> directly
Examples
- OpenAI agent via HTTP-only: examples/openai-time-agent.ts
- Examples environment: examples/.env.example
Run:
cp examples/.env.example examples/.env
source examples/.env
npm run examples:openai-timeCLI (optional)
The package also ships a handy CLI for discovery and execution.
List tools:
mcpo-client tools list --url https://mcpo.example.com --api-key <KEY> --format tableDescribe a tool (parameters/response):
mcpo-client tools describe time/get_current_time --url https://mcpo.example.com --api-key <KEY> --format tableCall a tool:
# Direct JSON
mcpo-client tools call time/get_current_time --url https://mcpo.example.com --api-key <KEY> -d '{"timezone":"Europe/Lisbon"}'
# Interactive (prompts required fields)
mcpo-client tools call time/get_current_time --url https://mcpo.example.com --api-key <KEY>
# Without OpenAPI (for slow environments)
mcpo-client tools call time/get_current_time --url https://mcpo.example.com --api-key <KEY> --no-spec -d '{"timezone":"Europe/Lisbon"}'Common options:
- --url: MCPO base URL (accepts prefix)
- --api-key or --basic user:pass
- --timeout, --insecure, --verbose
- --format: table|json|plain (for list/describe)
Notes
- Works with MCPO in stdio, sse and streamable-http modes (client is always HTTP/OpenAPI based)
- API documentation (TypeDoc): docs/api
