@civic/mcp-客户端
TypeScript客户端库,用于连接 Civil MCP Hub,并将MCP(模式上下文协议)工具曝光给AI SDK,如Vercel AI,OpenAI,Anthropic,和LangChain.js.
安装
pnpm add @civic/mcp-client
根据您使用的 AI SDK, 同时安装对等依赖 :
# 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
快速启动
使用 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();
带有 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,
});
与 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,
});
和LangChain.js在一起的电影
返回数组 DynamicStructuredTool 任何LangChain的代理商 langchain v1 级 createAgent兰格拉夫的 createReactAgent遗产 AgentExecutor,或者n8n的"AI代理"节点.
工具结果默认缩合为单个字符串( MCP) text 块加入;非文本块 JSON-stringifed),这是每个模型和代理变量最相容的形状.
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" }],
});
特征
- 议定书版本谈判:向支持它的服务器说出MCP 2026-07-28,并自动回落到2025-时代的握手状态
- 会话管理: 维持持续 MCP会话,在遗留时代服务器上自动重新连接
- 框架不可知论: 通过适配器与任何 AI SDK 工作
- 类型脚本第一: 完全类型安全和IntelliSense支持
- 灵活认证: 支持静态令牌、 自动令牌提供者或自动令牌交换
- 轻巧: 没有不必要的依赖, 最小捆绑大小
API 参考
CivicMcpClient
构造选项
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)
}
方法
getTools<T>(adapter?: ToolAdapter<T>): Promise<T>- 获取工具,可选地适用于特定的AI SDKgetServerInstructions(): Promise<string>- 获取服务器指令以便系统迅速callTool(name: string, args: unknown): Promise<CallToolResult>- 直接调用工具getAccessToken(): string | undefined- 获取当前缓存的 Civil Auth 访问令牌( 仅保存交换)close(): Promise<void>- 关闭连接
高级使用
议定书版本谈判
默认情况下,客户端会用 server/discover 并使用协议修订 2026-07-28 当服务器提供它。 只讲2025年代协议的服务器获得经典 initialize 握个手,这样一来就对了 连接后, getProtocolEra() 谈判的时代:
await client.connect();
client.getProtocolEra(); // "modern" (2026-07-28+) or "legacy" (2025-era)
会话标识和 onInitialized 仅适用于遗留时代的连接; 现代服务器不发布会话.
缓存客户端实例
图书馆不包含缓存逻辑 - 你自己管理 CivilMcpclient 例:
// 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;
}
配置范围
const client = new CivicMcpClient({
auth: { token: accessToken },
civicProfile: "7c9e6679-7425-40de-944b-e07fc1f90ae7",
});
动态托肯刷新
const client = new CivicMcpClient({
auth: {
token: async () => {
const session = await getSession();
return session.accessToken;
},
},
});
Token交易所(RFC 8693)
仅限服务器侧. 托肯交换需要
clientSecret,它绝不能在浏览器/客户端代码中被曝光。 仅使用tokenExchange在服务器侧环境(Node.js,无服务器功能等)中.
如果您的应用程序使用自己的身份提供者(Google, Auth0等),客户端可以自动交换外部的Civil Auth访问令牌. 交换的令牌被缓存并被重新交换,在到期或外部令牌改变时.
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());
设置指令(创建组织、连接客户端标识和配置符号交换),请参见 公民签名交换指南。 。 。 .
从1.x升级
版本 2 互换基础 SDK 从 @modelcontextprotocol/sdk v1 改为 @modelcontextprotocol/client v2. 对大多数消费者来说,没有什么变化: CivicMcpClient API和适配器相同,客户端自动与中枢谈判协议版本.
需要检查的东西 :
- 节点.js 22+ 需要时间.
CallToolResult财务报告和审定财务报表ListToolsResult现在由此软件包定义,而不是从v1 SDK再出口。 它们与MCP的光谱形状相匹配,因此平庸使用不受影响. 如果您把它们传递到v1 SDK 函数上,请在那个边界上投放或者直接导入 SDK 的类型.- V1 SDK不再以中转方式安装. 如果输入您的代码
@modelcontextprotocol/sdk仅仅因为这个包把它拉进去, 添加到你自己的依赖. - 会话恢复 仅适用于遗留时代的连接。 2026-07-28服务器上没有会话,所以
onInitialized不开火getSessionId()返回时undefined。 。 。 .
见 变动情况 完整名单.
许可证
麻省理工学院