Skip to main content

Low-level MCP client

import { KontextMcp } from "@kontext-dev/js-sdk/mcp";
import open from "open";

declare function waitForCallbackUrl(): Promise<string>;

const mcp = new KontextMcp({
  clientId: "app_your-app-id",
  redirectUri: "http://localhost:3333/callback",
  onAuthRequired: async (url) => {
    await open(url.toString());
    return await waitForCallbackUrl();
  },
});

const tools = await mcp.listTools();
if (tools.length > 0) {
  const result = await mcp.callTool(tools[0]!.name, {});
}
Direct MCP protocol client with OAuth handling. Most applications should use createKontextClient instead — this is for advanced use cases where you need raw MCP transport control.

Methods

MethodReturnsDescription
listTools()Promise<Tool[]>List available MCP tools.
callTool(name, args?)Promise<CallToolResult>Execute a tool by name.
handleCallback(url)Promise<void>Complete the OAuth callback.
disconnect()Promise<void>Close the MCP connection.
clearAuth()Promise<void>Remove stored tokens.
isCallback(url)booleanCheck if a URL is an OAuth callback.
createConnectSession()Promise<ConnectSessionResult>Create a connect page session.
listRuntimeIntegrations()Promise<RuntimeIntegrationRecord[]>List available integrations and their status.

Properties

PropertyTypeDescription
isConnectedbooleanWhether the MCP connection is active.
sessionIdstring?Current session ID, if connected.

Runtime integration shape

listRuntimeIntegrations() returns records with explicit connect semantics:
type RuntimeIntegrationConnectType =
  | "oauth"
  | "user_token"
  | "credentials"
  | "none";

interface RuntimeIntegrationRecord {
  id: string;
  name: string;
  url: string;
  category: "gateway_remote_mcp" | "internal_mcp_credentials";
  connectType: RuntimeIntegrationConnectType;
  authMode?: "oauth" | "user_token" | "server_token" | "none";
  tokenLabel?: string;
  tokenHelpUrl?: string;
  tokenPlaceholder?: string;
  connection?: {
    connected: boolean;
    status: "connected" | "disconnected";
    expiresAt?: string;
    displayName?: string;
    lastVerifiedAt?: string;
    lastVerifiedStatus?: string;
    verificationMessage?: string;
  };
}
For connectType: "user_token", prompt the user to provide an API key/token in the connect UI flow. For admin-managed shared tokens, the runtime record uses connectType: "none" together with authMode: "server_token". Treat these as read-only runtime entries: there is nothing for the end user to connect. The runtime integration parser is strict: unknown or missing connectType values throw kontext_runtime_integrations_invalid_response.

Error types

import {
  KontextError,
  translateError,
  isKontextError,
  isNetworkError,
  isUnauthorizedError,
} from "@kontext-dev/js-sdk/errors";

if (isKontextError(err)) {
  console.log(err.code, err.statusCode);
}
See Errors for the full error hierarchy, error codes, and handling patterns.

Error classes

ClassTypical codeDescription
AuthorizationRequiredErrorkontext_authorization_requiredUser needs to sign in.
IntegrationConnectionRequiredErrorkontext_integration_connection_requiredIntegration needs user connection (OAuth or API key). Has connectUrl.
OAuthErrorvaries (for example kontext_oauth_token_exchange_failed)OAuth flow failed.
ConfigErrorvaries (for example kontext_config_missing_client_id)SDK misconfiguration.
NetworkErrorkontext_network_errorConnection failure.
HttpErrorvaries (for example kontext_not_found, kontext_rate_limited)HTTP error with status code.

Type guards

FunctionChecks
isKontextError(err)Any KontextError subclass.
isNetworkError(err)Network-level failures (DNS, timeout, refused).
isUnauthorizedError(err)401 responses.

Error translation

translateError(err) normalizes MCP JSON-RPC errors, Streamable HTTP failures, unauthorized responses, and browser/network failures into KontextError subclasses or kontext_* codes. Use it when you are working directly with KontextMcp, raw MCP SDK errors, or custom wrappers and want the same classification behavior as the higher-level client/orchestrator.

Token verification

import { KontextTokenVerifier } from "@kontext-dev/js-sdk/verify";

const verifier = new KontextTokenVerifier({
  jwksUrl: "https://api.kontext.dev/.well-known/jwks.json",
  issuer: "https://api.kontext.dev/",
  audience: "https://api.kontext.dev/mcp",
});

const result = await verifier.verify(token);
if (result.success) {
  console.log(result.claims.clientId, result.claims.scopes);
} else {
  console.error(result.error.code, result.error.message);
}
Standalone token verification for custom middleware or non-Express servers. The server SDK uses this internally — you only need this if you are building your own transport layer.

Additional methods

MethodReturnsDescription
verifyOrNull(token)Promise<VerifiedTokenClaims | null>Returns claims if valid, null if invalid. Simpler API when you don’t need error details.
clearCache()voidClear the JWKS cache, forcing a fresh fetch on next verification.

OAuth utilities

import { parseOAuthCallback, exchangeToken } from "@kontext-dev/js-sdk/oauth";

const { code, state, error } = parseOAuthCallback(
  "http://localhost:3333/callback?code=abc&state=xyz",
);

const exchanged = await exchangeToken(
  {
    tokenUrl: "https://api.kontext.dev/oauth2/token",
    clientId: "app_or_mcp_client_id",
    clientSecret: process.env.KONTEXT_CLIENT_SECRET,
  },
  "subject_token_here",
  "mcp-gateway",
);
Low-level OAuth helpers for building custom flows. Most applications should use createKontextClient or the React adapter, which handle OAuth automatically.