Skip to main content
Glama
kimagure-dd

@kimagure-dd/xirr-mcp

by kimagure-dd

parse_rakuten_csv

Parse a Rakuten Securities transaction CSV to extract cash flows, automatically handling buy/sell transactions. Output is ready for XIRR calculation.

Instructions

Parse a Rakuten Securities transaction CSV (取引履歴) and convert it into a normalized cash flow list. Handles 買付/売却 transaction types automatically. The output can be fed directly into calculate_xirr.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
csvContentYesRaw CSV text exported from Rakuten Securities. Note: Rakuten exports are typically Shift_JIS encoded; decode to UTF-8 before passing.

Implementation Reference

  • Handler function for parse_rakuten_csv that validates input via Zod schema, calls mapRakutenCsv to parse the CSV, and returns the result as JSON.
    function handleParseRakutenCsv(args: unknown): string {
      const parsed = ParseRakutenCsvInputSchema.parse(args);
      const result = mapRakutenCsv(parsed.csvContent);
    
      if (!result.ok) {
        return JSON.stringify(
          {
            ok: false,
            error: result.error,
          },
          null,
          2,
        );
      }
    
      const totalAmount = result.rows.reduce((sum, r) => sum + r.amount, 0);
    
      return JSON.stringify(
        {
          ok: true,
          rowCount: result.rows.length,
          totalAmount,
          cashFlows: result.rows.map((r) => ({
            date: r.date,
            amount: r.amount,
            transactionType: r.transactionType,
            fundName: r.fundName,
          })),
          warnings: result.warnings,
        },
        null,
        2,
      );
    }
  • src/index.ts:177-192 (registration)
    Tool registration in ListToolsRequestSchema handler with name 'parse_rakuten_csv', description, and inputSchema (csvContent string).
    {
      name: 'parse_rakuten_csv',
      description:
        'Parse a Rakuten Securities transaction CSV (取引履歴) and convert it into a normalized cash flow list. Handles 買付/売却 transaction types automatically. The output can be fed directly into calculate_xirr.',
      inputSchema: {
        type: 'object',
        properties: {
          csvContent: {
            type: 'string',
            description:
              'Raw CSV text exported from Rakuten Securities. Note: Rakuten exports are typically Shift_JIS encoded; decode to UTF-8 before passing.',
          },
        },
        required: ['csvContent'],
      },
    },
  • src/index.ts:205-207 (registration)
    Switch-case dispatch mapping the tool name 'parse_rakuten_csv' to the handler function handleParseRakutenCsv.
    case 'parse_rakuten_csv':
      text = handleParseRakutenCsv(args);
      break;
  • Zod input validation schema for parse_rakuten_csv requiring a non-empty csvContent string.
    const ParseRakutenCsvInputSchema = z.object({
      csvContent: z
        .string()
        .min(1, 'csvContent must not be empty')
        .describe(
          'Raw CSV text exported from Rakuten Securities. Headers must include 約定日, 取引, ファンド名, 受渡金額/(ポイント利用)[円].',
        ),
    });
  • Core CSV parsing logic for Rakuten Securities CSV. Validates headers, normalizes dates, parses amounts, and converts buy/sell transactions to signed cash flows.
    export function mapRakutenCsv(csvText: string): MapResult {
      const parsed = parseCsv(csvText);
      if (!parsed.ok) {
        return { ok: false, error: parsed.error };
      }
    
      const { headers, rows: dataRows } = parsed;
    
      const indices: Record<string, number> = {};
      for (const name of REQUIRED_HEADERS) {
        const idx = findColumnIndex(headers, name);
        if (idx === -1) {
          return {
            ok: false,
            error: `必要なカラム「${name}」が見つかりません`,
          };
        }
        indices[name] = idx;
      }
    
      const results: RakutenCsvRow[] = [];
      const warnings: string[] = [];
    
      for (let i = 0; i < dataRows.length; i++) {
        const row = dataRows[i];
        const rawDate = row[indices['約定日']] ?? '';
        const rawTransaction = row[indices['取引']] ?? '';
        const rawFundName = row[indices['ファンド名']] ?? '';
        const rawAmount = row[indices['受渡金額/(ポイント利用)[円]']] ?? '';
    
        const date = normalizeDate(rawDate);
        if (!date) {
          warnings.push(`${i + 2}行目: 日付「${rawDate}」を解析できません`);
          continue;
        }
    
        const amount = parseAmount(rawAmount);
        if (amount === null) {
          warnings.push(`${i + 2}行目: 金額「${rawAmount}」を解析できません`);
          continue;
        }
    
        const isBuy = rawTransaction === '買付';
        results.push({
          date,
          amount: isBuy ? amount : -amount,
          transactionType: rawTransaction,
          fundName: rawFundName,
        });
      }
    
      if (results.length === 0) {
        return { ok: false, error: '有効な取引データがありません' };
      }
    
      return { ok: true, rows: results, warnings };
    }
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It discloses the automatic handling of transaction types and encoding issues, but lacks details on error behavior, file size limits, or other edge cases. It is partially transparent but leaves gaps.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences that are efficiently front-loaded. The first sentence states the core purpose, the second adds key details. Every sentence is meaningful with no superfluous words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the simple tool (1 param, no output schema), the description covers input format, handling, and integration with calculate_xirr. It could mention the output structure more explicitly, but it is sufficient for an agent to understand usage.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has 100% coverage with a single parameter. The description adds value by explaining the parameter is raw CSV text and specifically notes the Shift_JIS encoding issue, which is critical for correct usage. This exceeds the baseline of 3 for high schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool parses Rakuten Securities transaction CSV and converts to normalized cash flow list, handling specific transaction types. It implicitly distinguishes from the sibling tool calculate_xirr by indicating the output feeds into it.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description says when to use the tool (when you have a Rakuten Securities CSV) and hints at the workflow with calculate_xirr. It provides encoding context but doesn't explicitly state when not to use it or list alternatives, though the sibling count is low.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other 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/kimagure-dd/xirr-mcp'

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