mcpField
E
easy-mcp

easy-mcp

ローカル
github.com/zcaceres開発ツール19792 週間前に更新

easy-mcp について

easy-mcp は、プロトコルの仕組みや定型コードを隠す簡潔な宣言で MCP サーバーを作成する TypeScript フレームワークです。MCP サーバーを素早く構築したい開発者向けで、引数の型を推論する実験的なデコレーター API を備えています。現在はベータ版です。

主な機能

  1. 01Express に似た簡潔な API
  2. 02引数を推論する実験的なデコレーター API
  3. 03ログ出力と進捗報告のコンテキストオブジェクト
  4. 04TypeScript による型安全性

活用シーン

  1. 01ツールとリソースを備えた MCP サーバーの迅速な構築
  2. 02入力スキーマを手書きせずにツールを定義
  3. 03MCP サーバーのリソーステンプレートとルートの宣言

MCP 対応

easy-mcp は MCP サーバーを作成するためのフレームワークで、ツール、プロンプト、リソース、リソーステンプレート、ルートを定義して MCP クライアントに公開します。

設定

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

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

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

リポジトリ

ツール

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

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

詳細

easy-mcp

easyMCP ロゴ

EasyMCP は利用できますが、ベータ版です。問題が発生した場合はご報告ください。

EasyMCP は、TypeScript で Model Context Protocol(MCP)サーバーを作成する最も簡単な方法です。

配線、フォーマット、その他の定型的な定義を、シンプルな宣言の背後に隠します。

EasyMCP では、使い始めるために必要な最小限の定義だけを記述できます。また、より複雑なリソース、テンプレート、ツール、プロンプトを定義することもできます。

特長

  • Express のようにシンプルな API:EasyMCP は、高水準で直感的な API を提供します。ExpressJS でエンドポイントを定義するのと同様の呼び出しで、ツール、プロンプト、リソース、リソーステンプレート、ルートを定義できます。省略可能なパラメーターはすべて省略でき、必要になるまで表示されません。
  • 実験的なデコレーター API:ツール、プロンプト、リソースの引数を自動的に推論します。入力スキーマの定義は不要です。
  • コンテキストオブジェクト:ツール内でコンテキストオブジェクトを通じて、ログ記録や進捗報告などの MCP 機能にアクセスできます。
  • 優れた型安全性:開発者体験が向上し、実行時エラーが減少します。

ベータ版の制限事項

  • MCP サンプリングにはまだ対応していません
  • SSE にはまだ対応していません
  • リソース更新通知にはまだ対応していません
  • プロンプトは技術的には入力を受け付けますが、Typescript SDK では入力を受け付けないとされています。そのため、この機能は未完成に感じられます。

インストール

EasyMCP をインストールするには、プロジェクトディレクトリで次のコマンドを実行します。

bun install

(実験的)デコレーター API を使ったクイックスタート

examples/express-decorators.ts も参照するか、bun start:decorators を実行してください。

EasyMCP のデコレーター API は非常にシンプルで、型と入力設定を自動的に推論します。

ただし、実験的な機能であり、変更されたり、まだ発見されていない問題があったりする可能性があります。

import EasyMCP from "./lib/EasyMCP";
import { Tool, Resource, Prompt } from "./lib/experimental/decorators";

class MyMCP extends EasyMCP {

  @Resource("greeting/{name}")
  getGreeting(name: string) {
    return `Hello, ${name}!`;
  }

  @Prompt()
  greetingPrompt(name: string) {
    return `Generate a greeting for ${name}.`;
  }

  @Tool()
  greet(name: string, optionalContextFromServer: Context) {
    optionalContextFromServer.info(`Greeting ${name}`);
    return `Hello, ${name}!`;
  }
}

const mcp = new MyMCP({ version: "1.0.0" });

デコレーター API を使った複雑な例

examples/express-express.ts を参照するか、bun start:express を実行してください。

import EasyMCP from "./lib/EasyMCP";
import { Prompt } from "./lib/decorators/Prompt";
import { Resource } from "./lib/decorators/Resource";
import { Root } from "./lib/decorators/Root";
import { Tool } from "./lib/decorators/Tool";

@Root("/my-sample-dir/photos")
@Root("/my-root-dir", { name: "My laptop's root directory" }) // Optionally you can name the root
class ZachsMCP extends EasyMCP {
  /**
  You can declare a Tool with zero configuration. Relevant types and plumbing will be inferred and handled.

  By default, the name of the Tool will be the name of the method.
  */
  @Tool()
  simpleFunc(nickname: string, height: number) {
    return `${nickname} of ${height} height`;
  }

  /**
   * You can enhance a tool with optional data like a description.

   Due to limitations in Typescript, if you want the Tool to serialize certain inputs as optional to the Client, you need to provide an optionals list.
   */
  @Tool({
    description: "An optional description",
    optionals: ["active", "items", "age"],
  })
  middleFunc(name: string, active?: string, items?: string[], age?: number) {
    return `exampleFunc called: name ${name}, active ${active}, items ${items}, age ${age}`;
  }

  /**
   * You can also provide a schema for the input arguments of a tool, if you want full control.
   */
  @Tool({
    description: "A function with various parameter types",
    parameters: [
      {
        name: "date",
        type: "string",
        optional: false,
      },
      {
        name: "season",
        type: "string",
        optional: false,
      },
      {
        name: "year",
        type: "number",
        optional: true,
      },
    ],
  })
  complexTool(date: string, season: string, year?: number) {
    return `complexTool called: date ${date}, season ${season}, year ${year}`;
  }

  /**
  * Tools can use a context object to access MCP capabilities like logging, progress reporting, and meta data from the request
  */
  @Tool({
    description: "A tool that uses context",
  })
  async processData(dataSource: string, context: Context) {
    context.info(`Starting to process data from ${dataSource}`);

    try {
      const data = await context.readResource(dataSource);
      context.debug("Data loaded");

      for (let i = 0; i < 5; i++) {
        await new Promise((resolve) => setTimeout(resolve, 1000));
        await context.reportProgress(i * 20, 100);
        context.info(`Processing step ${i + 1} complete`);
      }

      return `Processed ${data.length} bytes of data from ${dataSource}`;
    } catch (error) {
      context.error(`Error processing data: ${(error as Error).message}`);
      throw error;
    }
  }

  /**
   * Resources can be declared with a simple URI.

   By default, the name of the resource will be the name of the method.
   */
  @Resource("simple-resource")
  simpleResource() {
    return "Hello, world!";
  }

  /**
   * Or include handlebars which EasyMCP will treat as a Resource Template.

   Both Resources and Resource Templates can be configured with optional data like a description.
   */
  @Resource("greeting/{name}")
  myResourceTemplate(name: string) {
    return `Hello, ${name}!`;
  }

  /**
   * By default, prompts need no configuration.

   They will be named after the method they decorate.
   */
  @Prompt()
  simplePrompt(name: string) {
    return `Prompting... ${name}`;
  }

  /**
   * Or you can override and configure a Prompt with a name, description, and explicit arguments.
   */
  @Prompt({
    name: "configured-prompt",
    description: "A prompt with a name and description",
    args: [
      {
        name: "name",
        description: "The name of the thing to prompt",
        required: true,
      },
    ],
  })
  configuredPrompt(name: string) {
    return `Prompting... ${name}`;
  }
}

const mcp = new ZachsMCP({ version: "1.0.0" });
console.log(mcp.name, "is now serving!");

Express のような API を使ったクイックスタート

examples/example-minimal.ts も参照するか、bun start:express を実行してください。

この API はより詳細な記述が必要で、魔法のような動作も少ない一方、より安定しており、テストも充実しています。

import EasyMCP from "easy-mcp";

const mcp = EasyMCP.create("my-mcp-server", {
  version: "0.1.0",
});

// Define a resource
mcp.resource({
  uri: "dir://desktop",
  name: "Desktop Directory", // Optional
  description: "Lists files on the desktop", // Optional
  mimeType: "text/plain", // Optional
  fn: async () => {
    return "file://desktop/file1.txt\nfile://desktop/file2.txt";
  },
});

// Define a resource template
mcp.template({
  uriTemplate: "file://{filename}",
  name: "File Template", // Optional
  description: "Template for accessing files", // Optional
  mimeType: "text/plain", // Optional
  fn: async ({ filename }) => {
    return `Contents of ${filename}`;
  },
});

// Define a tool
mcp.tool({
  name: "greet",
  description: "Greets a person", // Optional
  inputs: [ // Optional
    {
      name: "name",
      type: "string",
      description: "The name to greet",
      required: true,
    },
  ],
  fn: async ({ name }) => {
    return `Hello, ${name}!`;
  },
});

// Define a prompt
mcp.prompt({
  name: "introduction",
  description: "Generates an introduction", // Optional
  args: [ // Optional
    {
      name: "name",
      type: "string",
      description: "Your name",
      required: true,
    },
  ],
  fn: async ({ name }) => {
    return `Hi there! My name is ${name}. It's nice to meet you!`;
  },
});

// Start the server
mcp.serve().catch(console.error);

Express のような API

EasyMCP.create(name: string, options: ServerOptions)

新しい EasyMCP インスタンスを作成します。

  • name:MCP サーバーの名前です。
  • options:バージョンなどのサーバーオプションです。
mcp.resource(config: ResourceConfig)

リソースを定義します。

mcp.template(config: ResourceTemplateConfig)

リソーステンプレートを定義します。

mcp.tool(config: ToolConfig)

ツールを定義します。

mcp.prompt(config: PromptConfig)

プロンプトを定義します。

mcp.root(config: Root)

ルートを定義します。

mcp.serve()

MCP サーバーを起動します。

(実験的)デコレーター API

EasyMCP では、MCP サーバーのコンポーネントをより簡潔かつ宣言的に定義するためのデコレーターを提供しています。利用可能なデコレーターの概要を以下に示します。

@Tool(config?: ToolConfig)

メソッドをツールとして定義します。メソッドに宣言した引数を受け取り、TS の型注釈に基づいて型と入力設定を推論します。MCP 機能にアクセスするため、最後の引数として省略可能な context 引数を追加できます。

  • config:ツールの省略可能な設定オブジェクトです。
    • description:ツールの省略可能な説明です。
    • optionals:省略可能として指定するパラメーター名の省略可能な配列です。
    • parameters:入力スキーマを完全に制御するための、パラメーター定義の省略可能な配列です。

例:

@Tool({
  description: "Greets a person",
  optionals: ["title"],
})
greet(name: string, title?: string, optionalContext: Context) {
  return `Hello, ${title ? title + " " : ""}${name}!`;
}
@Resource(uri: string, config?: Partial<ResourceDefinition>)

メソッドをリソースまたはリソーステンプレートとして定義します。リソーステンプレートは、URI で Handlebars を使用して定義します。

  • uri:リソースの URI または URI テンプレートです。
  • config:リソースの省略可能な設定オブジェクトです。
    • name:リソースの省略可能な名前です。
    • description:リソースの省略可能な説明です。
    • mimeType:リソースの省略可能な MIME タイプです。

例:

@Resource("greeting/{name}")
getGreeting(name: string) {
  return `Hello, ${name}!`;
}
@Prompt(config?: PromptDefinition)

メソッドをプロンプトとして定義します。

  • config:プロンプトの省略可能な設定オブジェクトです。
    • name:プロンプトの省略可能な名前です(デフォルトはメソッド名です)。
    • description:プロンプトの省略可能な説明です。
    • args:引数定義の省略可能な配列です。

例:

@Prompt({
  description: "Generates a greeting prompt",
  args: [
    { name: "name", description: "Name to greet", required: true },
  ],
})
greetingPrompt(name: string) {
  return `Generate a friendly greeting for ${name}.`;
}
@Root(uri: string, config?: { name?: string })

MCP サーバーのルートディレクトリを定義します。このデコレーターはメソッドではなく、クラスに適用します。

  • uri:ルートディレクトリの URI です。
  • config:省略可能な設定オブジェクトです。
    • name:ルートの省略可能な名前です。

例:

@Root("/my-sample-dir/photos")
@Root("/my-root-dir", { name: "My laptop's root directory" })
class MyMCP extends EasyMCP {
  // ...
}

デコレーターを使用すると、EasyMCP がツール、リソース、プロンプト、ルートの型を自動的に推論し、適切な設定を作成します。これにより、ボイラープレートコードを大幅に削減し、MCP サーバーの定義をより簡潔にできます。

ただし、デコレーター API は実験的なものであり、バグや予期しない変更が発生する可能性があります。

貢献

貢献を歓迎します!PR を送信してください。

ライセンス

このプロジェクトは MIT ライセンスの下でライセンスされています。

クレジット

EasyMCP は Zach Caceres によって作成されましたが、Python MCP サーバー用ライブラリである FastMCP by kjlowin に着想を得ています。

コメント

MCP は初めてですか?

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

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