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 について

Node In Layers を使って MCP サーバーを構築し、アプリケーションのドメイン、機能、モデル CRUD 操作を AI に公開するパッケージです。開発者はナビゲーション情報を設定し、コンポーネントを非表示にしたり、フラットモードを利用したりできます。

主な機能

  1. 01機能とモデル CRUD ツールの公開
  2. 02ドメイン別のツール整理
  3. 03START_HERE の案内設定
  4. 04機能ツールを直接公開するフラットモード
  5. 05指定コンポーネントの非表示
  6. 06カスタムツールの登録

活用シーン

  1. 01AI クライアントへのアプリ機能公開
  2. 02MCP 経由のモデル CRUD 操作
  3. 03START_HERE によるナビゲーション呼び出しの削減
  4. 04呼び出し元が使えるコンポーネントの制限

MCP 対応

MCP サーバーを構築し、ドメイン、機能、モデル CRUD 操作を MCP クライアントに公開します。クライアントは実行前に機能を探してスキーマを確認でき、カスタムツールも登録できます。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

インストール方法は未掲載です

このサーバーのパッケージやリモートエンドポイントはまだ取得できていません。プロジェクトの README の手順に従ってください。

リポジトリ

ツール

ツール一覧はまだ取得されていません

ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。

詳細

MCP サーバー - 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 はスキーマを取得し、save、retrieve、delete、search、bulkInsert、bulkDelete を実行できます。

AI に返されるドキュメント(START_HERE が返す内容を含む)は設定可能です。デフォルトでは、サーバーは AI が次の操作を行うための手順を提供します。

  1. ドメインを一覧表示します。
  2. ドメイン内の機能(およびモデル)を一覧表示します。
  3. スキーマが必要なときに、機能またはモデルの詳細を取得します。
  4. 適切な引数を指定して、機能とモデルの CRUD 操作を実行します。

このように、AI は設定可能な「start here」とデフォルトのシステムエントリーからシステムの構成を学び、必要に応じてツールを使って一覧表示、詳細取得、実行を行います。

フラットモード(機能ツールのみ)

非常に小さく、目立つツールインターフェイス(たとえば、関数が1つだけのシステム)が必要な場合は、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 に、AI がそのまま適用できるよう、説明文を最小限にしたJSON オブジェクトの例として記述します。

ドメインを含める/機能を含める
これらを有効にすることは、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 アプリと組み合わせる場合(例:MCP アプリを特定のパスにマウントする場合)は getApp を使います。


ミドルウェアとルート

  • 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,
      }),
    },
  },
})

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。