@civic/mcp-client

中文文档
2.0.0发布于 2026/10/09MITTypeScriptESM + CJS近 30 天下载 4419

TypeScript client library for connecting to Civic Hub and exposing MCP tools to AI SDKs

原始使用文档
文档目录17 节
  1. Installation
  2. Quick Start
  3. With Vercel AI SDK
  4. With OpenAI SDK
  5. With Anthropic SDK
  6. With LangChain.js
  7. Features
  8. API Reference
  9. CivicMcpClient
  10. Advanced Usage
  11. Protocol Version Negotiation
  12. Caching Client Instances
  13. Profile Scoping
  14. Dynamic Token Refresh
  15. Token Exchange (RFC 8693)
  16. Upgrading from 1.x
  17. License

@civic/mcp-client

TypeScript client library for connecting to Civic MCP Hub and exposing MCP (Model Context Protocol) tools to AI SDKs like Vercel AI, OpenAI, Anthropic, and LangChain.js.

Installation

pnpm add @civic/mcp-client

Depending on which AI SDK you're using, also install the peer dependency:

# For Vercel AI SDK
pnpm add ai

# For OpenAI
pnpm add openai

# For Anthropic
pnpm add @anthropic-ai/sdk

# For LangChain.js
pnpm add @langchain/core

Quick Start

With Vercel AI SDK

import { CivicMcpClient } from "@civic/mcp-client";
import { vercelAIAdapter } from "@civic/mcp-client/adapters/vercel-ai";
import { streamText } from "ai";

const client = new CivicMcpClient({
  auth: {
    token: "your-access-token",
  },
});

const tools = await client.getTools(vercelAIAdapter());

const result = streamText({
  model: yourModel,
  messages: [{ role: "user", content: "Search GitHub for civic repos" }],
  tools,
});

// Clean up when done
await client.close();

With OpenAI SDK

import { CivicMcpClient } from "@civic/mcp-client";
import { openAIAdapter } from "@civic/mcp-client/adapters/openai";
import OpenAI from "openai";

const client = new CivicMcpClient({
  auth: { token: "your-access-token" },
});

const tools = await client.getTools(openAIAdapter());

const openai = new OpenAI();
const response = await openai.chat.completions.create({
  model: "gpt-4",
  messages: [{ role: "user", content: "Search GitHub for civic repos" }],
  tools,
});

With Anthropic SDK

import { CivicMcpClient } from "@civic/mcp-client";
import { anthropicAdapter } from "@civic/mcp-client/adapters/anthropic";
import Anthropic from "@anthropic-ai/sdk";

const client = new CivicMcpClient({
  auth: { token: "your-access-token" },
});

const tools = await client.getTools(anthropicAdapter());

const anthropic = new Anthropic();
const message = await anthropic.messages.create({
  model: "claude-3-5-sonnet-20241022",
  messages: [{ role: "user", content: "Search GitHub for civic repos" }],
  tools,
});

With LangChain.js

Returns an array of DynamicStructuredTool instances ready to drop into any LangChain agent — langchain v1's createAgent, LangGraph's createReactAgent, the legacy AgentExecutor, or n8n's "AI Agent" node.

Tool results are concatenated into a single string by default (MCP text blocks joined; non-text blocks JSON-stringified), which is the most compatible shape for every model and agent variant.

import { CivicMcpClient } from "@civic/mcp-client";
import { langchainAdapter } from "@civic/mcp-client/adapters/langchain";
import { ChatOpenAI } from "@langchain/openai";
import { createReactAgent } from "@langchain/langgraph/prebuilt";

const client = new CivicMcpClient({
  auth: { token: "your-access-token" },
});

const tools = await client.getTools(langchainAdapter());

const agent = createReactAgent({
  llm: new ChatOpenAI({ model: "gpt-4o-mini" }),
  tools,
});

const result = await agent.invoke({
  messages: [{ role: "user", content: "Search GitHub for civic repos" }],
});

Features

  • Protocol Version Negotiation: Speaks MCP 2026-07-28 to servers that support it and falls back to the 2025-era handshake automatically
  • Session Management: Maintains persistent MCP sessions with automatic reconnection on legacy-era servers
  • Framework Agnostic: Works with any AI SDK through adapters
  • TypeScript First: Full type safety and IntelliSense support
  • Flexible Authentication: Support for static tokens, async token providers, or automatic token exchange
  • Lightweight: No unnecessary dependencies, minimal bundle size

API Reference

CivicMcpClient

Constructor Options

interface CivicMcpClientConfig {
  // Hub URL (defaults to "https://app.civic.com/hub/mcp")
  url?: string;

  // Authentication — provide either a token directly or use token exchange
  auth:
    | { token: string | (() => Promise<string>) }
    | { tokenExchange: TokenExchangeConfig };

  // Scope requests to a specific profile (UUID)
  civicProfile?: string;  // Sent as x-civic-profile-id header

  // Optional custom headers
  headers?: Record<string, string>;

  // Optional connection options
  reconnection?: {
    maxRetries?: number;
    initialReconnectionDelay?: number;
    maxReconnectionDelay?: number;
    reconnectionDelayGrowFactor?: number;
  };

  // Protocol version negotiation (default: "auto")
  // "auto": probe with server/discover, fall back to initialize on legacy servers
  // "legacy": always run the 2025-era initialize handshake
  // { pin: "2026-07-28" }: require exactly that revision, fail otherwise
  versionNegotiation?: "auto" | "legacy" | { pin: string };
}

interface TokenExchangeConfig {
  clientId: string;       // Civic Auth Client ID
  clientSecret: string;   // Civic Auth Client Secret
  subjectToken: string | (() => Promise<string>); // External IdP token
  authUrl?: string;       // Token endpoint (default: "https://auth.civic.com/oauth/token")
  expiresIn?: number;     // Requested token lifetime in seconds (server default if omitted)
  lockToProfile?: boolean; // Lock exchanged token to civicProfile (default: true)
}

Methods

  • getTools<T>(adapter?: ToolAdapter<T>): Promise<T> - Get tools, optionally adapted for specific AI SDK
  • getServerInstructions(): Promise<string> - Get server instructions for system prompt
  • callTool(name: string, args: unknown): Promise<CallToolResult> - Call a tool directly
  • getAccessToken(): string | undefined - Get the currently cached Civic Auth access token (token exchange only)
  • close(): Promise<void> - Close the connection

Advanced Usage

Protocol Version Negotiation

By default the client probes the server with server/discover and uses protocol revision 2026-07-28 when the server offers it. Servers that only speak the 2025-era protocol get the classic initialize handshake, so one build works against both. After connecting, getProtocolEra() reports which era was negotiated:

await client.connect();
client.getProtocolEra(); // "modern" (2026-07-28+) or "legacy" (2025-era)

Session IDs and onInitialized only apply to legacy-era connections; modern-era servers do not issue sessions.

Caching Client Instances

The library doesn't include caching logic - you manage CivicMcpClient instances yourself:

// Simple in-memory cache
const clientCache = new Map<string, CivicMcpClient>();

function getCivicMcpClient(userId: string): CivicMcpClient {
  let client = clientCache.get(userId);
  if (!client) {
    client = new CivicMcpClient({ /* config */ });
    clientCache.set(userId, client);
  }
  return client;
}

Profile Scoping

const client = new CivicMcpClient({
  auth: { token: accessToken },
  civicProfile: "7c9e6679-7425-40de-944b-e07fc1f90ae7",
});

Dynamic Token Refresh

const client = new CivicMcpClient({
  auth: {
    token: async () => {
      const session = await getSession();
      return session.accessToken;
    },
  },
});

Token Exchange (RFC 8693)

Server-side only. Token exchange requires a clientSecret, which must never be exposed in browser/client-side code. Only use tokenExchange in server-side environments (Node.js, serverless functions, etc.).

If your app uses its own identity provider (Google, Auth0, etc.), the client can automatically exchange external tokens for Civic Auth access tokens. Exchanged tokens are cached and re-exchanged on expiry or when the external token changes.

const client = new CivicMcpClient({
  auth: {
    tokenExchange: {
      clientId: process.env.CIVIC_CLIENT_ID,
      clientSecret: process.env.CIVIC_CLIENT_SECRET,
      subjectToken: () => getGoogleAccessToken(user),
    },
  },
  civicProfile: "550e8400-e29b-41d4-a716-446655440000", // optional: scope to a specific profile
});

// Token exchange happens automatically on first use.
// The exchanged token is locked to the civicProfile by default.
const tools = await client.getTools(vercelAIAdapter());

For setup instructions (creating an organization, linking your Client ID, and configuring token exchange), see the Civic Auth token exchange guide.

Upgrading from 1.x

Version 2 swaps the underlying SDK from @modelcontextprotocol/sdk v1 to @modelcontextprotocol/client v2. For most consumers nothing changes: the CivicMcpClient API and the adapters are the same, and the client negotiates the protocol version with the hub automatically.

Things to check:

  • Node.js 22+ is required.
  • CallToolResult and ListToolsResult are now defined by this package instead of being re-exported from the v1 SDK. They match the MCP spec shapes, so plain usage is unaffected. If you passed them to v1 SDK functions, cast at that boundary or import the SDK's types directly.
  • The v1 SDK is no longer installed transitively. If your code imported @modelcontextprotocol/sdk only because this package pulled it in, add it to your own dependencies.
  • Session recovery only applies to legacy-era connections. On a 2026-07-28 server there is no session, so onInitialized does not fire and getSessionId() returns undefined.

See CHANGELOG.md for the full list.

License

MIT

版本与发布记录

@civic/mcp-client 共发布 6 个版本,首次发布于 2026/03/18;过去 12 个月发布了 6 个版本。

版本发布日期距今
2.0.0latest2026/10/091 个月前
1.0.12026/05/106 个月前
1.0.02026/05/086 个月前
0.1.12026/03/247 个月前
0.1.1-beta.1beta2026/03/217 个月前
0.1.02026/03/187 个月前

关于 @civic/mcp-client 的常见问题

@civic/mcp-client 是什么?

TypeScript client library for connecting to Civic Hub and exposing MCP tools to AI SDKs

如何安装 @civic/mcp-client?

在项目目录运行 npm install @civic/mcp-client,或使用 pnpm add / yarn add / bun add。

@civic/mcp-client 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@civic/mcp-client 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@civic/mcp-client 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@civic/mcp-client 可以商用吗?

@civic/mcp-client 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@civic/mcp-client 的下载量有多少?

根据 npm 官方下载统计,@civic/mcp-client 在 2026/10/10 – 2026/11/08 这 30 天内被下载 4,419 次,日均约 147 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@civic/mcp-client 还在维护吗?

最新版本 2.0.0 发布于 2026/10/09(1 个月前);至今共发布 6 个版本,其中过去 12 个月发布了 6 个;首次发布于 2026/03/18。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。