@civic/auth-mcp (中文(简体) )
🔐 向 MCP 服务器添加授权的最快捷方式
这是向MCP服务器添加授权的最快方式,使得LLMs能够安全地使用工具,并为您和您的客户提供信心和安全.
它与任何符合要求的OAuth2/OIDC供应商合作,同时被优化为Civil Auth的闪电快认证体验.
为什么选择公民奥特?
公民联盟 为现代应用提供最快,最灵活的认证经验:
- QQ 闪电设置: 用户在60秒内获得熟悉的登录选项(电子邮件、谷歌、密码、钱包)认证
- 可适应的入职: 所有用户的无缝体验 - 支持已存在的钱包或自动创建嵌入式钱包
- QQ 网络3 支持: 对索拉纳、伊特鲁姆、基地、多边形、BSC、Arbitrum和其他EVM链的原生支持
- 通用兼容性: 到处工作 - React, Next.js, Node.js, 或任何 OIDC/OAuth 2. 0 环境
准备好体验最快的Auth吗? 获取客户身份 auth.civic.com (英语) 几分钟后就起来跑.
* 特性
- 与最新版本的《示范上下文议定书》规格一致,特别是关于 授权服务器发现 光谱
- 方便集成的客户端和服务器 SDK
- 快速设置的快取中间软件
- 用于任何节点框架的框架不可知性核心
- 与命令行工具集成的 CLI 认证
QQ 快速启动
安装依赖性 :
npm install @civic/auth-mcp
服务器侧中件对一款MCP SDK没有依赖性:它与v2 SDK(@modelcontextprotocol/server),v1 SDK(英语:@modelcontextprotocol/sdk),或根本没有SDK. 这个 @civic/auth-mcp/client 切入点(参见 客户集成)建立在v2客户端包上, @modelcontextprotocol/client。 。 。 .
在您的快捷应用程序中添加中间软件 :
app.use(await auth());
出道后,这采用Civil Auth作为认证提供者,这是最快的启动方式.
一旦你准备好去现场, 获取客户身份 auth.civic.com (英语) 并替换中间软件中的默认客户端ID :
app.use(await auth({
clientId: "...", // Get your client ID from auth.civic.com
}));
就这样!
使用实例
QQ快取中件( 建议)
获取MCP服务器的最快方式. 工作顺利 MCP 类型脚本 SDK v2 (英语:@modelcontextprotocol/server 与 @modelcontextprotocol/node 与v1 SDK(运输)@modelcontextprotocol/sdk) (中文(简体) ).
import express from "express";
import {auth} from "@civic/auth-mcp";
import {NodeStreamableHTTPServerTransport} from "@modelcontextprotocol/node";
import {McpServer} from "@modelcontextprotocol/server";
// Create your Express app
const app = express();
// Add auth middleware
app.use(await auth());
// Create your MCP server
async function getServer() {
const server = new McpServer({
name: "my-mcp-server",
version: "0.0.1",
});
// Register your tools
server.registerTool(
"tool-name",
{ description: "Example tool" },
async (ctx) => {
// Access the authenticated user's information.
// The middleware sets req.auth; the transport forwards it as ctx.http.authInfo.
// (On the v1 SDK, use server.tool(...) and read extra.authInfo instead.)
const user = ctx.http?.authInfo?.extra?.sub;
return {
content: [
{
type: "text",
text: `Hello ${user}!`,
},
],
};
}
);
// Set up the transport layer
// In production you may need session management
const transport = new NodeStreamableHTTPServerTransport({
sessionIdGenerator: undefined,
});
await server.connect(transport);
return { transport, server };
}
// Set up MCP endpoint
app.post("/mcp", async (req, res) => {
const { transport, server } = await getServer();
await transport.handleRequest(req, res, req.body);
res.on('close', () => {
transport.close();
server.close()
})
});
QQ 配置选项
app.use(await auth({
// Use a different auth server:
wellKnownUrl: 'https://accounts.google.com/.well-known/openid-configuration',
// Or specify additional options
scopesSupported: ['openid', 'profile', 'email', 'custom:scope'],
// Protect a different route (defaults to '/mcp')
mcpRoute: '/api',
// Enrich auth info with custom data from your database
onLogin: async (authInfo, request) => {
// Look up user data based on the JWT subject claim
const userData = await db.users.findOne({ sub: authInfo?.extra?.sub });
// Return enriched auth info
return {
...authInfo,
extra: { ...authInfo.extra, ...userData }
};
},
// Legacy OAuth options
enableLegacyOAuth: true, // Defaults to true
stateStore: customStateStore, // Custom state store for OAuth flows
}));
框架不可知使用法
对于非印刷框架,请使用 McpServerAuth 直接分类 :
import { McpServerAuth } from "@civic/auth-mcp";
// Initialize the auth server
const mcpServerAuth = await McpServerAuth.init();
// Or with custom data enrichment
const mcpServerAuth = await McpServerAuth.init({
onLogin: async (authInfo, request) => {
const userData = await db.users.findOne({ sub: authInfo?.extra?.sub });
return {
...authInfo,
extra: { ...authInfo.extra, ...userData }
};
},
});
// In your framework's route handler:
// 1. Expose the protected resource metadata
if (path === '/.well-known/oauth-protected-resource') {
const metadata = mcpServerAuth.getProtectedResourceMetadata('https://my-server.com/mcp');
return json(metadata);
}
// 2. Validate bearer tokens
try {
const authInfo = await mcpServerAuth.handleRequest(request);
// User data will be in authInfo.extra
} catch (error) {
return unauthorized('Authentication failed');
}
QQ 客户集成
这个库包括一个客户SDK,以方便地与MCP服务器集成,支持各种认证方法.
客户端建立在 v2 MCP 客户端软件包上, 因此在库旁安装并导入 @civic/auth-mcp/client 切入点 :
npm install @civic/auth-mcp @modelcontextprotocol/client
CLIClient 自动谈判协议版本( e)versionNegotiation: { mode: "auto" }它探测器 server/discover 用于协议修订版的服务器 2026-07-28 并返回 initialize 用于先前修改的服务器。 自己传 versionNegotiation 选项以覆盖此选项.
QQ CLI 客户端
CLI客户端允许您从命令行直接认证并连接到MCP服务器. 当需要认证时,它将自动打开浏览器窗口供用户完成认证流程.
import { CLIAuthProvider, RestartableStreamableHTTPClientTransport, CLIClient } from "@civic/auth-mcp/client";
// Create the auth provider
const authProvider = new CLIAuthProvider({
clientId: "your-client-id", // Get your client ID from auth.civic.com
// clientSecret: "your-secret", // Optional: only for non-PKCE auth servers
// successHtml: "<html><body><h1>Success!</h1></body></html>", // Optional: custom success page
// errorHtml: "<html><body><h1>Error: {{error}}</h1></body></html>", // Optional: custom error page
});
// Create the restartable transport with auth provider
// This transport allows restarting the connection after authorisation is granted
const transport = new RestartableStreamableHTTPClientTransport(
new URL("http://localhost:33006/mcp"),
{ authProvider }
);
// Create and connect client
const mcpClient = new CLIClient(
{ name: "cli-example", version: "0.0.1" },
{ capabilities: {} }
);
// Connect to the server
await mcpClient.connect(transport);
QQ 客户身份元数据文档( CIMD)
与其预先登记客户身份,你的客户可以用一个
客户端ID 元数据文档
(SEP-991) — 在 HTTPS URL 托管的 JSON 文件, 作为 OAuth 双倍 client_id。 。 。 .
这是自2025-11-25年以来MCP光谱中首选的登记机制,并用于
克劳德 克劳德代码 VS代码.
如果您的元数据文档已经在某处托管, 请通过它的 URL 而不是客户端 ID :
const authProvider = new CLIAuthProvider({
clientMetadataUrl: "https://myagent.example.com/oauth/client-metadata.json",
});
当授权服务器发布广告时 client_id_metadata_document_supported,URL为
直接用作 client_id;否则流量会回落到动态客户端注册.
预先登记的 clientId如果同时提供,则始终优先.
要管理文档本身,请使用 buildClientMetadataDocument 或服务于
快捷处理器 — 安装在其公共 URL 的准确路径上 :
import { clientMetadataHandler } from "@civic/auth-mcp";
import { LOOPBACK_REDIRECT_URIS } from "@civic/auth-mcp/client";
app.get(
"/oauth/client-metadata.json",
clientMetadataHandler({
url: "https://myagent.example.com/oauth/client-metadata.json",
clientName: "My Agent",
// For CLI/native clients use portless loopback URIs (RFC 8252);
// for web clients list your hosted callback URLs.
redirectUris: LOOPBACK_REDIRECT_URIS,
})
);
* 坚忍不拔
默认情况下,令牌被存储在内存中,并在进程退出时丢失. 您可以通过执行 TokenPersistence 接口.
记忆托肯持久( 默认)
托肯存储在内存中, 当进程退出时丢失 :
import { CLIAuthProvider, InMemoryTokenPersistence } from "@civic/auth-mcp/client";
const authProvider = new CLIAuthProvider({
clientId: "your-client-id",
tokenPersistence: new InMemoryTokenPersistence(), // Explicit, but this is the default
});
自定义托肯持久性
通过执行《公约》执行自己的持续战略 TokenPersistence 接口 :
import { TokenPersistence } from "@civic/auth-mcp/client";
import type { OAuthTokens } from "@modelcontextprotocol/client";
class MyTokenPersistence implements TokenPersistence {
async saveTokens(tokens: OAuthTokens): Promise<void> { ... }
async loadTokens(): Promise<OAuthTokens | undefined> { ... }
async clearTokens(): Promise<void> { ... }
}
const authProvider = new CLIAuthProvider({
clientId: "your-client-id",
tokenPersistence: new DatabaseTokenPersistence(),
});
磁盘认证
TokenAuth Provider简化了与MCP服务器的连接,预取了JWT令牌. 如果您有一个已经处理认证的应用程序,例如通过 公民联盟。 。 。 .
import { TokenAuthProvider, RestartableStreamableHTTPClientTransport } from "@civic/auth-mcp/client";
import { Client, StreamableHTTPClientTransport } from "@modelcontextprotocol/client";
// Create with pre-obtained token
const authProvider = new TokenAuthProvider("your-jwt-token");
// Create transport and client
const transport = new StreamableHTTPClientTransport(
new URL("http://localhost:33006/mcp"),
{ authProvider }
);
const mcpClient = new Client(
{ name: "example-client", version: "0.0.1" },
{ capabilities: {} }
);
await mcpClient.connect(transport);
动态客户注册
一些MCP客户端使用 OAuth 2.0 动态客户端注册 以自动注册到认证服务器.
这意味着发送给您的 MCP 服务器的客户端ID将不会匹配您的客户端ID,因为在每个客户端的注册过程中都会动态生成一个新的客户端ID.
@civic/auth-mcp 图书馆支持此计划。 为了启用它,设置 allowDynamicClientRegistration 选项到 true 在 MCP 服务器配置中 :
app.use(await auth({
allowDynamicClientRegistration: true,
}));
这将确保您的客户端ID在客户端注册期间传递到认证服务器,由此而来的信使只对您的MCP服务器有效.
注 - 此功能仅供公民认证提供者使用。 其他提供者的行为可能不同.
发行人接受
在使用Citizen Auth时,发现会给租户范围发行商(如:. https://auth.civic.com/oauth/<tenant>/),但符号验证接受 两者 那个租户范围发行人 财务报告和审定财务报表 基础公民发行商(https://auth.civic.com/oauth/) (中文(简体) ). 这使基础发行者能够发出像 client_credentials 指使和指使交换输出——和租户范围指使的指使都对同一服务器进行验证。 所有公民发行商共用一个签名密钥,所以接受两者不会削弱签名验证.
接受范围更广或不同的发行人(例如,在多租户部署中的任何公民租户),提供 issuerValidator 上游, 完全覆盖默认检查 :
app.use(await auth({
allowDynamicClientRegistration: true,
issuerValidator: (iss) => iss?.startsWith("https://auth.civic.com/oauth/") ?? false,
}));
OAuth 遗产支持
该图书馆包括支持 遗留 MCP OAuth 规格 确保与现有客户端兼容,同时向最新规格过渡.
重要:一旦所有主要客户都更新到目前的MCP规格,这种遗留支持将在未来版本被删除.
遗留 OAuth 模式 :
- 这是 默认启用 以确保最大兼容性
- 直接在MCP服务器上提供OAuth端点(例如,
/authorize, (中文(简体) ),/token(中文(简体) ) - 透明代理 OAuth 流到配置的授权服务器
禁用遗留 OAuth 支持( 一旦客户端更新后推荐) :
app.use(await auth({
enableLegacyOAuth: false,
}));
我们建议,一旦所有客户端更新后,通过授权服务器的发现,使用标准的OAuth流量,就监测您的客户端使用率和无效的遗留支持.
页:1 如果使用 Claude (Web 或桌面) 进行测试, 您需要先使用 https 将您的服务器部署到远程环境中 , 因为克洛德不支持本地主机MCP集成.
页:1 当使用后遗症 OAuth 流出于 a 代理服务器,您也可以启用 Express 的“信任代理”设置
(见 代理后快递),或配置 protocolHeader 财务报告和审定财务报表 hostHeader 选项
从代理信头读取正确的值:
// Option 1: Trust proxy (Express handles X-Forwarded-* headers)
app.enable('trust proxy');
// Option 2: Explicit header configuration
app.use(await auth({
protocolHeader: 'X-Forwarded-Proto',
hostHeader: 'X-Forwarded-Host',
}));
// Option 3: Force HTTPS regardless
app.use(await auth({ forceHttps: true }));
亚帕斯登山和善知识发现
人数 RFC 9728 (英语),则 .well-known/oauth-protected-resource 端点是通过在主机与资源路径之间插入众所周知的路径来构建的. 例如,如果资源处于 https://example.com/hub/mcp,客户端将在 :
GET /.well-known/oauth-protected-resource/hub/mcp
当在子路径上架起中间软件时(例如:. app.use("/hub", await auth())),著名的终点将在 /hub/.well-known/oauth-protected-resource。您需要重新配置一条规则(例如,在您的反向代理或Express app中)以进行路由 /.well-known/oauth-protected-resource/hub/mcp 改为 /hub/.well-known/oauth-protected-resource。 。 。 .
同样,遗留下来的OAuth端点/authorize, (中文(简体) ), /token, (中文(简体) ), /register, (中文(简体) ), /oauth/callback, (中文(简体) ), /.well-known/oauth-authorization-server)总是在根部广告. 当中间器件被安装在子路径上时,这些端点会被服务在该路径下(例如. /hub/authorize) (中文(简体) ). 您需要配置重写规则来引导根路径到挂载路径 .
自定义状态存储
默认情况下,遗留的OAuth模式使用一个内膜状态商店来管理重定向之间的OAuth流量状态. 对于有多个服务器或流程的生产部署,您可以提供自定义状态存储执行:
// Implement a custom state store (e.g., using Redis)
class RedisStateStore implements StateStore {
...
}
// Use the custom state store
app.use(await auth({
stateStore: new RedisStateStore(),
}));
配置
这个 auth() 中间软件接受以下配置选项:
| 选项 | 类型 | 默认 | 说明 |
|---|---|---|---|
clientId | string | 公共公民客户身份证 | OAuth 客户端 ID / 租户 ID 用于验证符号 |
wellKnownUrl | string | https://auth.civic.com/oauth/.well-known/openid-configuration | 认证服务器的 OIDC 配置的 URL |
scopesSupported | string[] | ['openid', 'profile', 'email'] | 支持的权限范围 |
protocolHeader | string | - 说吧 | 要读取协议的页眉名称( 例如 ). X-Forwarded-Proto(中文(简体) ) |
hostHeader | string | host | 要读取主机的页眉名称( 例如 ) . X-Forwarded-Host(中文(简体) ) |
basePath | string | / | 认证端点的基础路径 |
mcpRoute | string | /mcp | 用认证保护的 MCP 路由 |
onLogin | function | - 说吧 | 可选回调以自定义数据丰富认证信息 |
allowDynamicClientRegistration | boolean | false | 启用动态客户端注册 |
enableLegacyOAuth | boolean | true | 启用遗留 OAuth 代理模式( 已过期) |
stateStore | StateStore | 记忆店 | 自定义 OAuth 流量的状态存储( 只保存模式) |
jwks | object | - 说吧 | 本地 JWKS 测试( 通过远程 JWKS 获取) |
disableClientIdVerification | boolean | false | 跳过 client_id编号 :tid 检查 |
forceHttps | boolean | false | 强制元数据 URL 到 https (例如,在 TLS 终止代理后面) |
issuerValidator | function | - 说吧 | 优先于默认发行人检查; 如果返回, 接受一个符号 true 给标志的 iss |
为什么选择@civic/auth-mcp?
QQ 零功能设置
- 投放快递的中间软件
- 一线一体化
企业安全,启动速度
- 与Civil Auth公司无缝合作,Civil Auth是经过战斗测试的安全认证供应商
- 自动令牌刷新和会话管理
- 隐私第一设计,数据收集最少
- PKCE 支助
QQ 开发者经验第一
- 带有自动浏览器流量的 CLI 认证
- 多个认证模式: 令牌、 OAuth 流、 预认证
- TypeScript 第一种具有综合类型安全性
生产准备
- 全面的错误处理和重试逻辑
- 内建运输层与连接恢复
- 最小依赖的轻量级
接下来呢?
- 📚 文档: 综合指南 维基文库中相关的原始文献: docs.civic.com
- 🐛 问题: 报告错误或请求特性 GitHub 图像
- 💬 社区: 加入我们的Discord 支持和讨论
- 🔄 更新: 跟着 @ civikey (帮助) 用于更新
许可证
提供 作为,没有任何形式的保证,明示或暗示。 公民制造 没有特定目的的健康保障或持续支助。 。 。 . 使用此库仅受麻省理工学院许可条款的制约.
通过使用这一软件,你同意公民不应对其使用、履行或整合所产生的任何损害承担责任.
备注: @civic/auth-mcp 库作为开源项目发布于此 MIT 许可证。 。 。 .
它的提供没有保证或支持保证.