@viyv/mcp-connect
v0.1.0
Published
Dial a Viyv MCP Gateway from any MCP server (official @modelcontextprotocol/sdk or otherwise): announce your tools over outbound WebSocket and serve tool calls locally. The TypeScript peer of viyv_mcp's connect mode.
Maintainers
Readme
@viyv/mcp-connect
Dial a Viyv MCP Gateway from any MCP server — over an outbound WebSocket —
without rewriting that server. It is the TypeScript peer of viyv_mcp's Python
connect mode: the connector acts as a
standard MCP client toward your server and speaks the Gateway's announce
protocol (@viyv/mcp-spec) on
the other side, so both the Python and TypeScript connectors emit identical
announce / tool_result frames.
Your existing @modelcontextprotocol/sdk tools are not modified. Connecting
to the Gateway centralizes auth (JWT), namespace + clearance authorization, and
audit for every server regardless of language.
Install
npm i @viyv/mcp-connect # peers: @modelcontextprotocol/sdk >=1.26, zodA. In-process (wrap an existing server, 3 lines)
import { connectServerToGateway } from '@viyv/mcp-connect'
const server = buildMyMcpServer() // your existing @modelcontextprotocol/sdk McpServer/Server — unchanged
const conn = await connectServerToGateway(server, {
gatewayUrl: process.env.GATEWAY_URL!, // wss://<gw>/ws/bridge
relayKey: process.env.RELAY_KEY!, // minted by the Gateway admin API
connectorName: 'my-server',
})
// conn.connector.isHealthy, await conn.stop(), await conn.doneInternally this links an in-memory transport pair, connects an MCP Client to
your server, then runs the connector: listTools() → announce, and each
tool_call → client.callTool() → tool_result (with the content-block
flattening the Gateway expects).
B. Sidecar CLI (separate process, zero dependency on your server)
For a server already running over stdio or Streamable HTTP — no code change, not even a dependency added:
npx @viyv/mcp-connect \
--target 'stdio:node dist/server.js' \
--gateway wss://<gw>/ws/bridge --key "$RELAY_KEY" --name my-server
# or an HTTP MCP endpoint:
npx @viyv/mcp-connect --target http://localhost:3000/mcp --gateway ... --key ...--gateway/--key also read CONNECT_GATEWAY_URL / CONNECT_RELAY_KEY. This
is the analogue of python -m viyv_mcp connect --bridges ....
C. Greenfield (build tools with the connector's sugar)
import { defineTool, createToolServer, connectServerToGateway } from '@viyv/mcp-connect'
import { z } from 'zod'
const server = createToolServer({ name: 'calc' }, [
defineTool({
name: 'add',
description: 'Add two numbers',
inputSchema: { a: z.number(), b: z.number() },
handler: ({ a, b }) => String((a as number) + (b as number)),
}),
])
await connectServerToGateway(server, { gatewayUrl, relayKey, connectorName: 'calc' })Behaviour
Faithful port of viyv_mcp/app/connect_client.py: exponential reconnect backoff
(1s→30s), a 5s floor after a deterministic auth rejection, a 30s auth timeout,
keepalive ping/pong, and a healthy gate so a rejected announce / bad key backs
off instead of hot-looping.
Notes & limits (v0.1.0)
- Tools-only.
resources/promptsare announce stubs (reserved). - Per-tool
namespace/security_levelare not yet carried on the announce wire — the Gateway applies a per-registration level. Use the bridge path (python -m viyv_mcp connect --bridges, withsecurity_level_map) when you need per-tool fidelity today. - For the in-process path,
@modelcontextprotocol/sdkis a peer dependency so your server and the connector share one SDK instance (required for the in-memory transport).
MIT.
