GitHub_Trending/ty/typescript-sdk资源模板:动态内容生成与参数绑定

【免费下载链接】typescript-sdk The official Typescript SDK for Model Context Protocol servers and clients 【免费下载链接】typescript-sdk 项目地址: https://gitcode.com/GitHub_Trending/ty/typescript-sdk

核心功能概览

GitHub_Trending/ty/typescript-sdk是Model Context Protocol(MCP)的官方TypeScript SDK,提供了服务器和客户端实现的完整工具链。该SDK的核心价值在于其资源模板系统,能够实现动态内容生成与参数绑定,帮助开发者快速构建具备上下文感知能力的AI应用。

主要模块架构

该项目采用分层架构设计,主要包含以下核心模块:

  • 客户端模块:提供了多种传输协议实现,包括HTTP流、SSE(Server-Sent Events)和WebSocket,位于src/client/目录下
  • 服务器模块:实现了MCP服务器核心功能,包括资源管理、工具注册和认证授权,位于src/server/目录下
  • 资源模板系统:允许定义动态资源,支持URI参数绑定和内容生成,核心实现位于src/server/mcp.ts

资源模板基础

资源模板定义

资源模板是SDK中最强大的功能之一,它允许开发者定义动态资源,这些资源的内容可以根据请求参数或上下文动态生成。在src/server/mcp.ts中,ResourceTemplate类是这一功能的核心:

// 资源模板定义示例
const userProfileTemplate = new ResourceTemplate({
  uriTemplate: new UriTemplate("/users/{userId}"),
  completeCallback: async (paramName, value, context) => {
    // 参数自动补全逻辑
    if (paramName === "userId") {
      return await userService.findUserIdsStartingWith(value);
    }
    return [];
  }
});

URI模板与参数绑定

SDK使用URI模板(src/shared/uriTemplate.ts)实现参数化资源路径。通过UriTemplate类,可以轻松定义包含动态参数的资源路径:

// URI模板使用示例
const template = new UriTemplate("/api/resources/{category}/{id}");
const uri = template.expand({ category: "documents", id: "123" });
// 结果: "/api/resources/documents/123"

// 参数提取示例
const variables = template.match("/api/resources/images/456");
// 结果: { category: "images", id: "456" }

动态内容生成实践

服务器端实现

下面我们通过src/examples/server/simpleStreamableHttp.ts中的示例,了解如何创建支持动态内容生成的MCP服务器:

// 创建MCP服务器实例
const server = new McpServer({
  name: 'simple-streamable-http-server',
  version: '1.0.0',
  websiteUrl: 'https://github.com/modelcontextprotocol/typescript-sdk',
});

// 注册动态资源模板
server.resource(
  "userProfileTemplate",
  new ResourceTemplate({
    uriTemplate: new UriTemplate("/users/{userId}"),
    completeCallback: async (paramName, value) => {
      if (paramName === "userId") {
        return await userService.searchUsers(value);
      }
      return [];
    },
    listCallback: async (extra) => {
      const users = await userService.listUsers();
      return {
        resources: users.map(user => ({
          uri: `/users/${user.id}`,
          name: user.name,
          mimeType: "application/json"
        }))
      };
    }
  }),
  async (uri, variables, extra) => {
    // 动态内容生成逻辑
    const user = await userService.getUserById(variables.userId);
    return {
      contents: [{
        uri,
        text: JSON.stringify(user),
        mimeType: "application/json"
      }]
    };
  }
);

客户端使用方式

客户端可以通过多种传输协议访问这些动态资源。以Streamable HTTP传输为例:

// 创建Streamable HTTP客户端
const transport = new StreamableHTTPClientTransport({
  serverUrl: "http://localhost:3000/mcp"
});

const client = new Client(transport);

// 读取动态资源
const result = await client.readResource("/users/123");
console.log(result.contents[0].text); // 用户123的资料JSON

高级特性

参数自动补全

SDK提供了强大的参数自动补全功能,当用户输入资源URI时,可以根据上下文提供参数建议。这一功能在src/server/mcp.tshandleResourceCompletion方法中实现:

private async handleResourceCompletion(
  request: CompleteRequest,
  ref: ResourceTemplateReference,
): Promise<CompleteResult> {
  const template = Object.values(this._registeredResourceTemplates).find(
    (t) => t.resourceTemplate.uriTemplate.toString() === ref.uri,
  );

  if (!template) {
    throw new McpError(
      ErrorCode.InvalidParams,
      `Resource template ${request.params.ref.uri} not found`,
    );
  }

  const completer = template.resourceTemplate.completeCallback(
    request.params.argument.name,
  );
  if (!completer) {
    return EMPTY_COMPLETION_RESULT;
  }

  const suggestions = await completer(request.params.argument.value, request.params.context);
  return createCompletionResult(suggestions);
}

资源链接与内容嵌入

SDK支持资源链接(ResourceLink)功能,允许在返回结果中包含对其他资源的引用,而不是直接嵌入内容:

// 资源链接示例
server.registerTool(
  "list-files",
  {
    title: "List Files with ResourceLinks",
    description: "Returns a list of files as ResourceLinks",
    inputSchema: {}
  },
  async (): Promise<CallToolResult> => {
    return {
      content: [
        {
          type: "text",
          text: "Available files:"
        },
        {
          type: "resource_link",
          uri: "https://example.com/greetings/default",
          name: "Default Greeting",
          mimeType: "text/plain"
        },
        {
          type: "resource_link",
          uri: "file:///example/report.pdf",
          name: "Monthly Report",
          mimeType: "application/pdf"
        }
      ]
    };
  }
);

实践案例

用户信息管理系统

以下是一个完整的用户信息管理系统示例,展示了如何结合资源模板、参数绑定和动态内容生成:

// 1. 定义用户资源模板
const userTemplate = new ResourceTemplate({
  uriTemplate: new UriTemplate("/users/{userId}"),
  completeCallback: async (paramName, value) => {
    if (paramName === "userId") {
      const users = await userService.searchUsers(value);
      return users.map(user => ({
        value: user.id,
        label: `${user.name} (${user.id})`
      }));
    }
    return [];
  },
  listCallback: async () => {
    const users = await userService.getAllUsers();
    return {
      resources: users.map(user => ({
        uri: `/users/${user.id}`,
        name: user.name,
        mimeType: "application/json"
      }))
    };
  }
});

// 2. 注册资源模板
server.resource(
  "userProfile",
  userTemplate,
  async (uri, variables) => {
    const user = await userService.getUserById(variables.userId);
    return {
      contents: [{
        uri,
        text: JSON.stringify({
          id: user.id,
          name: user.name,
          email: user.email,
          createdAt: user.createdAt
        }),
        mimeType: "application/json"
      }]
    };
  }
);

// 3. 注册操作工具
server.tool(
  "update-user",
  "Updates user information",
  {
    userId: z.string().describe("User ID"),
    name: z.string().optional().describe("New name"),
    email: z.string().optional().describe("New email")
  },
  async ({ userId, name, email }) => {
    await userService.updateUser(userId, { name, email });
    return {
      content: [{
        type: "text",
        text: `User ${userId} updated successfully`
      }]
    };
  }
);

最佳实践与性能优化

缓存策略

对于频繁访问的动态资源,建议实现缓存机制:

// 带缓存的资源实现示例
const cache = new Map();
const CACHE_TTL = 5 * 60 * 1000; // 5分钟缓存

server.resource(
  "product-info",
  new ResourceTemplate({
    uriTemplate: new UriTemplate("/products/{productId}")
  }),
  async (uri, variables) => {
    const cacheKey = variables.productId;
    
    // 检查缓存
    const cached = cache.get(cacheKey);
    if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
      return cached.data;
    }
    
    // 获取新数据
    const product = await productService.getProduct(variables.productId);
    const result = {
      contents: [{
        uri,
        text: JSON.stringify(product),
        mimeType: "application/json"
      }]
    };
    
    // 更新缓存
    cache.set(cacheKey, {
      timestamp: Date.now(),
      data: result
    });
    
    return result;
  }
);

错误处理

完善的错误处理对于动态资源至关重要:

// 资源错误处理示例
server.resource(
  "sensitive-data",
  new ResourceTemplate({
    uriTemplate: new UriTemplate("/secrets/{secretId}")
  }),
  async (uri, variables, extra) => {
    try {
      // 权限检查
      if (!await authService.hasAccess(extra.user, variables.secretId)) {
        throw new UnauthorizedError("Access denied to this resource");
      }
      
      const secret = await secretService.getSecret(variables.secretId);
      return {
        contents: [{
          uri,
          text: JSON.stringify(secret),
          mimeType: "application/json"
        }]
      };
    } catch (error) {
      // 错误日志记录
      logger.error(`Error accessing resource ${uri}:`, error);
      
      // 返回适当的错误响应
      if (error instanceof UnauthorizedError) {
        throw new McpError(ErrorCode.Unauthorized, error.message);
      }
      throw new McpError(ErrorCode.InternalError, "Failed to retrieve resource");
    }
  }
);

总结与后续学习

GitHub_Trending/ty/typescript-sdk的资源模板系统为动态内容生成和参数绑定提供了强大支持,主要优势包括:

  1. 灵活性:通过URI模板和动态生成逻辑,可以轻松应对各种复杂的内容需求
  2. 可扩展性:多种传输协议支持,易于集成到现有系统
  3. 开发者友好:类型安全的API设计,完善的错误处理机制

要深入学习该SDK,建议进一步研究以下资源:

  • 示例代码src/examples/目录包含各种使用场景的完整示例
  • 测试用例src/integration-tests/提供了更多高级用法
  • API文档:查看各模块的JSDoc注释了解详细用法

通过掌握资源模板的使用,您可以构建出高度动态且上下文感知的AI应用,为用户提供更加智能和个性化的体验。

【免费下载链接】typescript-sdk The official Typescript SDK for Model Context Protocol servers and clients 【免费下载链接】typescript-sdk 项目地址: https://gitcode.com/GitHub_Trending/ty/typescript-sdk

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐