mcpField
M
MCP Server - A Node In Layers Package for building MCP Servers

MCP Server - A Node In Layers Package for building MCP Servers

本地服务
node-in-layers.github.io开发工具023 周前更新

关于 MCP Server - A Node In Layers Package for building MCP Servers

这是用于构建 MCP 服务的 Node In Layers 软件包,可将应用域、功能和模型 CRUD 操作提供给 AI。开发者可配置能力导航、隐藏组件,或使用扁平模式直接暴露功能工具。

主要功能

  1. 01暴露功能和模型 CRUD 工具
  2. 02按领域组织工具
  3. 03可配置 START_HERE 指引
  4. 04扁平模式直接提供功能工具
  5. 05隐藏指定组件
  6. 06注册自定义工具

适用场景

  1. 01向 AI 客户端提供应用功能
  2. 02通过 MCP 提供模型 CRUD 操作
  3. 03借助 START_HERE 减少导航调用
  4. 04限制调用方可访问的组件

MCP 相关

它用于构建 MCP 服务,向 MCP 客户端暴露领域、功能和模型 CRUD 操作。客户端可先发现并查看能力说明,再执行操作;也可注册自定义工具。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

暂未收录安装方式

我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。

代码仓库

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

MCP Server - 用于构建 MCP 服务的 Node In Layers 包

一个用于构建 MCP 服务的 Node In Layers 包。它会将你的领域、功能和模型 CRUD 操作公开为 MCP 工具,供 AI 发现并调用。配套库:@node-in-layers/mcp-client(用于功能、模型和工具的共享协议)。

该系统具有 self-describing 特性,会自动将工具组织成经过优化且高效的系统,从而减少工具总数。它还会自动添加提示词和示例,大幅提升 AI 在系统中选择工具和准确格式化内容的能力,适用于拥有数百乃至数千个工具的系统。

API 文档


使用方法

1. 安装
npm install @node-in-layers/mcp-server
2. 配置
// /config.base.mts
import { CoreNamespace } from '@node-in-layers/core'
import { McpNamespace, HttpConnection } from '@node-in-layers/mcp-server'

export default () => ({
  systemName: 'your-system-name',
  [CoreNamespace.root]: {
    /* 1. Add to the Apps List */
    apps: await Promise.all([
      // Other Very Early Modules
      //import('@node-in-layers/data/index.js'),

      // Insert Here
      import('@node-in-layers/mcp-server/index.js'),

      // Insert Your Domains Here
    ]),
    /* 2. Add mcp layer. NOTE: You must have entries between features and mcp */
    layerOrder: ['services', 'features', ['entries', 'mcp']], // can also be ['entries', 'express', 'mcp']
  },
  /* 3. Add Mcp Server Configurations */
  [McpNamespace]: {
    // Required: The configuration of the server itself.
    server: {
      connection: {
        type: 'http',
        url: 'http://localhost',
        port: 4000,
      } as HttpConnection,
    },
    // Optional arguments go here.
  },
})
3. 现在可用的内容
  1. 功能会自动公开(除非明确隐藏)
  2. 模型 CRUD 操作会自动公开(除非明确隐藏)
  3. 功能现在可以使用 mcp 层,其中包含命名空间 McpNamespace 中的其他能力。(稍后说明)
4. 运行服务

你可以通过以下方式在简单脚本中轻松运行服务:

import { McpNamespace } from '@node-in-layers/mcp-server'
const system: System = (await core.loadSystem<SystemConfig>({
  environment,
})) as any // "System" is your typed System object.
await system.mcp[McpNamespace].start(context)
使用 ./bin/mcp_server.mts 文件的示例(可随意复制粘贴)
#!/usr/bin/env tsx

import esMain from 'es-main'
import { ArgumentParser } from 'argparse'
import * as core from '@node-in-layers/core'
import { McpNamespace } from '@node-in-layers/mcp-server'
import { SystemConfig } from '../src/types.js'
import { System } from '../src/system/types.js'

const _parseArguments = () => {
  const parser = new ArgumentParser({
    description: 'Starts the MCP server.',
  })
  parser.add_argument('environment', {
    help: 'The environment for the service.',
  })
  return parser.parse_args()
}

const startServer = async (environment: string) => {
  const system = (await core.loadSystem<SystemConfig>({
    environment,
  })) as unknown as System
  if (system.config[McpNamespace].server.connection.type === 'http') {
    console.info(
      `Starting MCP server on ${system.config[McpNamespace].server.connection.port}...`
    )
  }
  process.on('SIGINT', async function () {
    await system.services['@node-in-layers/data'].cleanup()
    process.exit()
  })

  await system.mcp[McpNamespace].start(system)
}

if (esMain(import.meta)) {
  const args = _parseArguments()
  startServer(args.environment).catch((error: any) => {
    console.error('Failed to start the server:', error)
    process.exit(1)
  })
}

背景与工作原理

MCP 接口(领域、功能、模型)

MCP 工具界面按领域组织,然后是功能和模型:

  • 领域 — AI 可以列出领域(list_domains),然后针对每个领域列出功能(list_features),并在有模型时列出模型。只有公开了功能或模型的领域才会显示。
  • 功能 — 对于指定的领域/功能,AI 可以获取其架构(describe_feature)并运行它(execute_feature)。
  • 模型 — 对于指定的领域/模型,AI 可以获取其架构,并运行保存、检索、删除、搜索、bulkInsert、bulkDelete 操作。

返回给 AI 的文档(包括 START_HERE 返回的内容)可配置。默认情况下,服务会提供说明,引导 AI:

  1. 列出领域。
  2. 列出某个领域中的功能(和模型)。
  3. 需要架构时,描述功能或模型。
  4. 使用正确的参数执行功能和模型 CRUD 操作。

因此,AI 会通过可配置的“从这里开始”内容和默认系统条目了解系统结构,然后根据需要使用工具进行列出、描述和执行操作。

扁平模式(仅功能工具)

如果你希望工具界面非常精简、重点突出(例如,只有一个函数的系统),可以让 MCP 服务以扁平模式运行。

在扁平模式下,服务会:

  • 将每个功能函数公开为独立的 MCP 工具,名称为 domain_featureName。
  • 不公开 Node-in-Layers 导航工具(START_HERE、list_domains、list_features、describe_feature、execute_feature)。
  • 不公开任何模型 CRUD 工具(list_models、describe_model、save、retrieve、delete、search、bulkInsert、bulkDelete)。
  • 仍会公开你通过 addTool() / addAnnotatedFunction() 明确注册的任何工具。

通过以下方式启用:

// /config.base.mts
import { McpNamespace } from '@node-in-layers/mcp-server'

export default () => ({
  // ...
  [McpNamespace]: {
    mode: 'flat',
    server: { connection: { type: 'cli' } },
  },
})
隐藏组件

你可以限制调用方可见(以及可执行)的内容(例如特定领域、功能或所有模型 CRUD 操作),只公开预期的工具界面。

在 MCP 配置中配置 hideComponents:

  • paths — 要隐藏的点分隔路径,例如 myDomain、myDomain.myFeature、myDomain.cruds、myDomain.cruds.MyModel。
  • domains — 要完全隐藏的领域名称(它们不会出现在 list_domains 中)。
  • allModels — 如果为 true,则不公开任何模型 CRUD 工具。

未隐藏的内容均保持可用。完整结构请参阅配置详情。

示例(部分配置):

// /config.base.mts
import { McpNamespace } from '@node-in-layers/mcp-server'

export default () => ({
  // ...
  [McpNamespace]: {
    // ...
    hideComponents: {
      // Completely hide these domains from the MCP surface
      domains: ['internalAdmin', 'experimental'],

      // Hide specific paths (domains, features, or models)
      paths: [
        'billing.cruds', // hide all models in the billing domain
        'users.cruds.ApiKeys', // hide a single model. (The ApiKeys table located in the users domain)
        'debug.internalFeature', // hide a specific feature
      ],

      // Or hide all models everywhere. Good for "feature" oriented systems.
      allModels: false, // set true to hide all model CRUD tools
    },
  },
})

系统描述

在 systemDescription 下设置系统的静态元数据,这些元数据会包含在起始说明响应中:

  • description — 面向 AI 的简短系统描述。
  • version — 系统版本字符串。

这里适合填写“这个系统是什么”以及版本信息;它不会控制系统中有哪些工具,也不会控制 START_HERE 工具包含哪些内容(这些由 startHere 配置)。

示例(部分配置):

// /config.base.mts
import { McpNamespace } from '@node-in-layers/mcp-server'

export default () => ({
  // ...
  [McpNamespace]: {
    // ...
    systemDescription: {
      description: 'Order management and billing system for ACME Corp.',
      version: '2.3.0',
    },
  },
})

从这里开始

START_HERE 工具让系统变得易于导航:系统会指示 AI 首先调用该工具(或在用户寻求帮助时调用)。其响应由以下内容构成:

  1. 系统元数据 — 配置中的 systemName、systemDescription、systemVersion。
  2. 默认系统条目 — 内置文档(例如“这是一个按领域分层的系统”“MCP 导航工作流”“跨层属性”)。你可以通过 startHere.hideDefaultSystemEntries 关闭这些条目。
  3. 可选:包含领域 / 包含功能 — 如果 startHere.includeDomains 为 true,响应会包含当前领域列表(相当于已调用 list_domains)。如果 startHere.includeFeatures 为 true,还会包含每个领域的功能列表(相当于已为每个领域调用 list_features)。这样一来,AI 无需额外调用工具即可获取领域和 / 或功能。
  4. 使用示例 — 你在 startHere.examplesOfUse 下添加的自定义条目。这里用于记录较高层级的流程(例如“运行功能 A,然后运行 B,最后运行 C”)。内置文档会介绍领域、功能和模型,但不会介绍你的应用专属流程。请将这些流程放在 examplesOfUse 中,并使用仅含少量说明文字的 JSON 对象示例,以便 AI 直接应用。

包含领域 / 包含功能
启用这些选项相当于预先运行 list_domains 和 / 或 list_features,并将结果嵌入 START_HERE。缺点是会增加上下文大小:对于大型系统(工具很多),这会占用大量上下文并引入干扰信息。对于小型系统(约有 1–10 个工具),通常没有问题。对于较大型的系统,建议使用使用示例,并让 AI 在需要时调用 list_domains / list_features。

示例(部分配置):

// /config.base.mts
import { McpNamespace } from '@node-in-layers/mcp-server'

export default () => ({
  // ...
  [McpNamespace]: {
    // ...
    startHere: {
      // Optional: override tool identity
      name: 'START_HERE',
      description:
        'BEFORE YOU DO ANYTHING, call this first to learn how to navigate the system.',

      // What to include in the start-here response
      hideDefaultSystemEntries: false, // do we want the ones that come by default? Usually this is yes.
      includeDomains: true, // Should we go ahead and tell it the domains? Commonly this should be true.
      includeFeatures: false, // Should we tell them all the features on the first go? In most cases this should be FALSE. Unless its a small system with few functions.

      // Higher-level flows through your system
      examplesOfUse: [
        {
          name: 'Create order then fetch it',
          description: 'Typical flow that creates an order and then retrieves it.',
          // Giving ACTUAL examples (json data, + small annotations) works amazingly.
          example: `
```markdown
// 1. Create an order
{ "tool": "execute_feature", "args": { "domain": "orders", "featureName": "createOrder" } }
// 2. Get the order by id (using the id from step 1)
{ "tool": "execute_feature", "args": { "domain": "orders", "featureName": "getOrderById" } }
      `,
      tags: ['orders', 'flow'],
    },
  ],
},

}, })


---

## Extending with custom tools

You can add your own MCP tools via the MCP layer using `addTool`. Use this from a layer that has access to `mcp[McpNamespace]` (e.g. after the MCP layer in the stack).

Example (conceptual):

```typescript
// In a layer that runs after the MCP layer and has context.mcp[McpNamespace]
const mcp = context.mcp[McpNamespace]
mcp.addTool({
  name: 'my_custom_tool',
  description: 'Does something custom',
  inputSchema: { type: 'object', properties: { id: { type: 'string' } }, required: ['id'] },
  outputSchema: { type: 'object' },
  execute: async (input) => ({ result: input.id }),
})

随后,你的工具会与内置的领域 / 功能 / 模型工具一同对外提供。


如何运行服务

  • start — 启动 MCP 服务(监听配置中定义的连接)。
    mcp[McpNamespace].start(systemContext, options?)
  • getApp — 获取 Express 应用(用于 HTTP/SSE),以便将其挂载到你自己的服务中。
    mcp[McpNamespace].getApp(options?)

当 MCP 服务是主进程时,使用 start。当你要与现有 Express 应用组合使用时,使用 getApp(例如将 MCP 应用挂载到某个路径)。


中间件和路由

  • addPreRouteMiddleware(middleware) — 添加在 MCP 路由处理之前运行的 Express 中间件。
  • addCrossLayerPropMiddleware(middleware) — 添加中间件,用于提取请求级数据(例如经过身份验证的 user),并将其传递到跨层属性中,供下游函数使用。
  • addAdditionalRoute(route) — 在同一个应用中注册额外的 Express 路由(例如健康检查或管理路由)。

请在设置期间调用这些方法(例如,在能够访问 mcp[McpNamespace] 的层中),并在启动服务或使用应用之前完成调用。


更改日志记录配置

日志记录在 MCP 配置的 logging 部分中进行配置。你可以控制日志级别,还可以选择为每条请求 / 响应日志添加结构化数据。

  • requestLogLevel / responseLogLevel:覆盖传入请求和传出响应的默认日志级别(info)。
  • requestLogGetData(input):将原始请求输入映射为要记录的额外数据的函数。
  • responseLogGetData(result):将原始工具结果映射为要记录的额外数据的函数。

示例(部分配置):

// /config.base.mts
import { McpNamespace } from '@node-in-layers/mcp-server'

export default () => ({
  // ...
  [McpNamespace]: {
    // ...
    logging: {
      // Adjust verbosity
      requestLogLevel: 'debug',
      responseLogLevel: 'info',

      // Attach additional request information to the log.
      requestLogGetData: (input: Request) => ({
        something: input.something,
      }),
      responseLogGetData: (input: Request) => ({
        // Shape this to your needs; example:
        truncated: true,
      }),
    },
  },
})

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。