跳到正文
社区版开源 Web · 最新文档 · 0.2.10内容核对:2026-10-23查看 Markdown

6.4 开发应用 ​

应用为员工提供一项可添加的能力。它可以是一套方法,也可以连接业务系统。本篇先做一个方法型应用,再运行一个只读 MCP 服务。

在平台用自然语言创建 ​

本节示例已用真实 MiniMax 验证;相关修复已包含在 0.2.10 中。截图使用虚构反馈,生成内容以实际模型输出为准。

做一个无需账号的方法应用 ​

打开 市场 > 我的应用与技能 > 添加应用或技能(+)> 创建应用,选择 制作可分享的应用模板。输入以下说明,点 继续,到会话中核对并发送:

text
制作一个“客户反馈台”应用模板,包含一个“客户反馈台简报”技能,
技能标识用 feedback-desk-brief,避免与独立技能同名。
方法:归类我提供的编号反馈,统计数量,列出依据和待确认项。
只使用输入文字,不连接账号、不读外部系统、不包含员工。
这是原创示例,采用 MIT 许可。应用模板使用 feedback-desk-app,
版本 1.0.1。先给我应用及技能内容的完整预览,不发布。

检查草稿包含真实技能正文、固定版本和许可,没有凭据或不存在的连接。点 预览并分享,核对内容后导出离线文件或生成在线链接。到 员工 > 导入模板 选择文件或粘贴链接,读取预览并确认添加,勾选随包技能的安装选项。

在 我的应用与技能 核对 feedback-desk-brief 已可用;如果同名技能遮蔽了它,先解决冲突,不能把“有安装记录”当作可调用。新开会话,要求“先加载已安装的 feedback-desk-brief”,再提供 SKILL 示例的三条反馈及计数口径,应得到 2 条和 1 条,并保留来源。给员工使用还需关联该方法。

自然语言创建的方法应用预览

本地 MiniMax 实测:客户反馈台应用包含独立技能,接收后安装方法,再用具体输入试做。生成模板本身不会安装应用。 点击图片查看原图。

接入自己的 MCP 服务 ​

先运行本篇后面的只读示例服务,再从 创建应用 输入:

text
添加一个名为“示例订单”的 MCP 应用。
服务地址:http://127.0.0.1:3277/mcp
使用 Streamable HTTP;这个本机示例不需要认证。
先预览连接定义,不调用工具、不授权给员工。

核对地址后,在连接确认区点击 添加并连接。本例应实际发现 get_demo_order;只把该工具授权给测试员工,再交办“读取 DEMO-001,告诉我金额和状态”。应得到 115 CNY、draft。服务未启动时应显示连接失败;启动后重试同一连接,不重复添加。

把示例换成自己的服务时,填写真实地址与认证方式,密钥仅在专用认证控件中输入。自然语言说明不会替你部署服务或创建 API。

先做不接外部账号的方法型应用 ​

下载应用开发示例。解压 app.json,在 员工 > 导入模板 的接收窗口选择该文件预览。示例应用只有一个 evidence-brief 技能,没有员工和连接;它与独立 SKILL 可以使用相同的方法,但保留应用主体。

示例的 app.json 声明应用主体,方法正文在 sources/skills/evidence-brief/SKILL.md。修改后,在解压目录运行 node pack.mjs app.json,再导入更新后的文件。共用格式见资源打包与分发。

应用中的方法只处理本人给定资料;有多个技能时逐项声明,不根据名称自动补齐依赖。发布前按校验方法检查并预览;添加后到 市场 > 我的应用与技能 核对实际安装状态。

给自己的服务提供 MCP 工具 ​

选择实现方式 ​

需求交付物接收端还需要做什么
固定的写作、分析、检查方法SKILL 正文及 subject: app 分享包添加方法并提供任务资料
读取业务系统中的实时信息MCP 服务和连接配置连接账号、发现工具并授权员工
复用现有已登记连接无凭据的固定连接资源核对本机支持的服务与工具,再连接
浏览器、电脑或其他宿主能力受支持的固定原生扩展安装、启用及必要系统授权

第一种不需要新建 Node 服务;第二种需要你维护服务端的鉴权、数据权限和可用性。若目标是让业务系统调用 Teloa 员工,使用员工对外接口,不用再开发一个向员工提供工具的服务。

运行一个最小的只读 MCP 服务 ​

以下例子只返回虚构订单,不访问真实系统。创建单独的示例目录,使用 Node.js 24,安装固定版本:

sh
npm init -y
npm install --save-exact @modelcontextprotocol/sdk@1.30.0

下载完整运行示例,解压后已有 app-server.mjs;安装依赖后可直接运行 node app-server.mjs。下面列出同一服务的完整代码。

保存为 server.mjs:

js
import {createServer} from 'node:http'
import {Server} from '@modelcontextprotocol/sdk/server/index.js'
import {StreamableHTTPServerTransport} from '@modelcontextprotocol/sdk/server/streamableHttp.js'
import {ListToolsRequestSchema, CallToolRequestSchema} from '@modelcontextprotocol/sdk/types.js'

const tool = {
  name: 'get_demo_order',
  description: 'Read the single fictional order DEMO-001.',
  inputSchema: {
    type: 'object', properties: {orderId: {type: 'string', enum: ['DEMO-001']}},
    required: ['orderId'], additionalProperties: false,
  },
  annotations: {readOnlyHint: true, destructiveHint: false, openWorldHint: false},
}
createServer(async (req, res) => {
  if (req.method !== 'POST' || req.url !== '/mcp') {
    res.writeHead(405); res.end(); return
  }
  const server = new Server({name: 'demo-orders', version: '1.0.0'}, {capabilities: {tools: {}}})
  server.setRequestHandler(ListToolsRequestSchema, async () => ({tools: [tool]}))
  server.setRequestHandler(CallToolRequestSchema, async ({params}) => {
    const args = params.arguments ?? {}
    if (params.name !== tool.name || args.orderId !== 'DEMO-001' ||
        Object.keys(args).some(k => k !== 'orderId')) {
      return {isError: true, content: [{type: 'text', text: 'Unknown demo order or arguments.'}]}
    }
    return {content: [{type: 'text', text: JSON.stringify({
      orderId: 'DEMO-001', amount: 115, currency: 'CNY', status: 'draft',
    })}]}
  })
  const transport = new StreamableHTTPServerTransport({enableJsonResponse: true})
  res.once('close', () => {void server.close()})
  try {
    await server.connect(transport)
    await transport.handleRequest(req, res)
  } catch {
    if (!res.headersSent) res.writeHead(500)
    res.end()
    await server.close()
  }
}).listen(3277, '127.0.0.1', () => console.log('Demo MCP: http://127.0.0.1:3277/mcp'))

运行 node server.mjs。这个教学服务仅绑定本机回环,没有生产鉴权、请求限流或真实数据访问;不要直接开放到公网。若 3277 已被占用,修改端口并同步下面的 URL。

在 Teloa 中连接并授权 ​

在自定义 MCP 应用入口提供以下连接定义,或按页面填写相同信息:

json
{
  "schema": "teloa.mcp-server/v1",
  "serverName": "demo-orders",
  "title": "Demo orders",
  "transport": "streamable-http",
  "url": "http://127.0.0.1:3277/mcp"
}

先连接并核对真实发现的 get_demo_order,再在测试员工的工具授权中选择该工具。用“读取虚构订单 DEMO-001,报告金额和状态”完成首次调用,结果应为 115 CNY、draft;轨迹应包含真实工具调用与回执,而不是模型根据示例文字猜答。工具在宿主中可能带服务前缀,以发现列表为准,不手工猜测名称。

再请求不存在的 DEMO-002,应收到明确错误,不能返回其他订单。断开服务后应报告连接或执行失败;恢复服务后重新核对连接状态再试。readOnlyHint 仅供客户端理解工具,不替代服务端权限校验,也不会自动授予员工工具权限。

从虚构服务迁移到真实业务系统 ​

保留工具的窄输入与结构化结果,把返回常量替换成有权限检查的只读查询。在服务端完成当前调用身份、租户、订单归属和字段过滤;不要相信模型传入的租户 ID。密钥保存在服务端,日志脱敏;调用外部系统设置超时,并传递取消信号。需要写入时,另建动作明确的工具,校验参数、幂等身份和必要确认,不把只读查询悄悄改成写操作。

远程连接使用 HTTPS。Header 凭据只在可信设置控件填写值;分享中只保留名称与前缀声明。OAuth 使用产品实际支持的连接路径,不能把个人访问令牌当成 OAuth 配置。上线前以服务端拒绝测试确认数据隔离,不能只看员工提示词中的范围说明。

先准备可访问的 Streamable HTTP MCP 服务,再在工作台创建自定义 MCP 应用。远程使用 HTTPS,本机回环可用 HTTP;服务地址由本人提供。连接定义使用 teloa.mcp-server/v1,工具在添加并连接后真实发现,不在模板里编造工具清单。

静态鉴权只声明最多 8 个 Header 名和可选前缀,例如 Authorization / Bearer,不把值写入定义、技能或聊天。本人在可信凭据控件填写值;保存、连接、工具发现和员工授权分别完成。具体入口与 OAuth/静态凭据边界见应用和连接指南。员工调用工具与业务系统通过API/SDK/MCP 调用员工是两个方向。

固定包中的连接与原生扩展 ​

团队或应用分享包可声明 kind: "mcp" 的 teloa.mcp-connection/v1,引用接收端实际支持的 serverName 与工具;也可声明固定 npm 版本的 teloa.plugin/v1。这两者都是依赖声明,不是 MCP 服务地址配置或任意代码安装许可。来源未核实、包名未知时停止补全,不编造示例为真实依赖。

带连接或扩展的分享包声明 compatibility.capabilities: ["connections"]。接收方先检查安装来源、系统要求和权限,再安装/启用、重启(如提示)并连接账号;不得只因显示“已添加”就开始调用。原生插件适配和安装要求见引擎接入边界与原生能力。

测试与分发 ​

对纯方法应用,用虚构输入核对输出;有外部服务时,还需覆盖连接失败、无权限、取消、重试与重复请求。明确区分本地示例预览、实际服务集成和真实模型验证,未连接的服务不能记为通过。按分享方法分发应用;官方目录收录另按固定来源、许可和兼容性审核。

交付时把安装步骤、所需运行时、配置项名称、发现到的工具、输入输出例子、权限要求和卸载方式写进说明。纯方法应用停止使用后可移除本地添加的能力;MCP 应用还应断开连接,并在服务提供方撤销不再使用的凭据。撤销分享链接不能撤销接收者已建立的第三方账号授权。

验证阶段最少证明什么
格式检查分享主体是 app、无员工,固定资源引用完整
安装与预览实际展示的方法、连接和扩展与包内容一致
服务连接工具真实发现、无权限被拒绝、断线有明确错误
员工使用真实模型调用了获准工具,结果能追溯到回执
取消与恢复请求停止不伪造完成,重试不产生重复业务写入
分享与接收新环境用自己的模型和账号配置,未夹带作者凭据