Skip to main content
Glama
Mistizz

Japanese Text Analyzer

count_clipboard_words

Count words from clipboard text, using space separation for English and morphological analysis for Japanese. Supports language-specific word counting accuracy.

Instructions

テキストの単語数を計測します。英語ではスペースで区切られた単語をカウントし、日本語では形態素解析を使用します。

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
languageNoテキストの言語 (en: 英語, ja: 日本語)en
textYes単語数をカウントするテキスト

Implementation Reference

  • Core handler function implementing word count logic: splits by spaces for English, uses kuromoji tokenizer for Japanese (excluding symbols and spaces), returns count and token details.
    private async countTextWordsImpl(text: string, language: 'en' | 'ja' = 'en', sourceName: string = 'テキスト') {
      try {
        let wordCount = 0;
        let resultText = '';
        
        if (language === 'en') {
          // 英語の場合、単語はスペースで区切られているためsplitで分割
          const words = text.trim().split(/\s+/);
          wordCount = words.length;
          resultText = `${sourceName}の単語数: ${wordCount}単語 (英語モード)`;
        } else if (language === 'ja') {
          // 日本語の場合、kuromojiを使用して形態素解析
          // 形態素解析器が利用可能かを確認
          let tokenizer;
          
          try {
            tokenizer = await initializeTokenizer();
          } catch (error) {
            return {
              content: [{ 
                type: 'text' as const, 
                text: '形態素解析器の初期化に失敗しました。しばらく待ってから再試行してください。'
              }],
              isError: true
            };
          }
          
          // 形態素解析を実行
          const tokens = tokenizer.tokenize(text);
          
          // 記号と空白以外のすべての単語をカウント(助詞や助動詞も含める)
          const meaningfulTokens = tokens.filter((token: any) => {
            // 記号と空白のみを除外
            return !(token.pos === '記号' || token.pos === '空白');
          });
          
          wordCount = meaningfulTokens.length;
          
          // 単語の詳細情報を出力
          const tokenDetails = tokens.map((token: any) => {
            return `【${token.surface_form}】 品詞: ${token.pos}, 品詞細分類: ${token.pos_detail_1}, 読み: ${token.reading}`;
          }).join('\n');
          
          resultText = `${sourceName}の単語数: ${wordCount}単語 (日本語モード、すべての品詞を含む)\n\n分析結果:\n${tokenDetails}\n\n有効な単語としてカウントしたもの:\n${meaningfulTokens.map((t: any) => t.surface_form).join(', ')}`;
        }
        
        return {
          content: [{ 
            type: 'text' as const, 
            text: resultText
          }]
        };
      } catch (error: any) {
        return {
          content: [{ 
            type: 'text' as const, 
            text: `エラーが発生しました: ${error.message}`
          }],
          isError: true
        };
      }
    }
  • src/index.ts:529-537 (registration)
    Tool registration via McpServer.tool: defines name, description, Zod input schema (text and optional language), and async handler delegating to countTextWordsImpl.
    this.server.tool(
      'count_clipboard_words', 
      'テキストの単語数を計測します。英語ではスペースで区切られた単語をカウントし、日本語では形態素解析を使用します。',
      { 
        text: z.string().describe('単語数をカウントするテキスト'),
        language: z.enum(['en', 'ja']).default('en').describe('テキストの言語 (en: 英語, ja: 日本語)')
      },
      async ({ text, language }) => await this.countTextWordsImpl(text, language)
    );
  • Zod schema for tool inputs: text (string), language (enum 'en'|'ja', default 'en').
    { 
      text: z.string().describe('単語数をカウントするテキスト'),
      language: z.enum(['en', 'ja']).default('en').describe('テキストの言語 (en: 英語, ja: 日本語)')
    },
  • Helper function to lazily initialize the kuromoji tokenizer used in Japanese word counting.
    async function initializeTokenizer() {
      // すでに初期化されている場合
      if (tokenizerInstance) {
        return tokenizerInstance;
      }
      
      // 初期化中の場合は既存のPromiseを返す
      if (initializingPromise) {
        return initializingPromise;
      }
      
      console.error('形態素解析器の初期化を開始...');
      
      // 辞書パスを取得
      const dicPath = findDictionaryPath();
      console.error(`使用する辞書パス: ${dicPath}`);
      
      // 初期化処理をPromiseでラップ
      initializingPromise = new Promise((resolve, reject) => {
        try {
          kuromoji.builder({ dicPath }).build((err, tokenizer) => {
            if (err) {
              console.error(`形態素解析器の初期化エラー: ${err.message || err}`);
              initializationError = err;
              initializingPromise = null; // リセットして再試行できるようにする
              tokenizerReady = false;
              reject(err);
              return;
            }
            
            console.error('形態素解析器の初期化が完了しました');
            tokenizerInstance = tokenizer;
            tokenizerReady = true;
            resolve(tokenizer);
          });
        } catch (error) {
          console.error(`形態素解析器の初期化中に例外が発生: ${error.message || error}`);
          initializationError = error;
          initializingPromise = null; // リセットして再試行できるようにする
          tokenizerReady = false;
          reject(error);
        }
      });
      
      return initializingPromise;
    }
Install Server

Other Tools

Related Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Mistizz/mcp-JapaneseTextAnalyzer'

If you have feedback or need assistance with the MCP directory API, please join our Discord server