Token导航 LogoToken导航TokenDH.com
Arcade MCP Ts logo
安全风控stdio官方级别未说明来源级核验

Arcade MCP Ts

MCP Server

@arcadeai/arcade-mcp

一个支持秘密注入、OAuth认证、多用户支持、工作路由和中间件的TypeScript MCP框架,适用于开发高效的多用户工具服务。

工具数

1

提示词数

0

GitHub Stars

2

资源数

0
TypeScriptClaude安全Claude

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

作者 / 组织

ArcadeAI

提供方

ArcadeAI

最后核验

2026/5/17 20:21

运行时

Node.js

快速接入

先看主来源和安装命令,再打开仓库或文档;下面只保留这个条目的关键接入事实。

命令预览

npx @arcadeai/arcade-mcp # auto-discover tools, run stdio

详细介绍

@arcadeai/arcade-mcp

TypeScript MCP框架,带有秘密注入、OAuth身份验证提供者、多用户支持、工作路由和中间件。包裹官方 @modelcontextprotocol/sdk --切勿对其进行分叉或修补。

快速开始

bun add @arcadeai/arcade-mcp
import { MCPApp } from "@arcadeai/arcade-mcp";
import { z } from "zod";

const app = new MCPApp({
  name: "MyServer",
  version: "1.0.0",
  instructions: "A helpful tool server",
});

app.tool(
  "greet",
  {
    description: "Greet someone by name",
    parameters: z.object({
      name: z.string().describe("Name to greet"),
    }),
  },
  async (args) => `Hello, ${args.name}!`,
);

app.run(); // stdio by default

运行它:

bun run server.ts

或者通过HTTP:

app.run({ transport: "http", port: 8000 });

CLI自动发现

在不写入服务器文件的情况下运行MCP服务器。CLI会自动发现当前目录中的工具模块:

npx @arcadeai/arcade-mcp          # auto-discover tools, run stdio
npx @arcadeai/arcade-mcp --http   # auto-discover tools, run HTTP

工具模块可以从以下位置找到:

  • *.tools.ts / *.tools.js 文件(例如。, math.tools.ts)
  • a中的任何文件 tools/ 目录(例如。, tools/greet.ts)

每个文件都应导出工具定义:

// tools/greet.ts
import { z } from "zod";

export const greetTools = {
  greet: {
    options: {
      description: "Greet someone",
      parameters: z.object({ name: z.string() }),
    },
    handler: async (args) => `Hello, ${args.name}!`,
  },
};

CLI选项:

标志默认值描述
--http--使用HTTP传输(默认:stdio)
--host 127.0.0.1HTTP主机
--port 8000HTTP端口
--name 目录名称应用程序名称
`--dir
`cwd要扫描的目录
--dev--文件更改时自动重新加载(仅限HTTP)
Node.js+TypeScript:使用 npx tsx arcade-mcp 或Bun进口 .ts 工具文件直接。

开发模式(自动重新加载)

监视源文件并在发生更改时自动重新启动服务器:

npx @arcadeai/arcade-mcp --http --dev

或者以编程方式:

app.run({ transport: "http", dev: true });

当a .ts, .js, .mts,或 .mjs 文件更改后,服务器停止,用新副本重新导入工具模块,然后重新启动。文件在 node_modules/, dist/,并且忽略隐藏目录。

备注:开发模式仅适用于HTTP传输。Stdio会话无法重新启动。

您还可以通过以下方式启用开发模式 ARCADE_SERVER_RELOAD=1 环境变量。

特性

  • 生成器APIapp.tool(name, options, handler) 使用方法链
  • 秘密注射 --env-vars自动捕获并注入到工具上下文中
  • OAuth身份验证提供者 --21家提供商:GitHub、谷歌、Slack、微软、Linear、Notion等。
  • 上下文对象 --用于日志记录、进度、采样、资源、工具、UI的命名空间外观
  • 中间件 --具有方法特定钩子的可组合洋葱模型中间件
  • 多用户HTTP身份验证 --通过JWKS验证JWT承载令牌
  • 工人路线/worker/tools, /worker/tools/invoke, /worker/health
  • 错误层次结构 --支持重试的结构化错误,上游错误映射
  • 提示app.prompt(name, options, handler) 具有参数验证和运行时管理
  • 资源app.resource(uri, options, handler) 具有MIME类型和运行时管理
  • 开发模式 --文件更改时自动重新加载 --dev 标志(仅限HTTP)
  • 可恢复流 --HTTP流可恢复性的可选事件存储 Last-Event-ID
  • 评估 --使用评论家、量规和匈牙利语最佳匹配来评估LLM工具调用的准确性
  • 双重运输 --stdio和HTTP(Elysia+流式HTTP)
  • 运行时兼容 --Bun和Node.js(否 Bun.* 库代码中的API)

工具选项

基本工具

app.tool(
  "echo",
  {
    description: "Echo a message",
    parameters: z.object({
      message: z.string(),
    }),
  },
  async (args) => args.message,
);

OAuth工具

import { auth } from "@arcadeai/arcade-mcp";

app.tool(
  "star_repo",
  {
    description: "Star a GitHub repository",
    parameters: z.object({
      owner: z.string(),
      repo: z.string(),
    }),
    auth: auth.GitHub({ scopes: ["repo"] }),
  },
  async (args, context) => {
    const token = context.getAuthToken();
    // ... use token to call GitHub API
    return { starred: true };
  },
);

秘密工具

app.tool(
  "get_repo",
  {
    description: "Get repo info",
    parameters: z.object({ repo: z.string() }),
    secrets: ["GITHUB_TOKEN"],
  },
  async (args, context) => {
    const token = context.getSecret("GITHUB_TOKEN");
    // ... use token
  },
);

任何未加前缀的env变量 MCP__ 可作为工具秘密使用。

带有行为提示的工具

用映射到MCP的行为提示注释工具 ToolAnnotations:

app.tool(
  "delete_file",
  {
    description: "Delete a file from the workspace",
    parameters: z.object({ path: z.string() }),
    behavior: {
      readOnly: false,
      destructive: true,
      idempotent: true,
      openWorld: false,
    },
  },
  async (args) => {
    // ...
  },
);

这些提示如下 readOnlyHint, destructiveHint, idempotentHint,以及 openWorldHint 在MCP工具列表中。

弃用的工具

将工具标记为已弃用——该消息将附加在描述之前:

app.tool(
  "old_search",
  {
    description: "Search for items",
    parameters: z.object({ query: z.string() }),
    deprecationMessage: "Use search_v2 instead",
  },
  async (args) => {
    // ...
  },
);
// Description seen by clients: "[DEPRECATED: Use search_v2 instead] Search for items"

工具标题

提供人类可读的显示名称:

app.tool(
  "gh_star",
  {
    description: "Star a GitHub repository",
    parameters: z.object({ repo: z.string() }),
    title: "Star Repository",
  },
  async (args) => {
    // ...
  },
);

工具包版本控制

应用程序的 name, version,以及 title 作为工具包元数据自动附加到每个工具。您还可以覆盖每个工具的工具包信息:

app.tool(
  "myTool",
  {
    description: "A tool with custom toolkit info",
    parameters: z.object({}),
    toolkit: { name: "my-toolkit", version: "1.2.0" },
  },
  async () => {},
);

版本已标准化为semver-- "1" 成为 "1.0.0", "v1.2" 成为 "1.2.0".

提示

注册提示 app.prompt(name, options, handler?):

app.prompt(
  "greeting",
  {
    description: "Generate a greeting",
    arguments: [{ name: "name", description: "Name to greet", required: true }],
  },
  (args) => ({
    messages: [
      {
        role: "user",
        content: { type: "text", text: `Please greet ${args.name} warmly.` },
      },
    ],
  }),
);

选项: description?arguments? (数组 { name, description?, required? }).如果没有提供处理程序,则默认处理程序将描述作为用户消息返回。

运行时管理(之后 app.run()):

app.prompts.add("new-prompt", { description: "Added at runtime" }, handler);
app.prompts.remove("new-prompt");
app.prompts.list(); // returns registered prompt names

资源

注册资源 app.resource(uri, options, handler?):

app.resource(
  "config://app",
  { description: "Application configuration", mimeType: "application/json" },
  (uri) => ({
    contents: [
      {
        uri: uri.href,
        mimeType: "application/json",
        text: JSON.stringify({ name: "EchoServer", version: "1.0.0" }),
      },
    ],
  }),
);

选项: description?mimeType?。如果没有提供处理程序,默认处理程序将返回空文本内容。

运行时管理(之后 app.run()):

app.resources.add("data://users", { mimeType: "application/json" }, handler);
app.resources.remove("data://users");
app.resources.list(); // returns registered resource URIs

认证提供商

21个OAuth2提供程序的工厂功能:

import { auth } from "@arcadeai/arcade-mcp";

auth.GitHub({ scopes: ["repo"] })
auth.Google({ scopes: ["https://www.googleapis.com/auth/calendar"] })
auth.Slack({ scopes: ["chat:write"], id: "my-slack" })
auth.Microsoft()
auth.Linear()
auth.Notion()
// ... Asana, Atlassian, Attio, ClickUp, Discord, Dropbox,
//     Figma, Hubspot, LinkedIn, PagerDuty, Reddit, Spotify,
//     Twitch, X, Zoom

Arcade Cloud Auth(本地开发)

工具与 auth 需求通过以下方式自动解析OAuth令牌 街机云。设置凭据有两种方法:

选项1:Arcade CLI(推荐)

安装Arcade CLI并登录。这将凭据存储在 ~/.arcade/credentials.yaml 框架自动读取:

pip install arcade-ai
arcade login

就是这样——不需要环境变量。运行您的服务器,工具将通过您的Arcade帐户进行身份验证:

bun run examples/github-tools/server.ts

选项2:环境变量

ARCADE_API_KEYARCADE_USER_ID 直接:

export ARCADE_API_KEY="your-arcade-api-key"
export ARCADE_USER_ID="your-user-id"

环境变量优先于凭据文件。

运作原理

当一个工具 auth 被调用,该框架调用Arcade Cloud的授权API:

  1. 第一个电话 --返回一个授权URL。在浏览器中访问该URL以完成OAuth流程。
  2. 重试该工具 --令牌现在可用并注入 context.getAuthToken().

这是自动的,不需要更改代码。相同的工具在本地(通过Arcade Cloud身份验证)和部署(通过ArcadeCloud直接注入令牌的工作路由)都能工作。

ARCADE_AUTH_DISABLED=true 跳过身份验证解析(对于使用模拟令牌进行测试很有用)。

上下文

工具处理程序接收 (args, context)。上下文提供了命名空间的立面:

app.tool("example", opts, async (args, context) => {
  // Secrets & auth
  context.getSecret("API_KEY");
  context.getAuthToken();
  context.getAuthTokenOrEmpty();

  // Logging
  context.log.info("Processing request");
  context.log.debug("Details", { extra: "data" });
  context.log.warning("Watch out");
  context.log.error("Something failed");

  // Progress
  await context.progress.report(50, 100, "Halfway done");

  // Notifications (deduplicated, flushed at end of request)
  await context.notifications.tools.listChanged();
  await context.notifications.resources.listChanged();
  await context.notifications.prompts.listChanged();

  // Metadata
  context.signal;      // AbortSignal
  context.sessionId;   // string | undefined
  context.requestId;   // string
  context.userId;      // string | undefined
});

中间件

具有洋葱模型的可组合中间件。覆盖任何钩子:

import { Middleware, composeMiddleware } from "@arcadeai/arcade-mcp";

class RateLimitMiddleware extends Middleware {
  async onCallTool(context, next) {
    // before
    const result = await next(context);
    // after
    return result;
  }
}

const app = new MCPApp({
  name: "MyServer",
  version: "1.0.0",
  middleware: composeMiddleware(
    new RateLimitMiddleware(),
  ),
});

可用挂钩: onMessage, onRequest, onCallTool, onListTools, onReadResource, onListResources, onListResourceTemplates, onGetPrompt, onListPrompts.

内置中间件(默认启用):

  • 错误处理中间件 --捕获错误,返回结构化MCP错误响应
  • 日志中间件 --记录请求/响应时间(自动检测TTY以获得漂亮的输出;用覆盖 MCP_LOG_FORMAT=json|pretty)

多用户HTTP身份验证

根据JWKS端点验证JWT承载令牌:

import { MCPApp, JWTResourceServerValidator } from "@arcadeai/arcade-mcp";

const app = new MCPApp({
  name: "MyServer",
  version: "1.0.0",
  auth: new JWTResourceServerValidator({
    canonicalUrl: "https://mcp.example.com/mcp",
    authorizationServers: [{
      authorizationServerUrl: "https://auth.example.com",
      issuer: "https://auth.example.com",
      jwksUri: "https://auth.example.com/.well-known/jwks.json",
      algorithm: "RS256",
      expectedAudiences: ["my-client-id"],
    }],
  }),
});

app.run({ transport: "http", port: 8000 });

支持RFC 9728 OAuth保护资源元数据发现。当 canonicalUrl 具有非根路径(例如。 https://example.com/mcp),两者 /.well-known/oauth-protected-resource/.well-known/oauth-protected-resource/mcp 已注册以实现向后兼容性。响应包括CORS标头。

可恢复流

启用HTTP流可恢复性,以便断开连接的客户端可以使用 Last-Event-ID 头球

import { MCPApp, InMemoryEventStore } from "@arcadeai/arcade-mcp";

const app = new MCPApp({ name: "MyServer", version: "1.0.0" });

app.run({
  transport: "http",
  eventStore: new InMemoryEventStore(),
});

这个 InMemoryEventStore 适用于单进程部署。对于分布式系统,实现 EventStore 与持久后端的接口:

import type { EventStore, EventId, StreamId } from "@arcadeai/arcade-mcp";
import type { JSONRPCMessage } from "@modelcontextprotocol/sdk/types.js";

class RedisEventStore implements EventStore {
  async storeEvent(streamId: StreamId, message: JSONRPCMessage): Promise {
    // Store in Redis...
  }
  async replayEventsAfter(
    lastEventId: EventId,
    { send }: { send: (eventId: EventId, message: JSONRPCMessage) => Promise },
  ): Promise {
    // Replay from Redis...
  }
}

会话管理

HTTP传输使用 HTTPSessionManager 支持有状态(默认)和无状态模式、基于TTL的会话驱逐和最大会话上限:

app.run({
  transport: "http",
  stateless: false,       // true = fresh transport per request, no session reuse
  sessionTtlMs: 300_000,  // evict idle sessions after 5 minutes
  maxSessions: 100,       // reject new sessions with 503 when at capacity
});

有状态模式 (默认),会话通过以下方式重用 mcp-session-id 头球无效的会话ID将收到400响应。

无状态模式,每个请求都会得到一个新的传输和服务器——不会跟踪任何会话。

您还可以使用 HTTPSessionManager 直接进行更多控制:

import { HTTPSessionManager } from "@arcadeai/arcade-mcp";

const manager = new HTTPSessionManager({
  server: arcadeMcpServer,
  sessionTtlMs: 60_000,
  maxSessions: 50,
});

// In your HTTP handler:
const response = await manager.handleRequest(request, { authInfo });

// Graceful shutdown:
await manager.close();

每个有状态的HTTP会话都由一个 ServerSession 它补充道:

  • 初始化状态跟踪NOT_INITIALIZED → INITIALIZING → INITIALIZED
  • 服务器发起的请求createMessage(), elicitInput(), listRoots() 具有超时和错误处理功能
  • 会话范围的数据 --通过以下方式为每个会话存储密钥/值 getData() / setData()
  • 通知广播NotificationManager 向所有或选定会话发送工具/资源/提示列表更改通知

这个 Context 立面 context.sampling.createMessage()context.ui.elicit() 自动委派给 ServerSession 如果可用。

工人路线

ARCADE_WORKER_SECRET 已设置,公开Arcade Cloud集成的工具执行端点:

import { createWorkerRoutes } from "@arcadeai/arcade-mcp";

const workerApp = createWorkerRoutes({
  catalog: app.catalog,
  secret: process.env.ARCADE_WORKER_SECRET,
});
端点方法身份验证描述
/worker/toolsGETBearer列出可用工具(裸阵列)
/worker/tools/invokePOST承载执行工具
/worker/healthGET健康检查

worker wire格式与Python匹配 arcade-mcp 框架准确:

  • GET /worker/tools 返回一个包含工具定义的JSON数组(未包装在 { tools: [...] }),使用 input.parameters 随着 value_schema (不是JSON模式 inputSchema), fully_qualified_name, requirements,以及 output 领域。
  • POST /worker/tools/invoke 接受 { tool: { name, toolkit, version }, inputs, context: { user_id, authorization, secrets, metadata }, run_id, execution_id, created_at }.
  • 回复 使用 snake_case 字段名称(execution_id, finished_at)结构化 output: { value, error: { message, kind, can_retry, ... }, requires_authorization }.
  • 工具名称分隔符 默认为 . (例如。, MyToolkit.echo),可通过以下方式配置 ARCADE_TOOL_NAME_SEPARATOR.

错误处理

工具执行的结构化错误层次结构:

import {
  RetryableToolError,
  FatalToolError,
  UpstreamError,
  ContextRequiredToolError,
} from "@arcadeai/arcade-mcp";

// Retryable error (LLM will retry)
throw new RetryableToolError("Rate limited, try again", {
  retryAfterMs: 5000,
  additionalPromptContent: "Wait a moment before retrying",
});

// Fatal error (no retry)
throw new FatalToolError("API key is invalid");

// Upstream service error (auto-maps status codes)
throw new UpstreamError("GitHub API failed", { statusCode: 503 });

// Needs more context from the user
throw new ContextRequiredToolError("Missing info", {
  additionalPromptContent: "Please specify the repository owner",
});

遥测(开放遥测)

内置OpenTetry支持跟踪和指标,通过OTLP HTTP导出。

使用环境变量启用:

ARCADE_MCP_OTEL_ENABLE=true \
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 \
bun run server.ts

启用后,框架会自动:

  • 创建 RunTool 围绕每个MCP工具执行( tool_name, toolkit_name, environment 属性)
  • 创建 CallToolCatalog 工人路线中的跨度
  • 增量a tool_call 每次工具调用的计数器度量
  • 通过OTLP HTTP将跟踪和指标导出到配置的端点

OTLP端点、标头和协议通过标准配置 OTEL_EXPORTER_OTLP_* env变量。

变量默认值描述
ARCADE_MCP_OTEL_ENABLEfalse启用开放遥测
OTEL_SERVICE_NAMEarcade-mcp-worker跟踪中的服务名称
OTEL_EXPORTER_OTLP_ENDPOINT--OTLP收集器端点
ARCADE_ENVIRONMENTdev部署环境名称

您还可以使用 OTELHandler 直接用于自定义集成:

import { OTELHandler } from "@arcadeai/arcade-mcp";

const telemetry = new OTELHandler({
  enable: true,
  serviceName: "my-service",
  environment: "production",
});
telemetry.initialize();
// ... use telemetry.getTracer(), telemetry.getMeter()
await telemetry.shutdown();

评估

评估LLM如何使用您的工具。定义预期的工具调用,并与批评者一起对结果进行评分。

import { EvalSuite, BinaryCritic, NumericCritic, SimilarityCritic } from "@arcadeai/arcade-mcp";

基本评估

const suite = new EvalSuite({
  name: "My Tool Eval",
  systemMessage: "You are a helpful assistant.",
  rubric: { failThreshold: 0.85, warnThreshold: 0.95 },
});

// Register tools (MCP-style definitions)
suite.addToolDefinitions([
  {
    name: "greet",
    description: "Greet someone by name",
    inputSchema: {
      type: "object",
      properties: { name: { type: "string" } },
      required: ["name"],
    },
  },
]);

// Add test cases
suite.addCase({
  name: "Greet Alice",
  userMessage: "Say hello to Alice",
  expectedToolCalls: [{ toolName: "greet", args: { name: "Alice" } }],
  critics: [new BinaryCritic({ field: "name" })],
});

// Run against an LLM
import Anthropic from "@anthropic-ai/sdk";

const results = await suite.run({
  client: new Anthropic(),
  model: "claude-sonnet-4-20250514",
  provider: "anthropic",
});

for (const c of results.cases) {
  console.log(`${c.evaluation.passed ? "PASS" : "FAIL"} ${c.name} (${c.evaluation.score})`);
}

OpenAI也能工作——通过 OpenAI 自动检测客户端和提供者。

使用工具目录

如果您已经在 MCPAppToolCatalog,直接添加它们:

suite.addFromCatalog(app.catalog);

批评者

评论家们对工具调用的各个论点进行了评分:

评论家用例关键选项
BinaryCritic完全相等(带类型强制)field, weight?
NumericCritic模糊数值范围匹配field, valueRange, matchThreshold?, weight?
SimilarityCritic词频余弦相似度field, similarityThreshold?, weight?
// Exact match
new BinaryCritic({ field: "city" })

// Numeric within range [1, 7], match if similarity >= 0.9
new NumericCritic({ field: "days", valueRange: [1, 7], matchThreshold: 0.9 })

// String similarity >= 0.75
new SimilarityCritic({ field: "description", similarityThreshold: 0.75 })

评分标准

这个 EvalRubric 控制通过/失败/警告阈值:

选项默认值描述
failThreshold0.8通过的最低分数
warnThreshold0.9低于此分数会触发警告
failOnToolSelectiontrue如果调用了错误的工具,则立即失败
failOnToolCallQuantitytrue如果呼叫次数错误,立即失败
toolSelectionWeight1.0工具名称匹配的权重

跑步逃生

# With Anthropic
ANTHROPIC_API_KEY=sk-ant-... bun run examples/evals/echo-eval.ts

# With OpenAI
OPENAI_API_KEY=sk-... bun run examples/evals/echo-eval.ts

examples/evals/ 查看完整示例。

示例

这个 examples/ 目录包含演示不同功能的可运行服务器。使用以下命令运行任何示例:

bun run examples/echo/server.ts

配置

所有设置都从环境变量加载:

变量默认值描述
MCP_SERVER_NAMEArcadeMCP服务器名称
MCP_SERVER_VERSION0.1.0服务器版本
MCP_SERVER_INSTRUCTIONS--服务器说明
MCP_MIDDLEWARE_ENABLE_LOGGINGtrue启用日志中间件
MCP_MIDDLEWARE_LOG_LEVELINFO日志级别
MCP_LOG_FORMATauto日志格式: json (结构化), pretty (彩色,人类可读),或自动(TTY格式,JSON格式)
MCP_MIDDLEWARE_MASK_ERROR_DETAILSfalse向客户端隐藏错误详细信息
ARCADE_MCP_OTEL_ENABLEfalse启用OpenTetry遥测
OTEL_SERVICE_NAMEarcade-mcp-workerOTEL服务名称
ARCADE_WORKER_SECRET--工人路线的承载令牌
ARCADE_API_KEY-Arcade API密钥
ARCADE_API_URLhttps://api.arcade.devArcade API URL
ARCADE_USER_ID--默认用户ID
ARCADE_TOOL_NAME_SEPARATOR.FQN中工具包和工具名称之间的分隔符

.env.example 查看完整列表。

许可证

麻省理工学院

目录标签

目录标签

TypeScriptClaude安全TypeScript框架本地部署OAuth认证秘密管理多用户支持工具开发

支持客户端

Claude

接入字段

传输方式(transport,传输协议)

stdio

鉴权方式(authType,认证方式)

oauth

运行时(runtime,运行环境)

Node.js

来源包(packageName,安装包名)

@arcadeai/arcade-mcp

工具数量(toolCount,工具数)

1

资源数量(resourceCount,资源数)

0

提示词数量(promptCount,提示词数)

0

权限和风险

stdiooauth部署方式未说明

接入前请确认传输方式、认证方式和部署位置,并根据实际工具能力限制访问范围。

安装前确认

不要直接授予不必要的文件、网络或账号权限;先核对安装命令和配置内容。

来源信息

继续浏览同类 MCP