You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用MCP TypeScript SDK迭代messages遇TypeScript类型错误求助

MCP TypeScript SDK遍历messages类型问题解决

问题描述

使用MCP(Model Context Protocol)TypeScript SDK(@modelcontextprotocol/sdk)遍历getPrompt()返回的messages时,即使显式转换为GetPromptResult["messages"]类型,TypeScript仍提示错误:Property 'content' does not exist on type 'string'。预期message类型为包含role和content的对象,但TypeScript将其推断为string类型。

相关代码:

命令提取函数

/**
 * Checks if the user prompt is a slash command (e.g. "/format deposition.md"), fetches the corresponding MCP prompt, and returns the server-built messages.
 * Returns null if the query is not a slash command.
 * @param query User prompt (may start with a "/" command)
 * @param mcpClient Connected MCP Client instance
 * @returns Array of PromptMessages from the server, or null if not a command
 */
export const extractPromptCommand = async (query: string, mcpClient: Client) => {
    if(!query.startsWith("/")) return null;

    const [rawCommand, ...argParts] = query.slice(1).split(" ");
    const command = rawCommand?.trim();
    const argument = argParts.join(" ").trim();

    if(!command) return null;

    try {
        const { messages } = await mcpClient.getPrompt({
            name: command,
            ...(argument && { arguments: { doc_id: argument } })
        }) 

        return messages;
    }
    catch(error: any) {
        throw new Error(`Prompt command "/${command}" failed: ${error.message}`);
    }
}

遍历代码

// Handling the "/" commands
const promptMessage = await extractPromptCommand(prompt, mcpClient);

if(promptMessage) {
    for (const message in promptMessage as GetPromptResult["messages"]) {
        const msg = message.content;
    }
}

环境信息:

  • @modelcontextprotocol/sdk v1.29.0
  • TypeScript 6.0.2
  • Node.js 配置"module": "nodenext"

原因分析

  1. for...in的误用:for...in是用来遍历对象的键名的,对于数组来说,它遍历的是数组的索引字符串(比如"0"、"1"),而不是数组的元素本身。所以循环变量message被TypeScript推断为string类型,自然不存在content属性。
  2. 返回值类型未明确:extractPromptCommand函数没有标注返回值类型,导致TypeScript无法正确推断promptMessage的类型,即使你用as GetPromptResult["messages"]强制转换,也改变不了for...in遍历键名的行为。

正确解决方案

1. 明确函数返回值类型

给extractPromptCommand添加明确的返回值类型,让TypeScript能自动推断后续变量类型,避免不必要的类型断言:

import { Client, GetPromptResult } from '@modelcontextprotocol/sdk';

export const extractPromptCommand = async (
  query: string, 
  mcpClient: Client
): Promise<GetPromptResult["messages"] | null> => {
    if(!query.startsWith("/")) return null;

    const [rawCommand, ...argParts] = query.slice(1).split(" ");
    const command = rawCommand?.trim();
    const argument = argParts.join(" ").trim();

    if(!command) return null;

    try {
        const { messages } = await mcpClient.getPrompt({
            name: command,
            ...(argument && { arguments: { doc_id: argument } })
        }) 

        return messages;
    }
    catch(error: any) {
        throw new Error(`Prompt command "/${command}" failed: ${error.message}`);
    }
}

2. 使用正确的数组遍历方式

遍历数组要使用遍历元素的方式,比如for...of、forEach或普通for循环:

方式一:for...of循环(推荐)

直接遍历数组元素,TypeScript能正确推断元素类型:

const promptMessage = await extractPromptCommand(prompt, mcpClient);

if(promptMessage) {
    for (const message of promptMessage) {
        const msgContent = message.content; // 类型正确,无报错
    }
}

方式二:forEach遍历

利用数组的forEach方法遍历元素:

const promptMessage = await extractPromptCommand(prompt, mcpClient);

promptMessage?.forEach(message => {
    const msgContent = message.content; // 类型正确
});

方式三:普通for循环

通过索引访问数组元素:

const promptMessage = await extractPromptCommand(prompt, mcpClient);

if(promptMessage) {
    for (let i = 0; i < promptMessage.length; i++) {
        const message = promptMessage[i];
        const msgContent = message.content; // 类型正确
    }
}

内容的提问来源于stack exchange,提问作者Little Thinker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 18:24:52