├── .editorconfig ├── .github ├── ISSUE_TEMPLATE.md ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── feature_request.md │ └── question.md ├── release.yml ├── scripts │ ├── check-eol-newrelease.cjs │ └── update-version.mjs └── workflows │ ├── check-eol-newrelease.yml │ ├── close-issue.yml │ ├── create-draft-release.yml │ ├── label-issue.yml │ ├── release.yml │ └── test.yml ├── .gitignore ├── .prettierrc.json ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSE ├── README.ja.md ├── README.md ├── assets ├── demo.ja.png └── demo.png ├── package-lock.json ├── package.json ├── renovate.json5 ├── src ├── index.ts └── version.ts └── tsconfig.json /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Do this before creating an issue 2 | 3 | - Check our [developer documentation](https://developers.line.biz/en/docs/) and 4 | [FAQ](https://developers.line.biz/en/faq/) page for more 5 | information on LINE bots and the Messaging API 6 | - Make sure your issue is **related to** the line-bot-mcp-server. 7 | - Note that we don't provide technical support 8 | 9 | ## When creating an issue 10 | 11 | - Provide detailed information about the issue you had with this MCP Server 12 | - Provide logs if possible 13 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug Report Template 3 | about: Use this template to report bugs in the line-bot-mcp-server 4 | title: 'Bug Report' 5 | --- 6 | 7 | ## Bug Report 8 | 15 | 16 | ## System Information 17 | - OS: [e.g. Ubuntu] 18 | - Node.js Version [e.g. Node 22] 19 | - line-bot-mcp-server version(s) [e.g. 0.0.1] 20 | - AI Agent you use [e.g. Claude for Desktop] 21 | 22 | ## Expected Behavior 23 | 24 | 25 | ## Current Behavior 26 | 27 | 28 | ## Steps to Reproduce 29 | 31 | 1. 32 | 2. 33 | 3. 34 | 35 | ## Logs 36 | 37 | 38 | ## Additional Context (Optional) 39 | 41 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: "Feature Request" 5 | --- 6 | 7 | ## Feature Request 8 | **Is your feature request related to a problem? Please describe.** 9 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 10 | 11 | **Describe the solution you'd like** 12 | A clear and concise description of what you want to happen. 13 | 14 | **Describe alternatives you've considered** 15 | A clear and concise description of any alternative solutions or features you've considered. 16 | 17 | **Additional context** 18 | Add any other context or screenshots about the feature request here. 19 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Question Template" 3 | about: "Use this template to ask questions about usage or implementation of the line-bot-mcp-server." 4 | title: "Question" 5 | --- 6 | 7 | 18 | 19 | ## Have You Checked the Following? 20 | - [ ] [Developer Documentation - LINE Developers](https://developers.line.biz/en/docs/) 21 | - [ ] [FAQ - LINE Developers](https://developers.line.biz/en/faq/tags/messaging-api/) 22 | 23 | ## Summary of Your Question 24 | 25 | 26 | ## Details 27 | 28 | 29 | ## What You've Tried 30 | 32 | 33 | ## Your Environment 34 | 40 | 41 | ## Additional Context (Optional) 42 | 43 | -------------------------------------------------------------------------------- /.github/release.yml: -------------------------------------------------------------------------------- 1 | # https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes 2 | changelog: 3 | categories: 4 | - title: Breaking Changes 5 | labels: 6 | - breaking-change 7 | - title: line-openapi updates 8 | labels: 9 | - line-openapi-update 10 | - title: New Features 11 | labels: 12 | - new-features 13 | - title: Bug fix 14 | labels: 15 | - bug-fix 16 | - title: Dependency updates 17 | labels: 18 | - dependency upgrade 19 | exclude: 20 | labels: 21 | - line-openapi-update 22 | - title: Other Changes 23 | labels: 24 | - "*" 25 | -------------------------------------------------------------------------------- /.github/scripts/check-eol-newrelease.cjs: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | 3 | /** 4 | * @typedef {object} ReleaseCycle 5 | * @property {string|number} cycle - Release cycle (e.g. "1.20", 8.1, etc.) 6 | * @property {string} [releaseDate] - YYYY-MM-DD string for the first release in this cycle 7 | * @property {string|boolean} [eol] - End of Life date (YYYY-MM-DD) or false if not EoL 8 | * @property {string} [latest] - Latest release in this cycle 9 | * @property {string|null} [link] - Link to changelog or similar, if available 10 | * @property {boolean|string} [lts] - Whether this cycle is non-LTS (false), or LTS starting on a given date 11 | * @property {string|boolean} [support] - Active support date (YYYY-MM-DD) or boolean 12 | * @property {string|boolean} [discontinued] - Discontinued date (YYYY-MM-DD) or boolean 13 | */ 14 | 15 | /** 16 | * @typedef {object} EolNewReleaseConfig 17 | * @property {string} languageName 18 | * @property {string} eolJsonUrl 19 | * @property {string} eolViewUrl 20 | * @property {number} eolLookbackDays 21 | * @property {number} newReleaseThresholdDays 22 | * @property {boolean} ltsOnly 23 | * @property {number} retryCount 24 | * @property {number} retryIntervalSec 25 | */ 26 | 27 | /** 28 | * This script checks EoL and new releases from endoflife.date JSON. 29 | * It creates Issues for: 30 | * - EoL reached within eolLookbackDays 31 | * - New releases within newReleaseThresholdDays 32 | * If fetching fails after multiple retries, an error Issue is created once per week. 33 | * 34 | * Note this script is used in a GitHub Action workflow, and some line/line-bot-* repositories. 35 | * If you modify this script, please consider syncing the changes to other repositories. 36 | * 37 | * @param {import('@actions/github-script').AsyncFunctionArguments} actionCtx 38 | * @param {EolNewReleaseConfig} config 39 | */ 40 | module.exports = async function checkEolAndNewReleases(actionCtx, config) { 41 | const { github, context, core } = actionCtx; 42 | const { 43 | languageName, 44 | eolJsonUrl, 45 | eolViewUrl, 46 | eolLookbackDays, 47 | newReleaseThresholdDays, 48 | ltsOnly, 49 | retryCount, 50 | retryIntervalSec, 51 | } = config; 52 | 53 | /** 54 | * Returns a simple "year-week" string like "2025-W09". 55 | * This is a rough calculation (not strictly ISO-8601). 56 | * @param {Date} date 57 | * @returns {string} 58 | */ 59 | const getYearWeek = (date) => { 60 | const startOfYear = new Date(date.getFullYear(), 0, 1); 61 | const dayOfYear = Math.floor((date - startOfYear) / 86400000) + 1; 62 | const weekNum = Math.ceil(dayOfYear / 7); 63 | return `${date.getFullYear()}-W${String(weekNum).padStart(2, '0')}`; 64 | }; 65 | 66 | /** 67 | * Simple dedent function. 68 | * Removes common leading indentation based on the minimum indent across all lines. 69 | * Also trims empty lines at the start/end. 70 | * @param {string} str 71 | * @returns {string} 72 | */ 73 | const dedent = (str) => { 74 | const lines = str.split('\n'); 75 | while (lines.length && lines[0].trim() === '') lines.shift(); 76 | while (lines.length && lines[lines.length - 1].trim() === '') lines.pop(); 77 | 78 | /** @type {number[]} */ 79 | const indents = lines 80 | .filter(line => line.trim() !== '') 81 | .map(line => (line.match(/^(\s+)/)?.[1].length) ?? 0); 82 | 83 | const minIndent = indents.length > 0 ? Math.min(...indents) : 0; 84 | return lines.map(line => line.slice(minIndent)).join('\n'); 85 | }; 86 | 87 | /** 88 | * Creates an Issue if an Issue with the same title does not exist (state=all). 89 | * @param {string} title 90 | * @param {string} body 91 | * @param {string[]} [labels] 92 | * @returns {Promise} true if created, false if an Issue with same title already exists 93 | */ 94 | const createIssueIfNotExists = async (title, body, labels = []) => { 95 | const issues = await github.rest.issues.listForRepo({ 96 | owner: context.repo.owner, 97 | repo: context.repo.repo, 98 | state: 'all', 99 | per_page: 100, 100 | }); 101 | const found = issues.data.find(i => i.title === title); 102 | if (found) { 103 | core.info(`Issue already exists: "${title}"`); 104 | return false; 105 | } 106 | await github.rest.issues.create({ 107 | owner: context.repo.owner, 108 | repo: context.repo.repo, 109 | title, 110 | body, 111 | labels, 112 | }); 113 | core.notice(`Created Issue: "${title}"`); 114 | return true; 115 | }; 116 | 117 | /** 118 | * Fetch with retry, returning an array of ReleaseCycle objects. 119 | * @param {string} url 120 | * @returns {Promise} 121 | */ 122 | const fetchWithRetry = async (url) => { 123 | let lastErr = null; 124 | for (let i = 1; i <= retryCount; i++) { 125 | try { 126 | const response = await fetch(url); 127 | if (!response.ok) { 128 | throw new Error(`HTTP ${response.status} ${response.statusText}`); 129 | } 130 | /** @type {ReleaseCycle[]} */ 131 | const jsonData = await response.json(); 132 | return jsonData; 133 | } catch (err) { 134 | lastErr = err; 135 | core.warning(`Fetch failed (attempt ${i}/${retryCount}): ${err.message}`); 136 | if (i < retryCount) { 137 | await new Promise(r => setTimeout(r, retryIntervalSec * 1000)); 138 | } 139 | } 140 | } 141 | throw new Error(`Failed to fetch after ${retryCount} attempts: ${lastErr?.message}`); 142 | }; 143 | 144 | /** 145 | * Check EoL for a single release. 146 | * @param {ReleaseCycle} release 147 | * @param {Date} now 148 | * @param {Date} eolLookbackDate 149 | */ 150 | const checkEoL = async (release, now, eolLookbackDate) => { 151 | if (ltsOnly && release.lts === false) { 152 | core.info(`Skipping non-LTS release: ${release.cycle}`); 153 | return; 154 | } 155 | if (typeof release.eol === 'string') { 156 | const eolDate = new Date(release.eol); 157 | if (!isNaN(eolDate.getTime())) { 158 | // Check if it reached EoL within the last eolLookbackDays 159 | if (eolDate <= now && eolDate >= eolLookbackDate) { 160 | if (!release.cycle) return; 161 | const title = `Drop ${languageName} ${release.cycle} support`; 162 | const body = dedent(` 163 | This version(${languageName} ${release.cycle}) has reached End of Life. 164 | Please drop its support as needed. 165 | 166 | **EoL date**: ${release.eol} 167 | endoflife.date for ${languageName}: ${eolViewUrl} 168 | `); 169 | await createIssueIfNotExists(title, body, ['keep']); 170 | } 171 | } 172 | } 173 | }; 174 | 175 | /** 176 | * Check new release for a single release. 177 | * @param {ReleaseCycle} release 178 | * @param {Date} now 179 | * @param {Date} newReleaseSince 180 | */ 181 | const checkNewRelease = async (release, now, newReleaseSince) => { 182 | if (ltsOnly && release.lts === false) { 183 | core.info(`Skipping non-LTS release: ${release.cycle}`); 184 | return; 185 | } 186 | if (typeof release.releaseDate === 'string') { 187 | const rDate = new Date(release.releaseDate); 188 | if (!isNaN(rDate.getTime())) { 189 | // Check if releaseDate is within newReleaseThresholdDays 190 | if (rDate >= newReleaseSince && rDate <= now) { 191 | if (!release.cycle) return; 192 | const ltsTag = ltsOnly ? ' (LTS)' : ''; 193 | const title = `Support ${languageName} ${release.cycle}${ltsTag}`; 194 | const body = dedent(` 195 | A new version(${languageName} ${release.cycle}) has been released. 196 | Please start to support it. 197 | 198 | **Release date**: ${release.releaseDate} 199 | endoflife.date for ${languageName}: ${eolViewUrl} 200 | `); 201 | await createIssueIfNotExists(title, body, ['keep']); 202 | } 203 | } 204 | } 205 | }; 206 | 207 | core.info(`Starting EoL & NewRelease check for ${languageName} ...`); 208 | const now = new Date(); 209 | const eolLookbackDate = new Date(now); 210 | eolLookbackDate.setDate(eolLookbackDate.getDate() - eolLookbackDays); 211 | 212 | const newReleaseSince = new Date(now); 213 | newReleaseSince.setDate(newReleaseSince.getDate() - newReleaseThresholdDays); 214 | 215 | try { 216 | const data = await fetchWithRetry(eolJsonUrl); 217 | for (const release of data) { 218 | core.info(`Checking release: ${JSON.stringify(release)}`); 219 | await checkEoL(release, now, eolLookbackDate); 220 | await checkNewRelease(release, now, newReleaseSince); 221 | } 222 | } catch (err) { 223 | core.error(`Error checking EoL/NewReleases for ${languageName}: ${err.message}`); 224 | const yw = getYearWeek(new Date()); 225 | const errorTitle = `[CI ERROR] EoL/NewRelease check for ${languageName} in ${yw}`; 226 | const runUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`; 227 | const body = dedent(` 228 | The automated check for EoL and new releases failed (retried ${retryCount} times). 229 | **Error**: ${err.message} 230 | **Action URL**: [View job log here](${runUrl}) 231 | Please investigate (network issues, invalid JSON, etc.) and fix it to monitor EOL site automatically. 232 | `); 233 | await createIssueIfNotExists(errorTitle, body, ['keep']); 234 | core.setFailed(err.message); 235 | } 236 | }; 237 | -------------------------------------------------------------------------------- /.github/scripts/update-version.mjs: -------------------------------------------------------------------------------- 1 | import fs from 'fs/promises'; 2 | import { exec } from 'child_process'; 3 | import { promisify } from 'util'; 4 | 5 | const execAsync = promisify(exec); 6 | 7 | async function updateVersion(newVersion) { 8 | // Files having version number 9 | const files = { 10 | packageJson: './package.json', 11 | packageLockJson: './package-lock.json', 12 | versionTs: './src/version.ts', 13 | }; 14 | 15 | // package.json 16 | const packageJsonData = JSON.parse(await fs.readFile(files.packageJson, 'utf8')); 17 | packageJsonData.version = newVersion; 18 | await fs.writeFile(files.packageJson, JSON.stringify(packageJsonData, null, 2) + '\n'); 19 | 20 | // package-lock.json 21 | const packageLockJsonData = JSON.parse(await fs.readFile(files.packageLockJson, 'utf8')); 22 | packageLockJsonData.version = newVersion; 23 | if (packageLockJsonData.packages && packageLockJsonData.packages[""]) { 24 | packageLockJsonData.packages[""].version = newVersion; 25 | } 26 | await fs.writeFile(files.packageLockJson, JSON.stringify(packageLockJsonData, null, 2) + '\n'); 27 | 28 | // src/version.ts 29 | const versionTsData = await fs.readFile(files.versionTs, 'utf8'); 30 | const updatedVersionTsData = versionTsData.replace( 31 | /const LINE_BOT_MCP_SERVER_VERSION = ".*?";/, 32 | `const LINE_BOT_MCP_SERVER_VERSION = "${newVersion}";` 33 | ); 34 | await fs.writeFile(files.versionTs, updatedVersionTsData); 35 | 36 | console.log(`Version updated to ${newVersion} in all files.`); 37 | } 38 | 39 | async function verifyVersion(expectedVersion) { 40 | // package.json 41 | const packageJsonData = JSON.parse(await fs.readFile('./package.json', 'utf8')); 42 | if (packageJsonData.version !== expectedVersion) { 43 | throw new Error(`package.json version mismatch: expected ${expectedVersion}, found ${packageJsonData.version}`); 44 | } 45 | 46 | // package-lock.json 47 | const packageLockJsonData = JSON.parse(await fs.readFile('./package-lock.json', 'utf8')); 48 | if (packageLockJsonData.version !== expectedVersion) { 49 | throw new Error(`package-lock.json version mismatch: expected ${expectedVersion}, found ${packageLockJsonData.version}`); 50 | } 51 | if (packageLockJsonData.packages && packageLockJsonData.packages[""] && packageLockJsonData.packages[""].version !== expectedVersion) { 52 | throw new Error(`package-lock.json root package version mismatch: expected ${expectedVersion}, found ${packageLockJsonData.packages[""].version}`); 53 | } 54 | 55 | // src/version.ts 56 | const versionTsData = await fs.readFile('./src/version.ts', 'utf8'); 57 | if (!versionTsData.includes(`const LINE_BOT_MCP_SERVER_VERSION = "${expectedVersion}";`)) { 58 | throw new Error(`src/version.ts version mismatch: expected ${expectedVersion}`); 59 | } 60 | 61 | console.log(`All files have the correct version: ${expectedVersion}`); 62 | } 63 | 64 | async function verifyGitDiff() { 65 | try { 66 | const { stdout: numstatOutput } = await execAsync('git diff --numstat'); 67 | const { addedLines, deletedLines } = numstatOutput.trim().split('\n').reduce((acc, line) => { 68 | const [added, deleted] = line.split('\t').map(Number); 69 | acc.addedLines += added; 70 | acc.deletedLines += deleted; 71 | return acc; 72 | }, { addedLines: 0, deletedLines: 0 }); 73 | 74 | if (addedLines !== 4 || deletedLines !== 4) { 75 | throw new Error(`Unexpected number of changed lines: expected 4 added and 4 deleted, found ${addedLines} added and ${deletedLines} deleted`); 76 | } 77 | 78 | console.log('Git diff verification passed: 4 lines added and 4 lines deleted.'); 79 | 80 | // Display the diff with context and color 81 | const { stdout: diffOutput } = await execAsync('git diff -U5 --color=always'); 82 | console.log('Git diff with context and color:\n', diffOutput); 83 | 84 | } catch (error) { 85 | console.error('Error during git diff verification:', error.message); 86 | process.exit(1); 87 | } 88 | } 89 | 90 | // Main process 91 | const args = process.argv.slice(2); 92 | if (args.length !== 1) { 93 | console.error('Usage: node update-version.mjs '); 94 | process.exit(1); 95 | } 96 | 97 | const newVersion = args[0]; 98 | await updateVersion(newVersion); 99 | await verifyVersion(newVersion); 100 | await verifyGitDiff(); 101 | -------------------------------------------------------------------------------- /.github/workflows/check-eol-newrelease.yml: -------------------------------------------------------------------------------- 1 | name: "Check EoL & New Releases" 2 | 3 | on: 4 | schedule: 5 | # Every day at 22:00 UTC -> 07:00 JST 6 | - cron: '0 22 * * *' 7 | workflow_dispatch: 8 | 9 | jobs: 10 | check-eol-newrelease: 11 | runs-on: ubuntu-latest 12 | permissions: 13 | contents: read 14 | issues: write 15 | if: github.repository == 'line/line-bot-mcp-server' 16 | steps: 17 | - name: Check out code 18 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 19 | 20 | - name: Run EoL & NewRelease check 21 | uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 22 | with: 23 | script: | 24 | const checkEolAndNewReleases = require('.github/scripts/check-eol-newrelease.cjs'); 25 | await checkEolAndNewReleases({ github, context, core }, { 26 | languageName: 'Node.js', 27 | eolJsonUrl: 'https://endoflife.date/api/nodejs.json', 28 | eolViewUrl: 'https://endoflife.date/nodejs', 29 | eolLookbackDays: 100, 30 | newReleaseThresholdDays: 100, 31 | ltsOnly: true, 32 | retryCount: 3, 33 | retryIntervalSec: 30 34 | }); 35 | github-token: ${{ secrets.GITHUB_TOKEN }} 36 | -------------------------------------------------------------------------------- /.github/workflows/close-issue.yml: -------------------------------------------------------------------------------- 1 | # https://docs.github.com/en/actions/managing-issues-and-pull-requests/closing-inactive-issues 2 | # https://github.com/marketplace/actions/close-stale-issues 3 | name: Close inactive issues 4 | on: 5 | schedule: 6 | # Every day at 1:30 UTC -> 10:30 JST 7 | - cron: "30 1 * * *" 8 | 9 | jobs: 10 | close-issues: 11 | runs-on: ubuntu-latest 12 | permissions: 13 | issues: write 14 | pull-requests: write 15 | if: github.repository == 'line/line-bot-mcp-server' 16 | steps: 17 | - uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9.1.0 18 | with: 19 | days-before-issue-stale: 28 # 4 weeks 20 | days-before-issue-close: 0 21 | stale-issue-label: "no-activity" 22 | close-issue-message: "This issue was closed because it has been inactive for 28 days." 23 | exempt-issue-labels: "bug,enhancement,keep,untriaged" 24 | days-before-pr-stale: -1 25 | days-before-pr-close: 28 26 | stale-pr-label: "no-activity" 27 | close-pr-message: "This pull request was closed because it has been inactive for 28 days. Please reopen if you still intend to submit this pull request." 28 | repo-token: ${{ secrets.GITHUB_TOKEN }} 29 | -------------------------------------------------------------------------------- /.github/workflows/create-draft-release.yml: -------------------------------------------------------------------------------- 1 | name: Create Draft Release with Auto-Generated Notes 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | version_type: 7 | description: "Select the version type to increment (major, minor, patch)" 8 | required: true 9 | type: choice 10 | options: 11 | - patch 12 | - minor 13 | - major 14 | release_title: 15 | description: "Enter the title of the release" 16 | required: true 17 | type: string 18 | acknowledge_draft: 19 | description: "I understand that I must re-edit and finalize the draft release (Y/N)" 20 | required: true 21 | type: choice 22 | options: 23 | - "No" 24 | - "Yes" 25 | 26 | jobs: 27 | validate-input: 28 | runs-on: ubuntu-latest 29 | permissions: {} 30 | steps: 31 | - name: Validate Acknowledgement 32 | if: ${{ github.event.inputs.acknowledge_draft != 'Yes' }} 33 | run: | 34 | echo "You must select 'Yes' to acknowledge your responsibility for finalizing the draft release." 35 | exit 1 36 | - name: Validate title (no empty) 37 | if: ${{ github.event.inputs.release_title == '' }} 38 | run: | 39 | echo "You must enter a title for the release." 40 | exit 1 41 | 42 | create-draft-release: 43 | runs-on: ubuntu-latest 44 | needs: validate-input 45 | permissions: 46 | contents: write 47 | steps: 48 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 49 | - name: Fetch Latest Release 50 | id: get-latest-release 51 | uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 52 | with: 53 | script: | 54 | const latestRelease = await github.rest.repos.getLatestRelease({ 55 | owner: context.repo.owner, 56 | repo: context.repo.repo, 57 | }).catch(() => null); 58 | 59 | if (latestRelease) { 60 | core.setOutput('latest_tag', latestRelease.data.tag_name); 61 | } else { 62 | core.setOutput('latest_tag', 'v0.0.0'); // Default for first release 63 | } 64 | 65 | - name: Calculate New Version 66 | id: calculate-version 67 | uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 68 | with: 69 | script: | 70 | const latestTag = '${{ steps.get-latest-release.outputs.latest_tag }}'; 71 | const versionType = '${{ github.event.inputs.version_type }}'; 72 | 73 | const [major, minor, patch] = latestTag.replace('v', '').split('.').map(Number); 74 | 75 | let newVersion; 76 | if (versionType === 'major') { 77 | newVersion = `v${major + 1}.0.0`; 78 | } else if (versionType === 'minor') { 79 | newVersion = `v${major}.${minor + 1}.0`; 80 | } else { 81 | newVersion = `v${major}.${minor}.${patch + 1}`; 82 | } 83 | 84 | core.setOutput('new_version', newVersion); 85 | 86 | - name: Generate Release Notes 87 | id: generate-release-notes 88 | uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 89 | with: 90 | script: | 91 | const { data: releaseNotes } = await github.rest.repos.generateReleaseNotes({ 92 | owner: context.repo.owner, 93 | repo: context.repo.repo, 94 | tag_name: "${{ steps.calculate-version.outputs.new_version }}" 95 | }); 96 | 97 | const actor = context.actor; 98 | const noteToAdd = `**@${actor} 👈 TODO: Write detailed release note for this version before release**\n`; 99 | 100 | const footer = `---\nThis release is prepared by @${actor}`; 101 | 102 | const modifiedBody = releaseNotes.body.replace( 103 | '## What\'s Changed', 104 | `## What's Changed\n\n${noteToAdd}` 105 | ) 106 | .concat(`\n\n${footer}`); 107 | 108 | console.log(`releaseNotes (modified): ${JSON.stringify(modifiedBody, null, 2)}`); 109 | core.setOutput("release_body", modifiedBody); 110 | 111 | - name: Prepare Release Title 112 | id: title 113 | env: 114 | # "vX.Y.Z Release Title" 115 | RAW_TITLE: ${{ steps.calculate-version.outputs.new_version }} ${{ github.event.inputs.release_title }} 116 | run: | 117 | # Print RAW_TITLE safely, then escape double quotes 118 | SANITIZED_TITLE="$(printf '%s' "$RAW_TITLE" | sed 's/"/\\"/g')" 119 | echo "sanitized_title=$SANITIZED_TITLE" >> "$GITHUB_OUTPUT" 120 | 121 | - name: Write Release Notes to File 122 | run: | 123 | echo "${{ steps.generate-release-notes.outputs.release_body }}" > release-notes.txt 124 | 125 | - name: Create Draft Release 126 | run: | 127 | gh release create "${{ steps.calculate-version.outputs.new_version }}" \ 128 | --title "${{ steps.title.outputs.sanitized_title }}" \ 129 | --notes-file release-notes.txt \ 130 | --draft \ 131 | --repo "${{ github.repository }}" 132 | env: 133 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 134 | -------------------------------------------------------------------------------- /.github/workflows/label-issue.yml: -------------------------------------------------------------------------------- 1 | name: Label issue 2 | 3 | on: 4 | issues: 5 | types: 6 | - opened 7 | - reopened 8 | - closed 9 | 10 | jobs: 11 | label-issues: 12 | runs-on: ubuntu-latest 13 | permissions: 14 | issues: write 15 | steps: 16 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 17 | 18 | - name: Add label on issue open 19 | if: github.event.action == 'opened' || github.event.action == 'reopened' 20 | run: | 21 | gh issue edit ${{ github.event.issue.number }} \ 22 | --add-label "untriaged" \ 23 | env: 24 | GH_TOKEN: ${{ github.token }} 25 | 26 | - name: Remove label on issue close 27 | if: github.event.action == 'closed' 28 | run: | 29 | gh issue edit ${{ github.event.issue.number }} \ 30 | --remove-label "untriaged" 31 | env: 32 | GH_TOKEN: ${{ github.token }} 33 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release Node.js Package 2 | on: 3 | release: 4 | types: [published] 5 | workflow_dispatch: 6 | inputs: 7 | version: 8 | description: 'The version to release' 9 | required: true 10 | 11 | jobs: 12 | release-package: 13 | runs-on: ubuntu-latest 14 | permissions: 15 | contents: read 16 | id-token: write 17 | issues: write 18 | steps: 19 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 20 | # Setup .npmrc file to publish to GitHub Packages 21 | - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 22 | with: 23 | node-version: 22 24 | registry-url: 'https://registry.npmjs.org' 25 | - run: npm install 26 | - name: Update version in package.json, package-lock.json 27 | run: | 28 | if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then 29 | VERSION=${{ github.event.inputs.version }} 30 | else 31 | VERSION=${{ github.event.release.tag_name }} 32 | fi 33 | VERSION=${VERSION#v} 34 | echo "VERSION=$VERSION" >> $GITHUB_ENV 35 | node .github/scripts/update-version.mjs $VERSION 36 | - run: npm run release 37 | env: 38 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 39 | 40 | - name: Create GitHub Issue on Failure 41 | if: failure() 42 | uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 43 | with: 44 | script: | 45 | const { owner, repo } = context.repo; 46 | const version = process.env.VERSION; 47 | const issueTitle = `Release job for ${version} failed`; 48 | const issueBody = `The release job failed. Please check the [workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for more details.`; 49 | const assignees = [context.actor]; 50 | 51 | await github.rest.issues.create({ 52 | owner, 53 | repo, 54 | title: issueTitle, 55 | body: issueBody, 56 | assignees 57 | }); 58 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: 4 | push: 5 | pull_request: 6 | merge_group: 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | permissions: 12 | contents: read 13 | strategy: 14 | matrix: 15 | # https://nodejs.org/en/about/releases/ 16 | node: 17 | - '20' 18 | - '20.12.2' 19 | - '22' 20 | - '24' 21 | fail-fast: false 22 | 23 | name: Node.js ${{ matrix.node }} 24 | 25 | steps: 26 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 27 | with: 28 | submodules: true 29 | - name: Setup Node.js 30 | uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 31 | with: 32 | node-version: ${{ matrix.node }} 33 | cache: 'npm' 34 | - name: Install Dependency 35 | run: npm ci 36 | - name: Build 37 | run: npm run build 38 | - name: Install pnpm # For publint 39 | run: npm install -g pnpm 40 | - name: publint 41 | run: npx publint 42 | 43 | pinact: 44 | runs-on: ubuntu-latest 45 | permissions: 46 | contents: read 47 | steps: 48 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 49 | - name: Run pinact 50 | uses: suzuki-shunsuke/pinact-action@49cbd6acd0dbab6a6be2585d1dbdaa43b4410133 # v1.0.0 51 | with: 52 | skip_push: "true" 53 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Dependency directories 15 | node_modules/ 16 | 17 | # Optional npm cache directory 18 | .npm 19 | 20 | # Optional eslint cache 21 | .eslintcache 22 | 23 | # Optional REPL history 24 | .node_repl_history 25 | 26 | # Output of 'npm pack' 27 | *.tgz 28 | 29 | # Yarn Integrity file 30 | .yarn-integrity 31 | 32 | # dotenv environment variables file 33 | .env 34 | 35 | # Built files 36 | dist 37 | 38 | # IDE 39 | .idea/ 40 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "typescript", 3 | "trailingComma": "all", 4 | "arrowParens": "avoid" 5 | } 6 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | [dl_oss_dev@linecorp.com](mailto:dl_oss_dev@linecorp.com). 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | [https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][v2.0]. 120 | 121 | Community Impact Guidelines were inspired by 122 | [Mozilla's code of conduct enforcement ladder][Mozilla CoC]. 123 | 124 | For answers to common questions about this code of conduct, see the FAQ at 125 | [https://www.contributor-covenant.org/faq][FAQ]. Translations are available 126 | at [https://www.contributor-covenant.org/translations][translations]. 127 | 128 | [homepage]: https://www.contributor-covenant.org 129 | [v2.0]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html 130 | [Mozilla CoC]: https://github.com/mozilla/diversity 131 | [FAQ]: https://www.contributor-covenant.org/faq 132 | [translations]: https://www.contributor-covenant.org/translations 133 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to contribute to LINE Bot MCP Server 2 | 3 | First of all, thank you so much for taking your time to contribute! LINE Bot MCP 4 | Server is not very different from any other open source projects. It will 5 | be fantastic if you help us by doing any of the following: 6 | 7 | - File an issue in [the issue tracker](https://github.com/line/line-bot-mcp-server/issues) 8 | to report bugs and propose new features and improvements. 9 | - Ask a question using [the issue tracker](https://github.com/line/line-bot-mcp-server/issues). 10 | - Contribute your work by sending [a pull request](https://github.com/line/line-bot-mcp-server/pulls). 11 | 12 | ## Development 13 | 14 | You can freely fork the project, clone the forked repository, and start editing. 15 | 16 | You may use the following npm scripts for development: 17 | 18 | * `npm run format`: Format source code with [Prettier](https://github.com/prettier/prettier) 19 | * `npm run format:check`: Silently run `format` and report formatting errors 20 | * `npm run build`: Build TypeScript code into JavaScript. The built files will 21 | be placed in `dist/`. 22 | 23 | We lint and build on CI, but it is always nice to check them before 24 | uploading a pull request. 25 | 26 | ## Contributor license agreement 27 | 28 | When you are sending a pull request and it's a non-trivial change beyond fixing typos, please make sure to sign 29 | [the ICLA (individual contributor license agreement)](https://cla-assistant.io/line/line-bot-mcp-server). Please 30 | [contact us](mailto:dl_oss_dev@linecorp.com) if you need the CCLA (corporate contributor license agreement). 31 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:22.16-alpine AS builder 2 | 3 | COPY . /app 4 | 5 | WORKDIR /app 6 | 7 | RUN --mount=type=cache,target=/root/.npm-production npm ci --ignore-scripts --omit-dev 8 | 9 | RUN --mount=type=cache,target=/root/.npm npm run build 10 | 11 | # --- Release Stage --- 12 | FROM node:22-alpine AS release 13 | 14 | # Set up a non-root user ('appuser'/'appgroup') to avoid running as root - good security practice! 15 | # (-S is the Alpine option for a system user/group, suitable here) 16 | RUN addgroup -S appgroup && adduser -S appuser -G appgroup 17 | 18 | # Copy the built code and necessary package files from our builder stage 19 | COPY --from=builder /app/dist /app/dist 20 | COPY --from=builder /app/package.json /app/package.json 21 | COPY --from=builder /app/package-lock.json /app/package-lock.json 22 | 23 | ENV NODE_ENV=production 24 | 25 | WORKDIR /app 26 | 27 | # Give our new 'appuser' ownership of the application files inside /app 28 | # Needs to happen after copying the files over 29 | RUN chown -R appuser:appgroup /app 30 | 31 | # Install *only* the production dependencies 32 | RUN npm ci --ignore-scripts --omit-dev 33 | 34 | # Now, switch to running as our non-root user for the actual app process 35 | USER appuser 36 | 37 | # Define how to start the application 38 | ENTRYPOINT ["node", "dist/index.js"] 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | https://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2025 LY Corporation 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | https://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.ja.md: -------------------------------------------------------------------------------- 1 | # LINE Bot MCP Server 2 | 3 | [![npmjs](https://badge.fury.io/js/%40line%2Fline-bot-mcp-server.svg)](https://www.npmjs.com/package/@line/line-bot-mcp-server) 4 | 5 | LINE公式アカウントとAI Agentを接続するために、LINE Messaging APIを統合する[Model Context Protocol (MCP)](https://github.com/modelcontextprotocol) Server 6 | 7 | ![](/assets/demo.ja.png) 8 | 9 | > [!NOTE] 10 | > このリポジトリはプレビュー版として提供されています。実験的な目的で提供されており、完全な機能や包括的なサポートが含まれていないことにご注意ください。 11 | 12 | ## Tools 13 | 14 | 1. **push_text_message** 15 | - LINEでユーザーにシンプルなテキストメッセージを送信する。 16 | - **入力:** 17 | - `user_id` (string?): メッセージ受信者のユーザーID。デフォルトはDESTINATION_USER_ID。`user_id`または`DESTINATION_USER_ID`のどちらか一方は必ず設定する必要があります。 18 | - `message.text` (string): ユーザーに送信するテキスト。 19 | 2. **push_flex_message** 20 | - LINEでユーザーに高度にカスタマイズ可能なフレックスメッセージを送信する。 21 | - **入力:** 22 | - `user_id` (string?): メッセージ受信者のユーザーID。デフォルトはDESTINATION_USER_ID。`user_id`または`DESTINATION_USER_ID`のどちらか一方は必ず設定する必要があります。 23 | - `message.altText` (string): フレックスメッセージが表示できない場合に表示される代替テキスト。 24 | - `message.content` (any): フレックスメッセージの内容。メッセージのレイアウトとコンポーネントを定義するJSONオブジェクト。 25 | - `message.contents.type` (enum): コンテナのタイプ。'bubble'は単一コンテナ、'carousel'は複数のスワイプ可能なバブルを示す。 26 | 3. **broadcast_text_message** 27 | - LINE公式アカウントと友だちになっているすべてのユーザーに、LINEでシンプルなテキストメッセージを送信する。 28 | - **入力:** 29 | - `message.text` (string): ユーザーに送信するテキスト。 30 | 4. **broadcast_flex_message** 31 | - LINE公式アカウントと友だちになっているすべてのユーザーに、LINEで高度にカスタマイズ可能なフレックスメッセージを送信する。 32 | - **入力:** 33 | - `message.altText` (string): フレックスメッセージが表示できない場合に表示される代替テキスト。 34 | - `message.content` (any): フレックスメッセージの内容。メッセージのレイアウトとコンポーネントを定義するJSONオブジェクト。 35 | - `message.contents.type` (enum): コンテナのタイプ。'bubble'は単一コンテナ、'carousel'は複数のスワイプ可能なバブルを示す。 36 | 5. **get_profile** 37 | - LINEユーザーの詳細なプロフィール情報を取得する。表示名、プロフィール画像URL、ステータスメッセージ、言語を取得できる。 38 | - **入力:** 39 | - `user_id` (string?): プロフィールを取得したいユーザーのユーザーID。デフォルトはDESTINATION_USER_ID。`user_id`または`DESTINATION_USER_ID`のどちらか一方は必ず設定する必要があります。======= 40 | 6. **get_message_quota** 41 | - LINE公式アカウントのメッセージ容量と消費量を取得します。月間メッセージ制限と現在の使用量が表示されます。 42 | - **入力:** 43 | - なし 44 | 45 | ## インストール (npxを使用) 46 | 47 | 要件: 48 | - Node.js v20 以上 49 | 50 | ### Step 1: LINE公式アカウントを作成 51 | 52 | このMCP ServerはLINE公式アカウントを利用しています。公式アカウントをお持ちでない場合は、[こちらの手順](https://developers.line.biz/ja/docs/messaging-api/getting-started/#create-oa)に従って作成してください。 53 | 54 | LINE公式アカウントをお持ちであれば、[こちらの手順](https://developers.line.biz/ja/docs/messaging-api/getting-started/#using-oa-manager)に従ってMessaging APIを有効にしてください。 55 | 56 | ### Step 2: AI Agentを設定 57 | 58 | Claude DesktopやClaudeなどのAI Agentに次の設定を追加してください。 59 | 60 | 環境変数や引数は次のように設定してください: 61 | 62 | - `CHANNEL_ACCESS_TOKEN`: (必須) チャネルアクセストークン。これを取得するには、[こちらの手順](https://developers.line.biz/ja/docs/basics/channel-access-token/#long-lived-channel-access-token)に従ってください。 63 | - `DESTINATION_USER_ID`: (オプション) デフォルトのメッセージ受信者のユーザーID。Toolの入力に`user_id`が含まれていない場合、`DESTINATION_USER_ID`は必ず設定する必要があります。これを確認するには、[こちらの手順](https://developers.line.biz/ja/docs/messaging-api/getting-user-ids/#get-own-user-id)に従ってください。 64 | 65 | ```json 66 | { 67 | "mcpServers": { 68 | "line-bot": { 69 | "command": "npx", 70 | "args": [ 71 | "@line/line-bot-mcp-server" 72 | ], 73 | "env": { 74 | "CHANNEL_ACCESS_TOKEN" : "FILL_HERE", 75 | "DESTINATION_USER_ID" : "FILL_HERE" 76 | } 77 | } 78 | } 79 | } 80 | ``` 81 | 82 | ## インストール (Dockerを使用) 83 | 84 | ### Step 1: LINE公式アカウントを作成 85 | 86 | このMCP ServerはLINE公式アカウントを利用しています。公式アカウントをお持ちでない場合は、[こちらの手順](https://developers.line.biz/ja/docs/messaging-api/getting-started/#create-oa)に従って作成してください。 87 | 88 | LINE公式アカウントをお持ちであれば、[こちらの手順](https://developers.line.biz/ja/docs/messaging-api/getting-started/#using-oa-manager)に従ってMessaging APIを有効にしてください。 89 | 90 | ### Step 2: line-bot-mcp-serverをインストール 91 | 92 | このリポジトリをクローンします: 93 | 94 | ``` 95 | git clone git@github.com:line/line-bot-mcp-server.git 96 | ``` 97 | 98 | Dockerイメージをビルドします: 99 | ``` 100 | docker build -t line/line-bot-mcp-server . 101 | ``` 102 | 103 | ### Step 3: AI Agentを設定 104 | 105 | Claude DesktopやClaudeなどのAI Agentに次の設定を追加してください。 106 | 107 | 環境変数や引数は次のように設定してください: 108 | 109 | - `mcpServers.args`: (必須) `line-bot-mcp-server`へのパス。 110 | - `CHANNEL_ACCESS_TOKEN`: (必須) チャネルアクセストークン。これを取得するには、[こちらの手順](https://developers.line.biz/ja/docs/basics/channel-access-token/#long-lived-channel-access-token)に従ってください。 111 | - `DESTINATION_USER_ID`: (オプション) デフォルトのメッセージ受信者のユーザーID。Toolの入力に`user_id`が含まれていない場合、`DESTINATION_USER_ID`は必ず設定する必要があります。これを確認するには、[こちらの手順](https://developers.line.biz/ja/docs/messaging-api/getting-user-ids/#get-own-user-id)に従ってください。 112 | 113 | ```json 114 | { 115 | "mcpServers": { 116 | "line-bot": { 117 | "command": "docker", 118 | "args": [ 119 | "run", 120 | "-i", 121 | "--rm", 122 | "-e", 123 | "CHANNEL_ACCESS_TOKEN", 124 | "-e", 125 | "DESTINATION_USER_ID", 126 | "line/line-bot-mcp-server" 127 | ], 128 | "env": { 129 | "CHANNEL_ACCESS_TOKEN" : "FILL_HERE", 130 | "DESTINATION_USER_ID" : "FILL_HERE" 131 | } 132 | } 133 | } 134 | } 135 | ``` 136 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [日本語版 READMEはこちら](README.ja.md) 2 | 3 | # LINE Bot MCP Server 4 | 5 | [![npmjs](https://badge.fury.io/js/%40line%2Fline-bot-mcp-server.svg)](https://www.npmjs.com/package/@line/line-bot-mcp-server) 6 | 7 | [Model Context Protocol (MCP)](https://github.com/modelcontextprotocol) server implementation that integrates the LINE Messaging API to connect an AI Agent to the LINE Official Account. 8 | 9 | ![](/assets/demo.png) 10 | 11 | > [!NOTE] 12 | > This repository is provided as a preview version. While we offer it for experimental purposes, please be aware that it may not include complete functionality or comprehensive support. 13 | 14 | ## Tools 15 | 16 | 1. **push_text_message** 17 | - Push a simple text message to a user via LINE. 18 | - **Inputs:** 19 | - `user_id` (string?): The user ID to receive a message. Defaults to DESTINATION_USER_ID. Either `user_id` or `DESTINATION_USER_ID` must be set. 20 | - `message.text` (string): The plain text content to send to the user. 21 | 2. **push_flex_message** 22 | - Push a highly customizable flex message to a user via LINE. 23 | - **Inputs:** 24 | - `user_id` (string?): The user ID to receive a message. Defaults to DESTINATION_USER_ID. Either `user_id` or `DESTINATION_USER_ID` must be set. 25 | - `message.altText` (string): Alternative text shown when flex message cannot be displayed. 26 | - `message.content` (any): The content of the flex message. This is a JSON object that defines the layout and components of the message. 27 | - `message.contents.type` (enum): Type of the container. 'bubble' for single container, 'carousel' for multiple swipeable bubbles. 28 | 3. **broadcast_text_message** 29 | - Broadcast a simple text message via LINE to all users who have followed your LINE Official Account. 30 | - **Inputs:** 31 | - `message.text` (string): The plain text content to send to the users. 32 | 4. **broadcast_flex_message** 33 | - Broadcast a highly customizable flex message via LINE to all users who have added your LINE Official Account. 34 | - **Inputs:** 35 | - `message.altText` (string): Alternative text shown when flex message cannot be displayed. 36 | - `message.content` (any): The content of the flex message. This is a JSON object that defines the layout and components of the message. 37 | - `message.contents.type` (enum): Type of the container. 'bubble' for single container, 'carousel' for multiple swipeable bubbles. 38 | 5. **get_profile** 39 | - Get detailed profile information of a LINE user including display name, profile picture URL, status message and language. 40 | - **Inputs:** 41 | - `user_id` (string?): The ID of the user whose profile you want to retrieve. Defaults to DESTINATION_USER_ID. 42 | 6. **get_message_quota** 43 | - Get the message quota and consumption of the LINE Official Account. This shows the monthly message limit and current usage. 44 | - **Inputs:** 45 | - None 46 | 47 | ## Installation (Using npx) 48 | 49 | requirements: 50 | - Node.js v20 or later 51 | 52 | ### Step 1: Create LINE Official Account 53 | 54 | This MCP server utilizes a LINE Official Account. If you do not have one, please create it by following [this instructions](https://developers.line.biz/en/docs/messaging-api/getting-started/#create-oa). 55 | 56 | If you have a LINE Official Account, enable the Messaging API for your LINE Official Account by following [this instructions](https://developers.line.biz/en/docs/messaging-api/getting-started/#using-oa-manager). 57 | 58 | ### Step 2: Configure AI Agent 59 | 60 | Please add the following configuration for an AI Agent like Claude Desktop or Cline. 61 | 62 | Set the environment variables or arguments as follows: 63 | 64 | - `CHANNEL_ACCESS_TOKEN`: (required) Channel Access Token. You can confirm this by following [this instructions](https://developers.line.biz/en/docs/basics/channel-access-token/#long-lived-channel-access-token). 65 | - `DESTINATION_USER_ID`: (optional) The default user ID of the recipient. If the Tool's input does not include `user_id`, `DESTINATION_USER_ID` is required. You can confirm this by following [this instructions](https://developers.line.biz/en/docs/messaging-api/getting-user-ids/#get-own-user-id). 66 | 67 | ```json 68 | { 69 | "mcpServers": { 70 | "line-bot": { 71 | "command": "npx", 72 | "args": [ 73 | "@line/line-bot-mcp-server" 74 | ], 75 | "env": { 76 | "CHANNEL_ACCESS_TOKEN" : "FILL_HERE", 77 | "DESTINATION_USER_ID" : "FILL_HERE" 78 | } 79 | } 80 | } 81 | } 82 | ``` 83 | 84 | ## Installation (Using Docker) 85 | 86 | ### Step 1: Create LINE Official Account 87 | 88 | This MCP server utilizes a LINE Official Account. If you do not have one, please create it by following [this instructions](https://developers.line.biz/en/docs/messaging-api/getting-started/#create-oa). 89 | 90 | If you have a LINE Official Account, enable the Messaging API for your LINE Official Account by following [this instructions](https://developers.line.biz/en/docs/messaging-api/getting-started/#using-oa-manager). 91 | 92 | 93 | ### Step 2: Build line-bot-mcp-server image 94 | 95 | Clone this repository: 96 | 97 | ``` 98 | git clone git@github.com:line/line-bot-mcp-server.git 99 | ``` 100 | 101 | Build the Docker image: 102 | 103 | ``` 104 | docker build -t line/line-bot-mcp-server . 105 | ``` 106 | 107 | ### Step 3: Configure AI Agent 108 | 109 | Please add the following configuration for an AI Agent like Claude Desktop or Cline. 110 | 111 | Set the environment variables or arguments as follows: 112 | 113 | - `mcpServers.args`: (required) The path to `line-bot-mcp-server`. 114 | - `CHANNEL_ACCESS_TOKEN`: (required) Channel Access Token. You can confirm this by following [this instructions](https://developers.line.biz/en/docs/basics/channel-access-token/#long-lived-channel-access-token). 115 | - `DESTINATION_USER_ID`: (optional) The default user ID of the recipient. If the Tool's input does not include `user_id`, `DESTINATION_USER_ID` is required. 116 | You can confirm this by following [this instructions](https://developers.line.biz/en/docs/messaging-api/getting-user-ids/#get-own-user-id). 117 | 118 | 119 | ```json 120 | { 121 | "mcpServers": { 122 | "line-bot": { 123 | "command": "docker", 124 | "args": [ 125 | "run", 126 | "-i", 127 | "--rm", 128 | "-e", 129 | "CHANNEL_ACCESS_TOKEN", 130 | "-e", 131 | "DESTINATION_USER_ID", 132 | "line/line-bot-mcp-server" 133 | ], 134 | "env": { 135 | "CHANNEL_ACCESS_TOKEN" : "FILL_HERE", 136 | "DESTINATION_USER_ID" : "FILL_HERE" 137 | } 138 | } 139 | } 140 | } 141 | ``` 142 | 143 | ## Versioning 144 | 145 | This project respects semantic versioning 146 | 147 | See http://semver.org/ 148 | 149 | ## Contributing 150 | 151 | Please check [CONTRIBUTING](./CONTRIBUTING.md) before making a contribution. 152 | -------------------------------------------------------------------------------- /assets/demo.ja.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/line/line-bot-mcp-server/44651c4d32bec6923c50f71af55ef87d635e3833/assets/demo.ja.png -------------------------------------------------------------------------------- /assets/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/line/line-bot-mcp-server/44651c4d32bec6923c50f71af55ef87d635e3833/assets/demo.png -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@line/line-bot-mcp-server", 3 | "version": "0.0.1-local", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "@line/line-bot-mcp-server", 9 | "version": "0.0.1-local", 10 | "license": "Apache-2.0", 11 | "dependencies": { 12 | "@line/bot-sdk": "^10.0.0", 13 | "@modelcontextprotocol/sdk": "^1.8.0", 14 | "zod": "^3.24.2" 15 | }, 16 | "bin": { 17 | "line-bot-mcp-server": "dist/index.js" 18 | }, 19 | "devDependencies": { 20 | "@types/node": "^22", 21 | "prettier": "3.5.3", 22 | "shx": "^0.4.0", 23 | "tsx": "^4.19.3", 24 | "typescript": "^5.6.2" 25 | }, 26 | "engines": { 27 | "node": ">=20" 28 | } 29 | }, 30 | "node_modules/@esbuild/aix-ppc64": { 31 | "version": "0.25.2", 32 | "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.2.tgz", 33 | "integrity": "sha512-wCIboOL2yXZym2cgm6mlA742s9QeJ8DjGVaL39dLN4rRwrOgOyYSnOaFPhKZGLb2ngj4EyfAFjsNJwPXZvseag==", 34 | "cpu": [ 35 | "ppc64" 36 | ], 37 | "dev": true, 38 | "license": "MIT", 39 | "optional": true, 40 | "os": [ 41 | "aix" 42 | ], 43 | "engines": { 44 | "node": ">=18" 45 | } 46 | }, 47 | "node_modules/@esbuild/android-arm": { 48 | "version": "0.25.2", 49 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.2.tgz", 50 | "integrity": "sha512-NQhH7jFstVY5x8CKbcfa166GoV0EFkaPkCKBQkdPJFvo5u+nGXLEH/ooniLb3QI8Fk58YAx7nsPLozUWfCBOJA==", 51 | "cpu": [ 52 | "arm" 53 | ], 54 | "dev": true, 55 | "license": "MIT", 56 | "optional": true, 57 | "os": [ 58 | "android" 59 | ], 60 | "engines": { 61 | "node": ">=18" 62 | } 63 | }, 64 | "node_modules/@esbuild/android-arm64": { 65 | "version": "0.25.2", 66 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.2.tgz", 67 | "integrity": "sha512-5ZAX5xOmTligeBaeNEPnPaeEuah53Id2tX4c2CVP3JaROTH+j4fnfHCkr1PjXMd78hMst+TlkfKcW/DlTq0i4w==", 68 | "cpu": [ 69 | "arm64" 70 | ], 71 | "dev": true, 72 | "license": "MIT", 73 | "optional": true, 74 | "os": [ 75 | "android" 76 | ], 77 | "engines": { 78 | "node": ">=18" 79 | } 80 | }, 81 | "node_modules/@esbuild/android-x64": { 82 | "version": "0.25.2", 83 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.2.tgz", 84 | "integrity": "sha512-Ffcx+nnma8Sge4jzddPHCZVRvIfQ0kMsUsCMcJRHkGJ1cDmhe4SsrYIjLUKn1xpHZybmOqCWwB0zQvsjdEHtkg==", 85 | "cpu": [ 86 | "x64" 87 | ], 88 | "dev": true, 89 | "license": "MIT", 90 | "optional": true, 91 | "os": [ 92 | "android" 93 | ], 94 | "engines": { 95 | "node": ">=18" 96 | } 97 | }, 98 | "node_modules/@esbuild/darwin-arm64": { 99 | "version": "0.25.2", 100 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.2.tgz", 101 | "integrity": "sha512-MpM6LUVTXAzOvN4KbjzU/q5smzryuoNjlriAIx+06RpecwCkL9JpenNzpKd2YMzLJFOdPqBpuub6eVRP5IgiSA==", 102 | "cpu": [ 103 | "arm64" 104 | ], 105 | "dev": true, 106 | "license": "MIT", 107 | "optional": true, 108 | "os": [ 109 | "darwin" 110 | ], 111 | "engines": { 112 | "node": ">=18" 113 | } 114 | }, 115 | "node_modules/@esbuild/darwin-x64": { 116 | "version": "0.25.2", 117 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.2.tgz", 118 | "integrity": "sha512-5eRPrTX7wFyuWe8FqEFPG2cU0+butQQVNcT4sVipqjLYQjjh8a8+vUTfgBKM88ObB85ahsnTwF7PSIt6PG+QkA==", 119 | "cpu": [ 120 | "x64" 121 | ], 122 | "dev": true, 123 | "license": "MIT", 124 | "optional": true, 125 | "os": [ 126 | "darwin" 127 | ], 128 | "engines": { 129 | "node": ">=18" 130 | } 131 | }, 132 | "node_modules/@esbuild/freebsd-arm64": { 133 | "version": "0.25.2", 134 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.2.tgz", 135 | "integrity": "sha512-mLwm4vXKiQ2UTSX4+ImyiPdiHjiZhIaE9QvC7sw0tZ6HoNMjYAqQpGyui5VRIi5sGd+uWq940gdCbY3VLvsO1w==", 136 | "cpu": [ 137 | "arm64" 138 | ], 139 | "dev": true, 140 | "license": "MIT", 141 | "optional": true, 142 | "os": [ 143 | "freebsd" 144 | ], 145 | "engines": { 146 | "node": ">=18" 147 | } 148 | }, 149 | "node_modules/@esbuild/freebsd-x64": { 150 | "version": "0.25.2", 151 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.2.tgz", 152 | "integrity": "sha512-6qyyn6TjayJSwGpm8J9QYYGQcRgc90nmfdUb0O7pp1s4lTY+9D0H9O02v5JqGApUyiHOtkz6+1hZNvNtEhbwRQ==", 153 | "cpu": [ 154 | "x64" 155 | ], 156 | "dev": true, 157 | "license": "MIT", 158 | "optional": true, 159 | "os": [ 160 | "freebsd" 161 | ], 162 | "engines": { 163 | "node": ">=18" 164 | } 165 | }, 166 | "node_modules/@esbuild/linux-arm": { 167 | "version": "0.25.2", 168 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.2.tgz", 169 | "integrity": "sha512-UHBRgJcmjJv5oeQF8EpTRZs/1knq6loLxTsjc3nxO9eXAPDLcWW55flrMVc97qFPbmZP31ta1AZVUKQzKTzb0g==", 170 | "cpu": [ 171 | "arm" 172 | ], 173 | "dev": true, 174 | "license": "MIT", 175 | "optional": true, 176 | "os": [ 177 | "linux" 178 | ], 179 | "engines": { 180 | "node": ">=18" 181 | } 182 | }, 183 | "node_modules/@esbuild/linux-arm64": { 184 | "version": "0.25.2", 185 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.2.tgz", 186 | "integrity": "sha512-gq/sjLsOyMT19I8obBISvhoYiZIAaGF8JpeXu1u8yPv8BE5HlWYobmlsfijFIZ9hIVGYkbdFhEqC0NvM4kNO0g==", 187 | "cpu": [ 188 | "arm64" 189 | ], 190 | "dev": true, 191 | "license": "MIT", 192 | "optional": true, 193 | "os": [ 194 | "linux" 195 | ], 196 | "engines": { 197 | "node": ">=18" 198 | } 199 | }, 200 | "node_modules/@esbuild/linux-ia32": { 201 | "version": "0.25.2", 202 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.2.tgz", 203 | "integrity": "sha512-bBYCv9obgW2cBP+2ZWfjYTU+f5cxRoGGQ5SeDbYdFCAZpYWrfjjfYwvUpP8MlKbP0nwZ5gyOU/0aUzZ5HWPuvQ==", 204 | "cpu": [ 205 | "ia32" 206 | ], 207 | "dev": true, 208 | "license": "MIT", 209 | "optional": true, 210 | "os": [ 211 | "linux" 212 | ], 213 | "engines": { 214 | "node": ">=18" 215 | } 216 | }, 217 | "node_modules/@esbuild/linux-loong64": { 218 | "version": "0.25.2", 219 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.2.tgz", 220 | "integrity": "sha512-SHNGiKtvnU2dBlM5D8CXRFdd+6etgZ9dXfaPCeJtz+37PIUlixvlIhI23L5khKXs3DIzAn9V8v+qb1TRKrgT5w==", 221 | "cpu": [ 222 | "loong64" 223 | ], 224 | "dev": true, 225 | "license": "MIT", 226 | "optional": true, 227 | "os": [ 228 | "linux" 229 | ], 230 | "engines": { 231 | "node": ">=18" 232 | } 233 | }, 234 | "node_modules/@esbuild/linux-mips64el": { 235 | "version": "0.25.2", 236 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.2.tgz", 237 | "integrity": "sha512-hDDRlzE6rPeoj+5fsADqdUZl1OzqDYow4TB4Y/3PlKBD0ph1e6uPHzIQcv2Z65u2K0kpeByIyAjCmjn1hJgG0Q==", 238 | "cpu": [ 239 | "mips64el" 240 | ], 241 | "dev": true, 242 | "license": "MIT", 243 | "optional": true, 244 | "os": [ 245 | "linux" 246 | ], 247 | "engines": { 248 | "node": ">=18" 249 | } 250 | }, 251 | "node_modules/@esbuild/linux-ppc64": { 252 | "version": "0.25.2", 253 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.2.tgz", 254 | "integrity": "sha512-tsHu2RRSWzipmUi9UBDEzc0nLc4HtpZEI5Ba+Omms5456x5WaNuiG3u7xh5AO6sipnJ9r4cRWQB2tUjPyIkc6g==", 255 | "cpu": [ 256 | "ppc64" 257 | ], 258 | "dev": true, 259 | "license": "MIT", 260 | "optional": true, 261 | "os": [ 262 | "linux" 263 | ], 264 | "engines": { 265 | "node": ">=18" 266 | } 267 | }, 268 | "node_modules/@esbuild/linux-riscv64": { 269 | "version": "0.25.2", 270 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.2.tgz", 271 | "integrity": "sha512-k4LtpgV7NJQOml/10uPU0s4SAXGnowi5qBSjaLWMojNCUICNu7TshqHLAEbkBdAszL5TabfvQ48kK84hyFzjnw==", 272 | "cpu": [ 273 | "riscv64" 274 | ], 275 | "dev": true, 276 | "license": "MIT", 277 | "optional": true, 278 | "os": [ 279 | "linux" 280 | ], 281 | "engines": { 282 | "node": ">=18" 283 | } 284 | }, 285 | "node_modules/@esbuild/linux-s390x": { 286 | "version": "0.25.2", 287 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.2.tgz", 288 | "integrity": "sha512-GRa4IshOdvKY7M/rDpRR3gkiTNp34M0eLTaC1a08gNrh4u488aPhuZOCpkF6+2wl3zAN7L7XIpOFBhnaE3/Q8Q==", 289 | "cpu": [ 290 | "s390x" 291 | ], 292 | "dev": true, 293 | "license": "MIT", 294 | "optional": true, 295 | "os": [ 296 | "linux" 297 | ], 298 | "engines": { 299 | "node": ">=18" 300 | } 301 | }, 302 | "node_modules/@esbuild/linux-x64": { 303 | "version": "0.25.2", 304 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.2.tgz", 305 | "integrity": "sha512-QInHERlqpTTZ4FRB0fROQWXcYRD64lAoiegezDunLpalZMjcUcld3YzZmVJ2H/Cp0wJRZ8Xtjtj0cEHhYc/uUg==", 306 | "cpu": [ 307 | "x64" 308 | ], 309 | "dev": true, 310 | "license": "MIT", 311 | "optional": true, 312 | "os": [ 313 | "linux" 314 | ], 315 | "engines": { 316 | "node": ">=18" 317 | } 318 | }, 319 | "node_modules/@esbuild/netbsd-arm64": { 320 | "version": "0.25.2", 321 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.2.tgz", 322 | "integrity": "sha512-talAIBoY5M8vHc6EeI2WW9d/CkiO9MQJ0IOWX8hrLhxGbro/vBXJvaQXefW2cP0z0nQVTdQ/eNyGFV1GSKrxfw==", 323 | "cpu": [ 324 | "arm64" 325 | ], 326 | "dev": true, 327 | "license": "MIT", 328 | "optional": true, 329 | "os": [ 330 | "netbsd" 331 | ], 332 | "engines": { 333 | "node": ">=18" 334 | } 335 | }, 336 | "node_modules/@esbuild/netbsd-x64": { 337 | "version": "0.25.2", 338 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.2.tgz", 339 | "integrity": "sha512-voZT9Z+tpOxrvfKFyfDYPc4DO4rk06qamv1a/fkuzHpiVBMOhpjK+vBmWM8J1eiB3OLSMFYNaOaBNLXGChf5tg==", 340 | "cpu": [ 341 | "x64" 342 | ], 343 | "dev": true, 344 | "license": "MIT", 345 | "optional": true, 346 | "os": [ 347 | "netbsd" 348 | ], 349 | "engines": { 350 | "node": ">=18" 351 | } 352 | }, 353 | "node_modules/@esbuild/openbsd-arm64": { 354 | "version": "0.25.2", 355 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.2.tgz", 356 | "integrity": "sha512-dcXYOC6NXOqcykeDlwId9kB6OkPUxOEqU+rkrYVqJbK2hagWOMrsTGsMr8+rW02M+d5Op5NNlgMmjzecaRf7Tg==", 357 | "cpu": [ 358 | "arm64" 359 | ], 360 | "dev": true, 361 | "license": "MIT", 362 | "optional": true, 363 | "os": [ 364 | "openbsd" 365 | ], 366 | "engines": { 367 | "node": ">=18" 368 | } 369 | }, 370 | "node_modules/@esbuild/openbsd-x64": { 371 | "version": "0.25.2", 372 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.2.tgz", 373 | "integrity": "sha512-t/TkWwahkH0Tsgoq1Ju7QfgGhArkGLkF1uYz8nQS/PPFlXbP5YgRpqQR3ARRiC2iXoLTWFxc6DJMSK10dVXluw==", 374 | "cpu": [ 375 | "x64" 376 | ], 377 | "dev": true, 378 | "license": "MIT", 379 | "optional": true, 380 | "os": [ 381 | "openbsd" 382 | ], 383 | "engines": { 384 | "node": ">=18" 385 | } 386 | }, 387 | "node_modules/@esbuild/sunos-x64": { 388 | "version": "0.25.2", 389 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.2.tgz", 390 | "integrity": "sha512-cfZH1co2+imVdWCjd+D1gf9NjkchVhhdpgb1q5y6Hcv9TP6Zi9ZG/beI3ig8TvwT9lH9dlxLq5MQBBgwuj4xvA==", 391 | "cpu": [ 392 | "x64" 393 | ], 394 | "dev": true, 395 | "license": "MIT", 396 | "optional": true, 397 | "os": [ 398 | "sunos" 399 | ], 400 | "engines": { 401 | "node": ">=18" 402 | } 403 | }, 404 | "node_modules/@esbuild/win32-arm64": { 405 | "version": "0.25.2", 406 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.2.tgz", 407 | "integrity": "sha512-7Loyjh+D/Nx/sOTzV8vfbB3GJuHdOQyrOryFdZvPHLf42Tk9ivBU5Aedi7iyX+x6rbn2Mh68T4qq1SDqJBQO5Q==", 408 | "cpu": [ 409 | "arm64" 410 | ], 411 | "dev": true, 412 | "license": "MIT", 413 | "optional": true, 414 | "os": [ 415 | "win32" 416 | ], 417 | "engines": { 418 | "node": ">=18" 419 | } 420 | }, 421 | "node_modules/@esbuild/win32-ia32": { 422 | "version": "0.25.2", 423 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.2.tgz", 424 | "integrity": "sha512-WRJgsz9un0nqZJ4MfhabxaD9Ft8KioqU3JMinOTvobbX6MOSUigSBlogP8QB3uxpJDsFS6yN+3FDBdqE5lg9kg==", 425 | "cpu": [ 426 | "ia32" 427 | ], 428 | "dev": true, 429 | "license": "MIT", 430 | "optional": true, 431 | "os": [ 432 | "win32" 433 | ], 434 | "engines": { 435 | "node": ">=18" 436 | } 437 | }, 438 | "node_modules/@esbuild/win32-x64": { 439 | "version": "0.25.2", 440 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.2.tgz", 441 | "integrity": "sha512-kM3HKb16VIXZyIeVrM1ygYmZBKybX8N4p754bw390wGO3Tf2j4L2/WYL+4suWujpgf6GBYs3jv7TyUivdd05JA==", 442 | "cpu": [ 443 | "x64" 444 | ], 445 | "dev": true, 446 | "license": "MIT", 447 | "optional": true, 448 | "os": [ 449 | "win32" 450 | ], 451 | "engines": { 452 | "node": ">=18" 453 | } 454 | }, 455 | "node_modules/@line/bot-sdk": { 456 | "version": "10.0.0", 457 | "resolved": "https://registry.npmjs.org/@line/bot-sdk/-/bot-sdk-10.0.0.tgz", 458 | "integrity": "sha512-Uj6ZVivMDzZUV4Jm/RSsJinryyj3HS+fnyYob+mNl4/uUDWQ2OAEZDVopl0v0tcjXlCRC6GUB+nfEZLgBFI+dg==", 459 | "license": "Apache-2.0", 460 | "dependencies": { 461 | "@types/node": "^22.0.0" 462 | }, 463 | "engines": { 464 | "node": ">=20" 465 | }, 466 | "optionalDependencies": { 467 | "axios": "^1.7.4" 468 | } 469 | }, 470 | "node_modules/@modelcontextprotocol/sdk": { 471 | "version": "1.12.1", 472 | "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.12.1.tgz", 473 | "integrity": "sha512-KG1CZhZfWg+u8pxeM/mByJDScJSrjjxLc8fwQqbsS8xCjBmQfMNEBTotYdNanKekepnfRI85GtgQlctLFpcYPw==", 474 | "license": "MIT", 475 | "dependencies": { 476 | "ajv": "^6.12.6", 477 | "content-type": "^1.0.5", 478 | "cors": "^2.8.5", 479 | "cross-spawn": "^7.0.5", 480 | "eventsource": "^3.0.2", 481 | "express": "^5.0.1", 482 | "express-rate-limit": "^7.5.0", 483 | "pkce-challenge": "^5.0.0", 484 | "raw-body": "^3.0.0", 485 | "zod": "^3.23.8", 486 | "zod-to-json-schema": "^3.24.1" 487 | }, 488 | "engines": { 489 | "node": ">=18" 490 | } 491 | }, 492 | "node_modules/@nodelib/fs.scandir": { 493 | "version": "2.1.5", 494 | "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", 495 | "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", 496 | "dev": true, 497 | "license": "MIT", 498 | "dependencies": { 499 | "@nodelib/fs.stat": "2.0.5", 500 | "run-parallel": "^1.1.9" 501 | }, 502 | "engines": { 503 | "node": ">= 8" 504 | } 505 | }, 506 | "node_modules/@nodelib/fs.stat": { 507 | "version": "2.0.5", 508 | "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", 509 | "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", 510 | "dev": true, 511 | "license": "MIT", 512 | "engines": { 513 | "node": ">= 8" 514 | } 515 | }, 516 | "node_modules/@nodelib/fs.walk": { 517 | "version": "1.2.8", 518 | "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", 519 | "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", 520 | "dev": true, 521 | "license": "MIT", 522 | "dependencies": { 523 | "@nodelib/fs.scandir": "2.1.5", 524 | "fastq": "^1.6.0" 525 | }, 526 | "engines": { 527 | "node": ">= 8" 528 | } 529 | }, 530 | "node_modules/@types/node": { 531 | "version": "22.15.30", 532 | "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.30.tgz", 533 | "integrity": "sha512-6Q7lr06bEHdlfplU6YRbgG1SFBdlsfNC4/lX+SkhiTs0cpJkOElmWls8PxDFv4yY/xKb8Y6SO0OmSX4wgqTZbA==", 534 | "license": "MIT", 535 | "dependencies": { 536 | "undici-types": "~6.21.0" 537 | } 538 | }, 539 | "node_modules/accepts": { 540 | "version": "2.0.0", 541 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", 542 | "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", 543 | "license": "MIT", 544 | "dependencies": { 545 | "mime-types": "^3.0.0", 546 | "negotiator": "^1.0.0" 547 | }, 548 | "engines": { 549 | "node": ">= 0.6" 550 | } 551 | }, 552 | "node_modules/ajv": { 553 | "version": "6.12.6", 554 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", 555 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", 556 | "license": "MIT", 557 | "dependencies": { 558 | "fast-deep-equal": "^3.1.1", 559 | "fast-json-stable-stringify": "^2.0.0", 560 | "json-schema-traverse": "^0.4.1", 561 | "uri-js": "^4.2.2" 562 | }, 563 | "funding": { 564 | "type": "github", 565 | "url": "https://github.com/sponsors/epoberezkin" 566 | } 567 | }, 568 | "node_modules/asynckit": { 569 | "version": "0.4.0", 570 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 571 | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", 572 | "license": "MIT", 573 | "optional": true 574 | }, 575 | "node_modules/axios": { 576 | "version": "1.8.4", 577 | "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz", 578 | "integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==", 579 | "license": "MIT", 580 | "optional": true, 581 | "dependencies": { 582 | "follow-redirects": "^1.15.6", 583 | "form-data": "^4.0.0", 584 | "proxy-from-env": "^1.1.0" 585 | } 586 | }, 587 | "node_modules/body-parser": { 588 | "version": "2.2.0", 589 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz", 590 | "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==", 591 | "license": "MIT", 592 | "dependencies": { 593 | "bytes": "^3.1.2", 594 | "content-type": "^1.0.5", 595 | "debug": "^4.4.0", 596 | "http-errors": "^2.0.0", 597 | "iconv-lite": "^0.6.3", 598 | "on-finished": "^2.4.1", 599 | "qs": "^6.14.0", 600 | "raw-body": "^3.0.0", 601 | "type-is": "^2.0.0" 602 | }, 603 | "engines": { 604 | "node": ">=18" 605 | } 606 | }, 607 | "node_modules/braces": { 608 | "version": "3.0.3", 609 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", 610 | "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", 611 | "dev": true, 612 | "license": "MIT", 613 | "dependencies": { 614 | "fill-range": "^7.1.1" 615 | }, 616 | "engines": { 617 | "node": ">=8" 618 | } 619 | }, 620 | "node_modules/bytes": { 621 | "version": "3.1.2", 622 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 623 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", 624 | "license": "MIT", 625 | "engines": { 626 | "node": ">= 0.8" 627 | } 628 | }, 629 | "node_modules/call-bind-apply-helpers": { 630 | "version": "1.0.2", 631 | "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", 632 | "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", 633 | "license": "MIT", 634 | "dependencies": { 635 | "es-errors": "^1.3.0", 636 | "function-bind": "^1.1.2" 637 | }, 638 | "engines": { 639 | "node": ">= 0.4" 640 | } 641 | }, 642 | "node_modules/call-bound": { 643 | "version": "1.0.4", 644 | "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", 645 | "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", 646 | "license": "MIT", 647 | "dependencies": { 648 | "call-bind-apply-helpers": "^1.0.2", 649 | "get-intrinsic": "^1.3.0" 650 | }, 651 | "engines": { 652 | "node": ">= 0.4" 653 | }, 654 | "funding": { 655 | "url": "https://github.com/sponsors/ljharb" 656 | } 657 | }, 658 | "node_modules/combined-stream": { 659 | "version": "1.0.8", 660 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 661 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", 662 | "license": "MIT", 663 | "optional": true, 664 | "dependencies": { 665 | "delayed-stream": "~1.0.0" 666 | }, 667 | "engines": { 668 | "node": ">= 0.8" 669 | } 670 | }, 671 | "node_modules/content-disposition": { 672 | "version": "1.0.0", 673 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz", 674 | "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==", 675 | "license": "MIT", 676 | "dependencies": { 677 | "safe-buffer": "5.2.1" 678 | }, 679 | "engines": { 680 | "node": ">= 0.6" 681 | } 682 | }, 683 | "node_modules/content-type": { 684 | "version": "1.0.5", 685 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", 686 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", 687 | "license": "MIT", 688 | "engines": { 689 | "node": ">= 0.6" 690 | } 691 | }, 692 | "node_modules/cookie": { 693 | "version": "0.7.2", 694 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", 695 | "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", 696 | "license": "MIT", 697 | "engines": { 698 | "node": ">= 0.6" 699 | } 700 | }, 701 | "node_modules/cookie-signature": { 702 | "version": "1.2.2", 703 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", 704 | "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", 705 | "license": "MIT", 706 | "engines": { 707 | "node": ">=6.6.0" 708 | } 709 | }, 710 | "node_modules/cors": { 711 | "version": "2.8.5", 712 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", 713 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", 714 | "license": "MIT", 715 | "dependencies": { 716 | "object-assign": "^4", 717 | "vary": "^1" 718 | }, 719 | "engines": { 720 | "node": ">= 0.10" 721 | } 722 | }, 723 | "node_modules/cross-spawn": { 724 | "version": "7.0.6", 725 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", 726 | "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", 727 | "license": "MIT", 728 | "dependencies": { 729 | "path-key": "^3.1.0", 730 | "shebang-command": "^2.0.0", 731 | "which": "^2.0.1" 732 | }, 733 | "engines": { 734 | "node": ">= 8" 735 | } 736 | }, 737 | "node_modules/debug": { 738 | "version": "4.4.0", 739 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", 740 | "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", 741 | "license": "MIT", 742 | "dependencies": { 743 | "ms": "^2.1.3" 744 | }, 745 | "engines": { 746 | "node": ">=6.0" 747 | }, 748 | "peerDependenciesMeta": { 749 | "supports-color": { 750 | "optional": true 751 | } 752 | } 753 | }, 754 | "node_modules/delayed-stream": { 755 | "version": "1.0.0", 756 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 757 | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", 758 | "license": "MIT", 759 | "optional": true, 760 | "engines": { 761 | "node": ">=0.4.0" 762 | } 763 | }, 764 | "node_modules/depd": { 765 | "version": "2.0.0", 766 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 767 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", 768 | "license": "MIT", 769 | "engines": { 770 | "node": ">= 0.8" 771 | } 772 | }, 773 | "node_modules/dunder-proto": { 774 | "version": "1.0.1", 775 | "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", 776 | "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", 777 | "license": "MIT", 778 | "dependencies": { 779 | "call-bind-apply-helpers": "^1.0.1", 780 | "es-errors": "^1.3.0", 781 | "gopd": "^1.2.0" 782 | }, 783 | "engines": { 784 | "node": ">= 0.4" 785 | } 786 | }, 787 | "node_modules/ee-first": { 788 | "version": "1.1.1", 789 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 790 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", 791 | "license": "MIT" 792 | }, 793 | "node_modules/encodeurl": { 794 | "version": "2.0.0", 795 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", 796 | "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", 797 | "license": "MIT", 798 | "engines": { 799 | "node": ">= 0.8" 800 | } 801 | }, 802 | "node_modules/end-of-stream": { 803 | "version": "1.4.4", 804 | "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", 805 | "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", 806 | "dev": true, 807 | "license": "MIT", 808 | "dependencies": { 809 | "once": "^1.4.0" 810 | } 811 | }, 812 | "node_modules/es-define-property": { 813 | "version": "1.0.1", 814 | "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", 815 | "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", 816 | "license": "MIT", 817 | "engines": { 818 | "node": ">= 0.4" 819 | } 820 | }, 821 | "node_modules/es-errors": { 822 | "version": "1.3.0", 823 | "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", 824 | "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", 825 | "license": "MIT", 826 | "engines": { 827 | "node": ">= 0.4" 828 | } 829 | }, 830 | "node_modules/es-object-atoms": { 831 | "version": "1.1.1", 832 | "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", 833 | "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", 834 | "license": "MIT", 835 | "dependencies": { 836 | "es-errors": "^1.3.0" 837 | }, 838 | "engines": { 839 | "node": ">= 0.4" 840 | } 841 | }, 842 | "node_modules/es-set-tostringtag": { 843 | "version": "2.1.0", 844 | "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", 845 | "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", 846 | "license": "MIT", 847 | "optional": true, 848 | "dependencies": { 849 | "es-errors": "^1.3.0", 850 | "get-intrinsic": "^1.2.6", 851 | "has-tostringtag": "^1.0.2", 852 | "hasown": "^2.0.2" 853 | }, 854 | "engines": { 855 | "node": ">= 0.4" 856 | } 857 | }, 858 | "node_modules/esbuild": { 859 | "version": "0.25.2", 860 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.2.tgz", 861 | "integrity": "sha512-16854zccKPnC+toMywC+uKNeYSv+/eXkevRAfwRD/G9Cleq66m8XFIrigkbvauLLlCfDL45Q2cWegSg53gGBnQ==", 862 | "dev": true, 863 | "hasInstallScript": true, 864 | "license": "MIT", 865 | "bin": { 866 | "esbuild": "bin/esbuild" 867 | }, 868 | "engines": { 869 | "node": ">=18" 870 | }, 871 | "optionalDependencies": { 872 | "@esbuild/aix-ppc64": "0.25.2", 873 | "@esbuild/android-arm": "0.25.2", 874 | "@esbuild/android-arm64": "0.25.2", 875 | "@esbuild/android-x64": "0.25.2", 876 | "@esbuild/darwin-arm64": "0.25.2", 877 | "@esbuild/darwin-x64": "0.25.2", 878 | "@esbuild/freebsd-arm64": "0.25.2", 879 | "@esbuild/freebsd-x64": "0.25.2", 880 | "@esbuild/linux-arm": "0.25.2", 881 | "@esbuild/linux-arm64": "0.25.2", 882 | "@esbuild/linux-ia32": "0.25.2", 883 | "@esbuild/linux-loong64": "0.25.2", 884 | "@esbuild/linux-mips64el": "0.25.2", 885 | "@esbuild/linux-ppc64": "0.25.2", 886 | "@esbuild/linux-riscv64": "0.25.2", 887 | "@esbuild/linux-s390x": "0.25.2", 888 | "@esbuild/linux-x64": "0.25.2", 889 | "@esbuild/netbsd-arm64": "0.25.2", 890 | "@esbuild/netbsd-x64": "0.25.2", 891 | "@esbuild/openbsd-arm64": "0.25.2", 892 | "@esbuild/openbsd-x64": "0.25.2", 893 | "@esbuild/sunos-x64": "0.25.2", 894 | "@esbuild/win32-arm64": "0.25.2", 895 | "@esbuild/win32-ia32": "0.25.2", 896 | "@esbuild/win32-x64": "0.25.2" 897 | } 898 | }, 899 | "node_modules/escape-html": { 900 | "version": "1.0.3", 901 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 902 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", 903 | "license": "MIT" 904 | }, 905 | "node_modules/etag": { 906 | "version": "1.8.1", 907 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 908 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", 909 | "license": "MIT", 910 | "engines": { 911 | "node": ">= 0.6" 912 | } 913 | }, 914 | "node_modules/eventsource": { 915 | "version": "3.0.6", 916 | "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.6.tgz", 917 | "integrity": "sha512-l19WpE2m9hSuyP06+FbuUUf1G+R0SFLrtQfbRb9PRr+oimOfxQhgGCbVaXg5IvZyyTThJsxh6L/srkMiCeBPDA==", 918 | "license": "MIT", 919 | "dependencies": { 920 | "eventsource-parser": "^3.0.1" 921 | }, 922 | "engines": { 923 | "node": ">=18.0.0" 924 | } 925 | }, 926 | "node_modules/eventsource-parser": { 927 | "version": "3.0.1", 928 | "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.1.tgz", 929 | "integrity": "sha512-VARTJ9CYeuQYb0pZEPbzi740OWFgpHe7AYJ2WFZVnUDUQp5Dk2yJUgF36YsZ81cOyxT0QxmXD2EQpapAouzWVA==", 930 | "license": "MIT", 931 | "engines": { 932 | "node": ">=18.0.0" 933 | } 934 | }, 935 | "node_modules/execa": { 936 | "version": "1.0.0", 937 | "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", 938 | "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", 939 | "dev": true, 940 | "license": "MIT", 941 | "dependencies": { 942 | "cross-spawn": "^6.0.0", 943 | "get-stream": "^4.0.0", 944 | "is-stream": "^1.1.0", 945 | "npm-run-path": "^2.0.0", 946 | "p-finally": "^1.0.0", 947 | "signal-exit": "^3.0.0", 948 | "strip-eof": "^1.0.0" 949 | }, 950 | "engines": { 951 | "node": ">=6" 952 | } 953 | }, 954 | "node_modules/execa/node_modules/cross-spawn": { 955 | "version": "6.0.6", 956 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", 957 | "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==", 958 | "dev": true, 959 | "license": "MIT", 960 | "dependencies": { 961 | "nice-try": "^1.0.4", 962 | "path-key": "^2.0.1", 963 | "semver": "^5.5.0", 964 | "shebang-command": "^1.2.0", 965 | "which": "^1.2.9" 966 | }, 967 | "engines": { 968 | "node": ">=4.8" 969 | } 970 | }, 971 | "node_modules/execa/node_modules/path-key": { 972 | "version": "2.0.1", 973 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", 974 | "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", 975 | "dev": true, 976 | "license": "MIT", 977 | "engines": { 978 | "node": ">=4" 979 | } 980 | }, 981 | "node_modules/execa/node_modules/shebang-command": { 982 | "version": "1.2.0", 983 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", 984 | "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", 985 | "dev": true, 986 | "license": "MIT", 987 | "dependencies": { 988 | "shebang-regex": "^1.0.0" 989 | }, 990 | "engines": { 991 | "node": ">=0.10.0" 992 | } 993 | }, 994 | "node_modules/execa/node_modules/shebang-regex": { 995 | "version": "1.0.0", 996 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", 997 | "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", 998 | "dev": true, 999 | "license": "MIT", 1000 | "engines": { 1001 | "node": ">=0.10.0" 1002 | } 1003 | }, 1004 | "node_modules/execa/node_modules/which": { 1005 | "version": "1.3.1", 1006 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", 1007 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", 1008 | "dev": true, 1009 | "license": "ISC", 1010 | "dependencies": { 1011 | "isexe": "^2.0.0" 1012 | }, 1013 | "bin": { 1014 | "which": "bin/which" 1015 | } 1016 | }, 1017 | "node_modules/express": { 1018 | "version": "5.1.0", 1019 | "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz", 1020 | "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==", 1021 | "license": "MIT", 1022 | "dependencies": { 1023 | "accepts": "^2.0.0", 1024 | "body-parser": "^2.2.0", 1025 | "content-disposition": "^1.0.0", 1026 | "content-type": "^1.0.5", 1027 | "cookie": "^0.7.1", 1028 | "cookie-signature": "^1.2.1", 1029 | "debug": "^4.4.0", 1030 | "encodeurl": "^2.0.0", 1031 | "escape-html": "^1.0.3", 1032 | "etag": "^1.8.1", 1033 | "finalhandler": "^2.1.0", 1034 | "fresh": "^2.0.0", 1035 | "http-errors": "^2.0.0", 1036 | "merge-descriptors": "^2.0.0", 1037 | "mime-types": "^3.0.0", 1038 | "on-finished": "^2.4.1", 1039 | "once": "^1.4.0", 1040 | "parseurl": "^1.3.3", 1041 | "proxy-addr": "^2.0.7", 1042 | "qs": "^6.14.0", 1043 | "range-parser": "^1.2.1", 1044 | "router": "^2.2.0", 1045 | "send": "^1.1.0", 1046 | "serve-static": "^2.2.0", 1047 | "statuses": "^2.0.1", 1048 | "type-is": "^2.0.1", 1049 | "vary": "^1.1.2" 1050 | }, 1051 | "engines": { 1052 | "node": ">= 18" 1053 | }, 1054 | "funding": { 1055 | "type": "opencollective", 1056 | "url": "https://opencollective.com/express" 1057 | } 1058 | }, 1059 | "node_modules/express-rate-limit": { 1060 | "version": "7.5.0", 1061 | "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.0.tgz", 1062 | "integrity": "sha512-eB5zbQh5h+VenMPM3fh+nw1YExi5nMr6HUCR62ELSP11huvxm/Uir1H1QEyTkk5QX6A58pX6NmaTMceKZ0Eodg==", 1063 | "license": "MIT", 1064 | "engines": { 1065 | "node": ">= 16" 1066 | }, 1067 | "funding": { 1068 | "url": "https://github.com/sponsors/express-rate-limit" 1069 | }, 1070 | "peerDependencies": { 1071 | "express": "^4.11 || 5 || ^5.0.0-beta.1" 1072 | } 1073 | }, 1074 | "node_modules/fast-deep-equal": { 1075 | "version": "3.1.3", 1076 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 1077 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", 1078 | "license": "MIT" 1079 | }, 1080 | "node_modules/fast-glob": { 1081 | "version": "3.3.3", 1082 | "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", 1083 | "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", 1084 | "dev": true, 1085 | "license": "MIT", 1086 | "dependencies": { 1087 | "@nodelib/fs.stat": "^2.0.2", 1088 | "@nodelib/fs.walk": "^1.2.3", 1089 | "glob-parent": "^5.1.2", 1090 | "merge2": "^1.3.0", 1091 | "micromatch": "^4.0.8" 1092 | }, 1093 | "engines": { 1094 | "node": ">=8.6.0" 1095 | } 1096 | }, 1097 | "node_modules/fast-json-stable-stringify": { 1098 | "version": "2.1.0", 1099 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 1100 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", 1101 | "license": "MIT" 1102 | }, 1103 | "node_modules/fastq": { 1104 | "version": "1.19.1", 1105 | "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", 1106 | "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", 1107 | "dev": true, 1108 | "license": "ISC", 1109 | "dependencies": { 1110 | "reusify": "^1.0.4" 1111 | } 1112 | }, 1113 | "node_modules/fill-range": { 1114 | "version": "7.1.1", 1115 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", 1116 | "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", 1117 | "dev": true, 1118 | "license": "MIT", 1119 | "dependencies": { 1120 | "to-regex-range": "^5.0.1" 1121 | }, 1122 | "engines": { 1123 | "node": ">=8" 1124 | } 1125 | }, 1126 | "node_modules/finalhandler": { 1127 | "version": "2.1.0", 1128 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz", 1129 | "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==", 1130 | "license": "MIT", 1131 | "dependencies": { 1132 | "debug": "^4.4.0", 1133 | "encodeurl": "^2.0.0", 1134 | "escape-html": "^1.0.3", 1135 | "on-finished": "^2.4.1", 1136 | "parseurl": "^1.3.3", 1137 | "statuses": "^2.0.1" 1138 | }, 1139 | "engines": { 1140 | "node": ">= 0.8" 1141 | } 1142 | }, 1143 | "node_modules/follow-redirects": { 1144 | "version": "1.15.9", 1145 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", 1146 | "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", 1147 | "funding": [ 1148 | { 1149 | "type": "individual", 1150 | "url": "https://github.com/sponsors/RubenVerborgh" 1151 | } 1152 | ], 1153 | "license": "MIT", 1154 | "optional": true, 1155 | "engines": { 1156 | "node": ">=4.0" 1157 | }, 1158 | "peerDependenciesMeta": { 1159 | "debug": { 1160 | "optional": true 1161 | } 1162 | } 1163 | }, 1164 | "node_modules/form-data": { 1165 | "version": "4.0.2", 1166 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", 1167 | "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", 1168 | "license": "MIT", 1169 | "optional": true, 1170 | "dependencies": { 1171 | "asynckit": "^0.4.0", 1172 | "combined-stream": "^1.0.8", 1173 | "es-set-tostringtag": "^2.1.0", 1174 | "mime-types": "^2.1.12" 1175 | }, 1176 | "engines": { 1177 | "node": ">= 6" 1178 | } 1179 | }, 1180 | "node_modules/form-data/node_modules/mime-db": { 1181 | "version": "1.52.0", 1182 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 1183 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 1184 | "license": "MIT", 1185 | "optional": true, 1186 | "engines": { 1187 | "node": ">= 0.6" 1188 | } 1189 | }, 1190 | "node_modules/form-data/node_modules/mime-types": { 1191 | "version": "2.1.35", 1192 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 1193 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 1194 | "license": "MIT", 1195 | "optional": true, 1196 | "dependencies": { 1197 | "mime-db": "1.52.0" 1198 | }, 1199 | "engines": { 1200 | "node": ">= 0.6" 1201 | } 1202 | }, 1203 | "node_modules/forwarded": { 1204 | "version": "0.2.0", 1205 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 1206 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", 1207 | "license": "MIT", 1208 | "engines": { 1209 | "node": ">= 0.6" 1210 | } 1211 | }, 1212 | "node_modules/fresh": { 1213 | "version": "2.0.0", 1214 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", 1215 | "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", 1216 | "license": "MIT", 1217 | "engines": { 1218 | "node": ">= 0.8" 1219 | } 1220 | }, 1221 | "node_modules/fsevents": { 1222 | "version": "2.3.3", 1223 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", 1224 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", 1225 | "dev": true, 1226 | "hasInstallScript": true, 1227 | "license": "MIT", 1228 | "optional": true, 1229 | "os": [ 1230 | "darwin" 1231 | ], 1232 | "engines": { 1233 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 1234 | } 1235 | }, 1236 | "node_modules/function-bind": { 1237 | "version": "1.1.2", 1238 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", 1239 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", 1240 | "license": "MIT", 1241 | "funding": { 1242 | "url": "https://github.com/sponsors/ljharb" 1243 | } 1244 | }, 1245 | "node_modules/get-intrinsic": { 1246 | "version": "1.3.0", 1247 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", 1248 | "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", 1249 | "license": "MIT", 1250 | "dependencies": { 1251 | "call-bind-apply-helpers": "^1.0.2", 1252 | "es-define-property": "^1.0.1", 1253 | "es-errors": "^1.3.0", 1254 | "es-object-atoms": "^1.1.1", 1255 | "function-bind": "^1.1.2", 1256 | "get-proto": "^1.0.1", 1257 | "gopd": "^1.2.0", 1258 | "has-symbols": "^1.1.0", 1259 | "hasown": "^2.0.2", 1260 | "math-intrinsics": "^1.1.0" 1261 | }, 1262 | "engines": { 1263 | "node": ">= 0.4" 1264 | }, 1265 | "funding": { 1266 | "url": "https://github.com/sponsors/ljharb" 1267 | } 1268 | }, 1269 | "node_modules/get-proto": { 1270 | "version": "1.0.1", 1271 | "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", 1272 | "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", 1273 | "license": "MIT", 1274 | "dependencies": { 1275 | "dunder-proto": "^1.0.1", 1276 | "es-object-atoms": "^1.0.0" 1277 | }, 1278 | "engines": { 1279 | "node": ">= 0.4" 1280 | } 1281 | }, 1282 | "node_modules/get-stream": { 1283 | "version": "4.1.0", 1284 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", 1285 | "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", 1286 | "dev": true, 1287 | "license": "MIT", 1288 | "dependencies": { 1289 | "pump": "^3.0.0" 1290 | }, 1291 | "engines": { 1292 | "node": ">=6" 1293 | } 1294 | }, 1295 | "node_modules/get-tsconfig": { 1296 | "version": "4.10.0", 1297 | "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.0.tgz", 1298 | "integrity": "sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==", 1299 | "dev": true, 1300 | "license": "MIT", 1301 | "dependencies": { 1302 | "resolve-pkg-maps": "^1.0.0" 1303 | }, 1304 | "funding": { 1305 | "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" 1306 | } 1307 | }, 1308 | "node_modules/glob-parent": { 1309 | "version": "5.1.2", 1310 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 1311 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 1312 | "dev": true, 1313 | "license": "ISC", 1314 | "dependencies": { 1315 | "is-glob": "^4.0.1" 1316 | }, 1317 | "engines": { 1318 | "node": ">= 6" 1319 | } 1320 | }, 1321 | "node_modules/gopd": { 1322 | "version": "1.2.0", 1323 | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", 1324 | "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", 1325 | "license": "MIT", 1326 | "engines": { 1327 | "node": ">= 0.4" 1328 | }, 1329 | "funding": { 1330 | "url": "https://github.com/sponsors/ljharb" 1331 | } 1332 | }, 1333 | "node_modules/has-symbols": { 1334 | "version": "1.1.0", 1335 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", 1336 | "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", 1337 | "license": "MIT", 1338 | "engines": { 1339 | "node": ">= 0.4" 1340 | }, 1341 | "funding": { 1342 | "url": "https://github.com/sponsors/ljharb" 1343 | } 1344 | }, 1345 | "node_modules/has-tostringtag": { 1346 | "version": "1.0.2", 1347 | "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", 1348 | "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", 1349 | "license": "MIT", 1350 | "optional": true, 1351 | "dependencies": { 1352 | "has-symbols": "^1.0.3" 1353 | }, 1354 | "engines": { 1355 | "node": ">= 0.4" 1356 | }, 1357 | "funding": { 1358 | "url": "https://github.com/sponsors/ljharb" 1359 | } 1360 | }, 1361 | "node_modules/hasown": { 1362 | "version": "2.0.2", 1363 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", 1364 | "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", 1365 | "license": "MIT", 1366 | "dependencies": { 1367 | "function-bind": "^1.1.2" 1368 | }, 1369 | "engines": { 1370 | "node": ">= 0.4" 1371 | } 1372 | }, 1373 | "node_modules/http-errors": { 1374 | "version": "2.0.0", 1375 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", 1376 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 1377 | "license": "MIT", 1378 | "dependencies": { 1379 | "depd": "2.0.0", 1380 | "inherits": "2.0.4", 1381 | "setprototypeof": "1.2.0", 1382 | "statuses": "2.0.1", 1383 | "toidentifier": "1.0.1" 1384 | }, 1385 | "engines": { 1386 | "node": ">= 0.8" 1387 | } 1388 | }, 1389 | "node_modules/iconv-lite": { 1390 | "version": "0.6.3", 1391 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", 1392 | "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", 1393 | "license": "MIT", 1394 | "dependencies": { 1395 | "safer-buffer": ">= 2.1.2 < 3.0.0" 1396 | }, 1397 | "engines": { 1398 | "node": ">=0.10.0" 1399 | } 1400 | }, 1401 | "node_modules/inherits": { 1402 | "version": "2.0.4", 1403 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 1404 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 1405 | "license": "ISC" 1406 | }, 1407 | "node_modules/interpret": { 1408 | "version": "1.4.0", 1409 | "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", 1410 | "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", 1411 | "dev": true, 1412 | "license": "MIT", 1413 | "engines": { 1414 | "node": ">= 0.10" 1415 | } 1416 | }, 1417 | "node_modules/ipaddr.js": { 1418 | "version": "1.9.1", 1419 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 1420 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", 1421 | "license": "MIT", 1422 | "engines": { 1423 | "node": ">= 0.10" 1424 | } 1425 | }, 1426 | "node_modules/is-core-module": { 1427 | "version": "2.16.1", 1428 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", 1429 | "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", 1430 | "dev": true, 1431 | "license": "MIT", 1432 | "dependencies": { 1433 | "hasown": "^2.0.2" 1434 | }, 1435 | "engines": { 1436 | "node": ">= 0.4" 1437 | }, 1438 | "funding": { 1439 | "url": "https://github.com/sponsors/ljharb" 1440 | } 1441 | }, 1442 | "node_modules/is-extglob": { 1443 | "version": "2.1.1", 1444 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 1445 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", 1446 | "dev": true, 1447 | "license": "MIT", 1448 | "engines": { 1449 | "node": ">=0.10.0" 1450 | } 1451 | }, 1452 | "node_modules/is-glob": { 1453 | "version": "4.0.3", 1454 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 1455 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 1456 | "dev": true, 1457 | "license": "MIT", 1458 | "dependencies": { 1459 | "is-extglob": "^2.1.1" 1460 | }, 1461 | "engines": { 1462 | "node": ">=0.10.0" 1463 | } 1464 | }, 1465 | "node_modules/is-number": { 1466 | "version": "7.0.0", 1467 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 1468 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 1469 | "dev": true, 1470 | "license": "MIT", 1471 | "engines": { 1472 | "node": ">=0.12.0" 1473 | } 1474 | }, 1475 | "node_modules/is-promise": { 1476 | "version": "4.0.0", 1477 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", 1478 | "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", 1479 | "license": "MIT" 1480 | }, 1481 | "node_modules/is-stream": { 1482 | "version": "1.1.0", 1483 | "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", 1484 | "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", 1485 | "dev": true, 1486 | "license": "MIT", 1487 | "engines": { 1488 | "node": ">=0.10.0" 1489 | } 1490 | }, 1491 | "node_modules/isexe": { 1492 | "version": "2.0.0", 1493 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 1494 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", 1495 | "license": "ISC" 1496 | }, 1497 | "node_modules/json-schema-traverse": { 1498 | "version": "0.4.1", 1499 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 1500 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 1501 | "license": "MIT" 1502 | }, 1503 | "node_modules/math-intrinsics": { 1504 | "version": "1.1.0", 1505 | "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", 1506 | "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", 1507 | "license": "MIT", 1508 | "engines": { 1509 | "node": ">= 0.4" 1510 | } 1511 | }, 1512 | "node_modules/media-typer": { 1513 | "version": "1.1.0", 1514 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", 1515 | "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", 1516 | "license": "MIT", 1517 | "engines": { 1518 | "node": ">= 0.8" 1519 | } 1520 | }, 1521 | "node_modules/merge-descriptors": { 1522 | "version": "2.0.0", 1523 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", 1524 | "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", 1525 | "license": "MIT", 1526 | "engines": { 1527 | "node": ">=18" 1528 | }, 1529 | "funding": { 1530 | "url": "https://github.com/sponsors/sindresorhus" 1531 | } 1532 | }, 1533 | "node_modules/merge2": { 1534 | "version": "1.4.1", 1535 | "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", 1536 | "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", 1537 | "dev": true, 1538 | "license": "MIT", 1539 | "engines": { 1540 | "node": ">= 8" 1541 | } 1542 | }, 1543 | "node_modules/micromatch": { 1544 | "version": "4.0.8", 1545 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", 1546 | "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", 1547 | "dev": true, 1548 | "license": "MIT", 1549 | "dependencies": { 1550 | "braces": "^3.0.3", 1551 | "picomatch": "^2.3.1" 1552 | }, 1553 | "engines": { 1554 | "node": ">=8.6" 1555 | } 1556 | }, 1557 | "node_modules/mime-db": { 1558 | "version": "1.54.0", 1559 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", 1560 | "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", 1561 | "license": "MIT", 1562 | "engines": { 1563 | "node": ">= 0.6" 1564 | } 1565 | }, 1566 | "node_modules/mime-types": { 1567 | "version": "3.0.1", 1568 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", 1569 | "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", 1570 | "license": "MIT", 1571 | "dependencies": { 1572 | "mime-db": "^1.54.0" 1573 | }, 1574 | "engines": { 1575 | "node": ">= 0.6" 1576 | } 1577 | }, 1578 | "node_modules/minimist": { 1579 | "version": "1.2.8", 1580 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", 1581 | "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", 1582 | "dev": true, 1583 | "license": "MIT", 1584 | "funding": { 1585 | "url": "https://github.com/sponsors/ljharb" 1586 | } 1587 | }, 1588 | "node_modules/ms": { 1589 | "version": "2.1.3", 1590 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 1591 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 1592 | "license": "MIT" 1593 | }, 1594 | "node_modules/negotiator": { 1595 | "version": "1.0.0", 1596 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", 1597 | "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", 1598 | "license": "MIT", 1599 | "engines": { 1600 | "node": ">= 0.6" 1601 | } 1602 | }, 1603 | "node_modules/nice-try": { 1604 | "version": "1.0.5", 1605 | "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", 1606 | "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", 1607 | "dev": true, 1608 | "license": "MIT" 1609 | }, 1610 | "node_modules/npm-run-path": { 1611 | "version": "2.0.2", 1612 | "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", 1613 | "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", 1614 | "dev": true, 1615 | "license": "MIT", 1616 | "dependencies": { 1617 | "path-key": "^2.0.0" 1618 | }, 1619 | "engines": { 1620 | "node": ">=4" 1621 | } 1622 | }, 1623 | "node_modules/npm-run-path/node_modules/path-key": { 1624 | "version": "2.0.1", 1625 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", 1626 | "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", 1627 | "dev": true, 1628 | "license": "MIT", 1629 | "engines": { 1630 | "node": ">=4" 1631 | } 1632 | }, 1633 | "node_modules/object-assign": { 1634 | "version": "4.1.1", 1635 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 1636 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", 1637 | "license": "MIT", 1638 | "engines": { 1639 | "node": ">=0.10.0" 1640 | } 1641 | }, 1642 | "node_modules/object-inspect": { 1643 | "version": "1.13.4", 1644 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", 1645 | "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", 1646 | "license": "MIT", 1647 | "engines": { 1648 | "node": ">= 0.4" 1649 | }, 1650 | "funding": { 1651 | "url": "https://github.com/sponsors/ljharb" 1652 | } 1653 | }, 1654 | "node_modules/on-finished": { 1655 | "version": "2.4.1", 1656 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", 1657 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", 1658 | "license": "MIT", 1659 | "dependencies": { 1660 | "ee-first": "1.1.1" 1661 | }, 1662 | "engines": { 1663 | "node": ">= 0.8" 1664 | } 1665 | }, 1666 | "node_modules/once": { 1667 | "version": "1.4.0", 1668 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1669 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 1670 | "license": "ISC", 1671 | "dependencies": { 1672 | "wrappy": "1" 1673 | } 1674 | }, 1675 | "node_modules/p-finally": { 1676 | "version": "1.0.0", 1677 | "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", 1678 | "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", 1679 | "dev": true, 1680 | "license": "MIT", 1681 | "engines": { 1682 | "node": ">=4" 1683 | } 1684 | }, 1685 | "node_modules/parseurl": { 1686 | "version": "1.3.3", 1687 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 1688 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", 1689 | "license": "MIT", 1690 | "engines": { 1691 | "node": ">= 0.8" 1692 | } 1693 | }, 1694 | "node_modules/path-key": { 1695 | "version": "3.1.1", 1696 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 1697 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 1698 | "license": "MIT", 1699 | "engines": { 1700 | "node": ">=8" 1701 | } 1702 | }, 1703 | "node_modules/path-parse": { 1704 | "version": "1.0.7", 1705 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", 1706 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", 1707 | "dev": true, 1708 | "license": "MIT" 1709 | }, 1710 | "node_modules/path-to-regexp": { 1711 | "version": "8.2.0", 1712 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", 1713 | "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==", 1714 | "license": "MIT", 1715 | "engines": { 1716 | "node": ">=16" 1717 | } 1718 | }, 1719 | "node_modules/picomatch": { 1720 | "version": "2.3.1", 1721 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 1722 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 1723 | "dev": true, 1724 | "license": "MIT", 1725 | "engines": { 1726 | "node": ">=8.6" 1727 | }, 1728 | "funding": { 1729 | "url": "https://github.com/sponsors/jonschlinkert" 1730 | } 1731 | }, 1732 | "node_modules/pkce-challenge": { 1733 | "version": "5.0.0", 1734 | "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.0.tgz", 1735 | "integrity": "sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ==", 1736 | "license": "MIT", 1737 | "engines": { 1738 | "node": ">=16.20.0" 1739 | } 1740 | }, 1741 | "node_modules/prettier": { 1742 | "version": "3.5.3", 1743 | "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz", 1744 | "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==", 1745 | "dev": true, 1746 | "license": "MIT", 1747 | "bin": { 1748 | "prettier": "bin/prettier.cjs" 1749 | }, 1750 | "engines": { 1751 | "node": ">=14" 1752 | }, 1753 | "funding": { 1754 | "url": "https://github.com/prettier/prettier?sponsor=1" 1755 | } 1756 | }, 1757 | "node_modules/proxy-addr": { 1758 | "version": "2.0.7", 1759 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 1760 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 1761 | "license": "MIT", 1762 | "dependencies": { 1763 | "forwarded": "0.2.0", 1764 | "ipaddr.js": "1.9.1" 1765 | }, 1766 | "engines": { 1767 | "node": ">= 0.10" 1768 | } 1769 | }, 1770 | "node_modules/proxy-from-env": { 1771 | "version": "1.1.0", 1772 | "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", 1773 | "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", 1774 | "license": "MIT", 1775 | "optional": true 1776 | }, 1777 | "node_modules/pump": { 1778 | "version": "3.0.2", 1779 | "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", 1780 | "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", 1781 | "dev": true, 1782 | "license": "MIT", 1783 | "dependencies": { 1784 | "end-of-stream": "^1.1.0", 1785 | "once": "^1.3.1" 1786 | } 1787 | }, 1788 | "node_modules/punycode": { 1789 | "version": "2.3.1", 1790 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", 1791 | "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", 1792 | "license": "MIT", 1793 | "engines": { 1794 | "node": ">=6" 1795 | } 1796 | }, 1797 | "node_modules/qs": { 1798 | "version": "6.14.0", 1799 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", 1800 | "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", 1801 | "license": "BSD-3-Clause", 1802 | "dependencies": { 1803 | "side-channel": "^1.1.0" 1804 | }, 1805 | "engines": { 1806 | "node": ">=0.6" 1807 | }, 1808 | "funding": { 1809 | "url": "https://github.com/sponsors/ljharb" 1810 | } 1811 | }, 1812 | "node_modules/queue-microtask": { 1813 | "version": "1.2.3", 1814 | "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", 1815 | "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", 1816 | "dev": true, 1817 | "funding": [ 1818 | { 1819 | "type": "github", 1820 | "url": "https://github.com/sponsors/feross" 1821 | }, 1822 | { 1823 | "type": "patreon", 1824 | "url": "https://www.patreon.com/feross" 1825 | }, 1826 | { 1827 | "type": "consulting", 1828 | "url": "https://feross.org/support" 1829 | } 1830 | ], 1831 | "license": "MIT" 1832 | }, 1833 | "node_modules/range-parser": { 1834 | "version": "1.2.1", 1835 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 1836 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", 1837 | "license": "MIT", 1838 | "engines": { 1839 | "node": ">= 0.6" 1840 | } 1841 | }, 1842 | "node_modules/raw-body": { 1843 | "version": "3.0.0", 1844 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz", 1845 | "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==", 1846 | "license": "MIT", 1847 | "dependencies": { 1848 | "bytes": "3.1.2", 1849 | "http-errors": "2.0.0", 1850 | "iconv-lite": "0.6.3", 1851 | "unpipe": "1.0.0" 1852 | }, 1853 | "engines": { 1854 | "node": ">= 0.8" 1855 | } 1856 | }, 1857 | "node_modules/rechoir": { 1858 | "version": "0.6.2", 1859 | "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", 1860 | "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", 1861 | "dev": true, 1862 | "dependencies": { 1863 | "resolve": "^1.1.6" 1864 | }, 1865 | "engines": { 1866 | "node": ">= 0.10" 1867 | } 1868 | }, 1869 | "node_modules/resolve": { 1870 | "version": "1.22.10", 1871 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", 1872 | "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", 1873 | "dev": true, 1874 | "license": "MIT", 1875 | "dependencies": { 1876 | "is-core-module": "^2.16.0", 1877 | "path-parse": "^1.0.7", 1878 | "supports-preserve-symlinks-flag": "^1.0.0" 1879 | }, 1880 | "bin": { 1881 | "resolve": "bin/resolve" 1882 | }, 1883 | "engines": { 1884 | "node": ">= 0.4" 1885 | }, 1886 | "funding": { 1887 | "url": "https://github.com/sponsors/ljharb" 1888 | } 1889 | }, 1890 | "node_modules/resolve-pkg-maps": { 1891 | "version": "1.0.0", 1892 | "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", 1893 | "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", 1894 | "dev": true, 1895 | "license": "MIT", 1896 | "funding": { 1897 | "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" 1898 | } 1899 | }, 1900 | "node_modules/reusify": { 1901 | "version": "1.1.0", 1902 | "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", 1903 | "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", 1904 | "dev": true, 1905 | "license": "MIT", 1906 | "engines": { 1907 | "iojs": ">=1.0.0", 1908 | "node": ">=0.10.0" 1909 | } 1910 | }, 1911 | "node_modules/router": { 1912 | "version": "2.2.0", 1913 | "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", 1914 | "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", 1915 | "license": "MIT", 1916 | "dependencies": { 1917 | "debug": "^4.4.0", 1918 | "depd": "^2.0.0", 1919 | "is-promise": "^4.0.0", 1920 | "parseurl": "^1.3.3", 1921 | "path-to-regexp": "^8.0.0" 1922 | }, 1923 | "engines": { 1924 | "node": ">= 18" 1925 | } 1926 | }, 1927 | "node_modules/run-parallel": { 1928 | "version": "1.2.0", 1929 | "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", 1930 | "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", 1931 | "dev": true, 1932 | "funding": [ 1933 | { 1934 | "type": "github", 1935 | "url": "https://github.com/sponsors/feross" 1936 | }, 1937 | { 1938 | "type": "patreon", 1939 | "url": "https://www.patreon.com/feross" 1940 | }, 1941 | { 1942 | "type": "consulting", 1943 | "url": "https://feross.org/support" 1944 | } 1945 | ], 1946 | "license": "MIT", 1947 | "dependencies": { 1948 | "queue-microtask": "^1.2.2" 1949 | } 1950 | }, 1951 | "node_modules/safe-buffer": { 1952 | "version": "5.2.1", 1953 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 1954 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 1955 | "funding": [ 1956 | { 1957 | "type": "github", 1958 | "url": "https://github.com/sponsors/feross" 1959 | }, 1960 | { 1961 | "type": "patreon", 1962 | "url": "https://www.patreon.com/feross" 1963 | }, 1964 | { 1965 | "type": "consulting", 1966 | "url": "https://feross.org/support" 1967 | } 1968 | ], 1969 | "license": "MIT" 1970 | }, 1971 | "node_modules/safer-buffer": { 1972 | "version": "2.1.2", 1973 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 1974 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", 1975 | "license": "MIT" 1976 | }, 1977 | "node_modules/semver": { 1978 | "version": "5.7.2", 1979 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", 1980 | "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", 1981 | "dev": true, 1982 | "license": "ISC", 1983 | "bin": { 1984 | "semver": "bin/semver" 1985 | } 1986 | }, 1987 | "node_modules/send": { 1988 | "version": "1.2.0", 1989 | "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz", 1990 | "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==", 1991 | "license": "MIT", 1992 | "dependencies": { 1993 | "debug": "^4.3.5", 1994 | "encodeurl": "^2.0.0", 1995 | "escape-html": "^1.0.3", 1996 | "etag": "^1.8.1", 1997 | "fresh": "^2.0.0", 1998 | "http-errors": "^2.0.0", 1999 | "mime-types": "^3.0.1", 2000 | "ms": "^2.1.3", 2001 | "on-finished": "^2.4.1", 2002 | "range-parser": "^1.2.1", 2003 | "statuses": "^2.0.1" 2004 | }, 2005 | "engines": { 2006 | "node": ">= 18" 2007 | } 2008 | }, 2009 | "node_modules/serve-static": { 2010 | "version": "2.2.0", 2011 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz", 2012 | "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==", 2013 | "license": "MIT", 2014 | "dependencies": { 2015 | "encodeurl": "^2.0.0", 2016 | "escape-html": "^1.0.3", 2017 | "parseurl": "^1.3.3", 2018 | "send": "^1.2.0" 2019 | }, 2020 | "engines": { 2021 | "node": ">= 18" 2022 | } 2023 | }, 2024 | "node_modules/setprototypeof": { 2025 | "version": "1.2.0", 2026 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 2027 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", 2028 | "license": "ISC" 2029 | }, 2030 | "node_modules/shebang-command": { 2031 | "version": "2.0.0", 2032 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 2033 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 2034 | "license": "MIT", 2035 | "dependencies": { 2036 | "shebang-regex": "^3.0.0" 2037 | }, 2038 | "engines": { 2039 | "node": ">=8" 2040 | } 2041 | }, 2042 | "node_modules/shebang-regex": { 2043 | "version": "3.0.0", 2044 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 2045 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 2046 | "license": "MIT", 2047 | "engines": { 2048 | "node": ">=8" 2049 | } 2050 | }, 2051 | "node_modules/shelljs": { 2052 | "version": "0.9.2", 2053 | "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.9.2.tgz", 2054 | "integrity": "sha512-S3I64fEiKgTZzKCC46zT/Ib9meqofLrQVbpSswtjFfAVDW+AZ54WTnAM/3/yENoxz/V1Cy6u3kiiEbQ4DNphvw==", 2055 | "dev": true, 2056 | "license": "BSD-3-Clause", 2057 | "dependencies": { 2058 | "execa": "^1.0.0", 2059 | "fast-glob": "^3.3.2", 2060 | "interpret": "^1.0.0", 2061 | "rechoir": "^0.6.2" 2062 | }, 2063 | "bin": { 2064 | "shjs": "bin/shjs" 2065 | }, 2066 | "engines": { 2067 | "node": ">=18" 2068 | } 2069 | }, 2070 | "node_modules/shx": { 2071 | "version": "0.4.0", 2072 | "resolved": "https://registry.npmjs.org/shx/-/shx-0.4.0.tgz", 2073 | "integrity": "sha512-Z0KixSIlGPpijKgcH6oCMCbltPImvaKy0sGH8AkLRXw1KyzpKtaCTizP2xen+hNDqVF4xxgvA0KXSb9o4Q6hnA==", 2074 | "dev": true, 2075 | "license": "MIT", 2076 | "dependencies": { 2077 | "minimist": "^1.2.8", 2078 | "shelljs": "^0.9.2" 2079 | }, 2080 | "bin": { 2081 | "shx": "lib/cli.js" 2082 | }, 2083 | "engines": { 2084 | "node": ">=18" 2085 | } 2086 | }, 2087 | "node_modules/side-channel": { 2088 | "version": "1.1.0", 2089 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", 2090 | "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", 2091 | "license": "MIT", 2092 | "dependencies": { 2093 | "es-errors": "^1.3.0", 2094 | "object-inspect": "^1.13.3", 2095 | "side-channel-list": "^1.0.0", 2096 | "side-channel-map": "^1.0.1", 2097 | "side-channel-weakmap": "^1.0.2" 2098 | }, 2099 | "engines": { 2100 | "node": ">= 0.4" 2101 | }, 2102 | "funding": { 2103 | "url": "https://github.com/sponsors/ljharb" 2104 | } 2105 | }, 2106 | "node_modules/side-channel-list": { 2107 | "version": "1.0.0", 2108 | "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", 2109 | "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", 2110 | "license": "MIT", 2111 | "dependencies": { 2112 | "es-errors": "^1.3.0", 2113 | "object-inspect": "^1.13.3" 2114 | }, 2115 | "engines": { 2116 | "node": ">= 0.4" 2117 | }, 2118 | "funding": { 2119 | "url": "https://github.com/sponsors/ljharb" 2120 | } 2121 | }, 2122 | "node_modules/side-channel-map": { 2123 | "version": "1.0.1", 2124 | "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", 2125 | "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", 2126 | "license": "MIT", 2127 | "dependencies": { 2128 | "call-bound": "^1.0.2", 2129 | "es-errors": "^1.3.0", 2130 | "get-intrinsic": "^1.2.5", 2131 | "object-inspect": "^1.13.3" 2132 | }, 2133 | "engines": { 2134 | "node": ">= 0.4" 2135 | }, 2136 | "funding": { 2137 | "url": "https://github.com/sponsors/ljharb" 2138 | } 2139 | }, 2140 | "node_modules/side-channel-weakmap": { 2141 | "version": "1.0.2", 2142 | "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", 2143 | "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", 2144 | "license": "MIT", 2145 | "dependencies": { 2146 | "call-bound": "^1.0.2", 2147 | "es-errors": "^1.3.0", 2148 | "get-intrinsic": "^1.2.5", 2149 | "object-inspect": "^1.13.3", 2150 | "side-channel-map": "^1.0.1" 2151 | }, 2152 | "engines": { 2153 | "node": ">= 0.4" 2154 | }, 2155 | "funding": { 2156 | "url": "https://github.com/sponsors/ljharb" 2157 | } 2158 | }, 2159 | "node_modules/signal-exit": { 2160 | "version": "3.0.7", 2161 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", 2162 | "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", 2163 | "dev": true, 2164 | "license": "ISC" 2165 | }, 2166 | "node_modules/statuses": { 2167 | "version": "2.0.1", 2168 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", 2169 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", 2170 | "license": "MIT", 2171 | "engines": { 2172 | "node": ">= 0.8" 2173 | } 2174 | }, 2175 | "node_modules/strip-eof": { 2176 | "version": "1.0.0", 2177 | "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", 2178 | "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==", 2179 | "dev": true, 2180 | "license": "MIT", 2181 | "engines": { 2182 | "node": ">=0.10.0" 2183 | } 2184 | }, 2185 | "node_modules/supports-preserve-symlinks-flag": { 2186 | "version": "1.0.0", 2187 | "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", 2188 | "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", 2189 | "dev": true, 2190 | "license": "MIT", 2191 | "engines": { 2192 | "node": ">= 0.4" 2193 | }, 2194 | "funding": { 2195 | "url": "https://github.com/sponsors/ljharb" 2196 | } 2197 | }, 2198 | "node_modules/to-regex-range": { 2199 | "version": "5.0.1", 2200 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 2201 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 2202 | "dev": true, 2203 | "license": "MIT", 2204 | "dependencies": { 2205 | "is-number": "^7.0.0" 2206 | }, 2207 | "engines": { 2208 | "node": ">=8.0" 2209 | } 2210 | }, 2211 | "node_modules/toidentifier": { 2212 | "version": "1.0.1", 2213 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 2214 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", 2215 | "license": "MIT", 2216 | "engines": { 2217 | "node": ">=0.6" 2218 | } 2219 | }, 2220 | "node_modules/tsx": { 2221 | "version": "4.19.4", 2222 | "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.4.tgz", 2223 | "integrity": "sha512-gK5GVzDkJK1SI1zwHf32Mqxf2tSJkNx+eYcNly5+nHvWqXUJYUkWBQtKauoESz3ymezAI++ZwT855x5p5eop+Q==", 2224 | "dev": true, 2225 | "license": "MIT", 2226 | "dependencies": { 2227 | "esbuild": "~0.25.0", 2228 | "get-tsconfig": "^4.7.5" 2229 | }, 2230 | "bin": { 2231 | "tsx": "dist/cli.mjs" 2232 | }, 2233 | "engines": { 2234 | "node": ">=18.0.0" 2235 | }, 2236 | "optionalDependencies": { 2237 | "fsevents": "~2.3.3" 2238 | } 2239 | }, 2240 | "node_modules/type-is": { 2241 | "version": "2.0.1", 2242 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", 2243 | "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", 2244 | "license": "MIT", 2245 | "dependencies": { 2246 | "content-type": "^1.0.5", 2247 | "media-typer": "^1.1.0", 2248 | "mime-types": "^3.0.0" 2249 | }, 2250 | "engines": { 2251 | "node": ">= 0.6" 2252 | } 2253 | }, 2254 | "node_modules/typescript": { 2255 | "version": "5.8.3", 2256 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", 2257 | "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", 2258 | "dev": true, 2259 | "license": "Apache-2.0", 2260 | "bin": { 2261 | "tsc": "bin/tsc", 2262 | "tsserver": "bin/tsserver" 2263 | }, 2264 | "engines": { 2265 | "node": ">=14.17" 2266 | } 2267 | }, 2268 | "node_modules/undici-types": { 2269 | "version": "6.21.0", 2270 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", 2271 | "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", 2272 | "license": "MIT" 2273 | }, 2274 | "node_modules/unpipe": { 2275 | "version": "1.0.0", 2276 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 2277 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", 2278 | "license": "MIT", 2279 | "engines": { 2280 | "node": ">= 0.8" 2281 | } 2282 | }, 2283 | "node_modules/uri-js": { 2284 | "version": "4.4.1", 2285 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", 2286 | "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", 2287 | "license": "BSD-2-Clause", 2288 | "dependencies": { 2289 | "punycode": "^2.1.0" 2290 | } 2291 | }, 2292 | "node_modules/vary": { 2293 | "version": "1.1.2", 2294 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 2295 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", 2296 | "license": "MIT", 2297 | "engines": { 2298 | "node": ">= 0.8" 2299 | } 2300 | }, 2301 | "node_modules/which": { 2302 | "version": "2.0.2", 2303 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 2304 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 2305 | "license": "ISC", 2306 | "dependencies": { 2307 | "isexe": "^2.0.0" 2308 | }, 2309 | "bin": { 2310 | "node-which": "bin/node-which" 2311 | }, 2312 | "engines": { 2313 | "node": ">= 8" 2314 | } 2315 | }, 2316 | "node_modules/wrappy": { 2317 | "version": "1.0.2", 2318 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 2319 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", 2320 | "license": "ISC" 2321 | }, 2322 | "node_modules/zod": { 2323 | "version": "3.25.56", 2324 | "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.56.tgz", 2325 | "integrity": "sha512-rd6eEF3BTNvQnR2e2wwolfTmUTnp70aUTqr0oaGbHifzC3BKJsoV+Gat8vxUMR1hwOKBs6El+qWehrHbCpW6SQ==", 2326 | "license": "MIT", 2327 | "funding": { 2328 | "url": "https://github.com/sponsors/colinhacks" 2329 | } 2330 | }, 2331 | "node_modules/zod-to-json-schema": { 2332 | "version": "3.24.5", 2333 | "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.5.tgz", 2334 | "integrity": "sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g==", 2335 | "license": "ISC", 2336 | "peerDependencies": { 2337 | "zod": "^3.24.1" 2338 | } 2339 | } 2340 | } 2341 | } 2342 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@line/line-bot-mcp-server", 3 | "version": "0.0.1-local", 4 | "description": "MCP server for interacting with your LINE Official Account", 5 | "type": "module", 6 | "engines": { 7 | "node": ">=20" 8 | }, 9 | "module": "./dist/index.js", 10 | "bin": { 11 | "line-bot-mcp-server": "./dist/index.js" 12 | }, 13 | "files": [ 14 | "dist" 15 | ], 16 | "scripts": { 17 | "build": "tsc && shx chmod +x dist/*.js", 18 | "prettier": "prettier \"src/**/*.ts\"", 19 | "format": "npm run prettier -- --write", 20 | "format:check": "npm run prettier -- -l", 21 | "clean": "rm -rf dist/*", 22 | "prebuild": "npm run format:check && npm run clean", 23 | "release": "npm run build && npm publish --provenance --access public" 24 | }, 25 | "repository": { 26 | "type": "git", 27 | "url": "git@github.com:line/line-bot-mcp-server.git" 28 | }, 29 | "keywords": [ 30 | "line", 31 | "bot", 32 | "mcp" 33 | ], 34 | "homepage": "https://github.com/line/line-bot-mcp-server", 35 | "bugs": "https://github.com/line/line-bot-mcp-server/issues", 36 | "dependencies": { 37 | "@line/bot-sdk": "^10.0.0", 38 | "@modelcontextprotocol/sdk": "^1.8.0", 39 | "zod": "^3.24.2" 40 | }, 41 | "devDependencies": { 42 | "@types/node": "^22", 43 | "prettier": "3.5.3", 44 | "shx": "^0.4.0", 45 | "tsx": "^4.19.3", 46 | "typescript": "^5.6.2" 47 | }, 48 | "license": "Apache-2.0", 49 | "packageManager": "pnpm@10.11.1+sha512.e519b9f7639869dc8d5c3c5dfef73b3f091094b0a006d7317353c72b124e80e1afd429732e28705ad6bfa1ee879c1fce46c128ccebd3192101f43dd67c667912" 50 | } 51 | -------------------------------------------------------------------------------- /renovate.json5: -------------------------------------------------------------------------------- 1 | { 2 | $schema: "https://docs.renovatebot.com/renovate-schema.json", 3 | extends: [ 4 | "config:recommended", 5 | "helpers:pinGitHubActionDigestsToSemver" 6 | ], 7 | timezone: "Asia/Tokyo", 8 | automerge: true, 9 | platformAutomerge: true, 10 | labels: [ 11 | "dependency upgrade" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /** 4 | * Copyright 2025 LY Corporation 5 | * 6 | * LINE Corporation licenses this file to you under the Apache License, 7 | * version 2.0 (the "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at: 9 | * 10 | * https://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 14 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 15 | * License for the specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; 20 | import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; 21 | import * as line from "@line/bot-sdk"; 22 | import { z } from "zod"; 23 | import { LINE_BOT_MCP_SERVER_VERSION, USER_AGENT } from "./version.js"; 24 | 25 | const NO_USER_ID_ERROR = 26 | "Error: Specify the userId or set the DESTINATION_USER_ID in the environment variables of this MCP Server."; 27 | 28 | const server = new McpServer({ 29 | name: "line-bot", 30 | version: LINE_BOT_MCP_SERVER_VERSION, 31 | }); 32 | 33 | const channelAccessToken = process.env.CHANNEL_ACCESS_TOKEN || ""; 34 | const destinationId = process.env.DESTINATION_USER_ID || ""; 35 | 36 | const messagingApiClient = new line.messagingApi.MessagingApiClient({ 37 | channelAccessToken: channelAccessToken, 38 | defaultHeaders: { 39 | "User-Agent": USER_AGENT, 40 | }, 41 | }); 42 | 43 | function createErrorResponse(message: string) { 44 | return { 45 | isError: true, 46 | content: [ 47 | { 48 | type: "text" as const, 49 | text: message, 50 | }, 51 | ], 52 | }; 53 | } 54 | 55 | function createSuccessResponse(response: object) { 56 | return { 57 | content: [ 58 | { 59 | type: "text" as const, 60 | text: JSON.stringify(response), 61 | }, 62 | ], 63 | }; 64 | } 65 | 66 | const userIdSchema = z 67 | .string() 68 | .default(destinationId) 69 | .describe( 70 | "The user ID to receive a message. Defaults to DESTINATION_USER_ID.", 71 | ); 72 | 73 | const textMessageSchema = z.object({ 74 | type: z.literal("text").default("text"), 75 | text: z 76 | .string() 77 | .max(5000) 78 | .describe("The plain text content to send to the user."), 79 | }); 80 | 81 | const flexMessageSchema = z.object({ 82 | type: z.literal("flex").default("flex"), 83 | altText: z 84 | .string() 85 | .describe("Alternative text shown when flex message cannot be displayed."), 86 | contents: z 87 | .object({ 88 | type: z 89 | .enum(["bubble", "carousel"]) 90 | .describe( 91 | "Type of the container. 'bubble' for single container, 'carousel' for multiple swipeable bubbles.", 92 | ), 93 | }) 94 | .passthrough() 95 | .describe( 96 | "Flexible container structure following LINE Flex Message format. For 'bubble' type, can include header, " + 97 | "hero, body, footer, and styles sections. For 'carousel' type, includes an array of bubble containers in " + 98 | "the 'contents' property.", 99 | ), 100 | }); 101 | 102 | server.tool( 103 | "push_text_message", 104 | "Push a simple text message to a user via LINE. Use this for sending plain text messages without formatting.", 105 | { 106 | userId: userIdSchema, 107 | message: textMessageSchema, 108 | }, 109 | async ({ userId, message }) => { 110 | if (!userId) { 111 | return createErrorResponse(NO_USER_ID_ERROR); 112 | } 113 | 114 | try { 115 | const response = await messagingApiClient.pushMessage({ 116 | to: userId, 117 | messages: [message as unknown as line.messagingApi.Message], 118 | }); 119 | return createSuccessResponse(response); 120 | } catch (error) { 121 | return createErrorResponse(`Failed to push message: ${error.message}`); 122 | } 123 | }, 124 | ); 125 | 126 | server.tool( 127 | "push_flex_message", 128 | "Push a highly customizable flex message to a user via LINE. Supports both bubble (single container) and carousel " + 129 | "(multiple swipeable bubbles) layouts.", 130 | { 131 | userId: userIdSchema, 132 | message: flexMessageSchema, 133 | }, 134 | async ({ userId, message }) => { 135 | if (!userId) { 136 | return createErrorResponse(NO_USER_ID_ERROR); 137 | } 138 | 139 | try { 140 | const response = await messagingApiClient.pushMessage({ 141 | to: userId, 142 | messages: [message as unknown as line.messagingApi.Message], 143 | }); 144 | return createSuccessResponse(response); 145 | } catch (error) { 146 | return createErrorResponse( 147 | `Failed to push flex message: ${error.message}`, 148 | ); 149 | } 150 | }, 151 | ); 152 | 153 | server.tool( 154 | "broadcast_text_message", 155 | "Broadcast a simple text message via LINE to all users who have followed your LINE Official Account. Use this for sending " + 156 | "plain text messages without formatting. Please be aware that this message will be sent to all users.", 157 | { 158 | message: textMessageSchema, 159 | }, 160 | async ({ message }) => { 161 | try { 162 | const response = await messagingApiClient.broadcast({ 163 | messages: [message as unknown as line.messagingApi.Message], 164 | }); 165 | return createSuccessResponse(response); 166 | } catch (error) { 167 | return createErrorResponse( 168 | `Failed to broadcast message: ${error.message}`, 169 | ); 170 | } 171 | }, 172 | ); 173 | 174 | server.tool( 175 | "broadcast_flex_message", 176 | "Broadcast a highly customizable flex message via LINE to all users who have added your LINE Official Account. " + 177 | "Supports both bubble (single container) and carousel (multiple swipeable bubbles) layouts. Please be aware that " + 178 | "this message will be sent to all users.", 179 | { 180 | message: flexMessageSchema, 181 | }, 182 | async ({ message }) => { 183 | try { 184 | const response = await messagingApiClient.broadcast({ 185 | messages: [message as unknown as line.messagingApi.Message], 186 | }); 187 | return createSuccessResponse(response); 188 | } catch (error) { 189 | return createErrorResponse( 190 | `Failed to broadcast message: ${error.message}`, 191 | ); 192 | } 193 | }, 194 | ); 195 | 196 | server.tool( 197 | "get_profile", 198 | "Get detailed profile information of a LINE user including display name, profile picture URL, status message and language.", 199 | { 200 | userId: userIdSchema, 201 | }, 202 | async ({ userId }) => { 203 | if (!userId) { 204 | return createErrorResponse(NO_USER_ID_ERROR); 205 | } 206 | 207 | try { 208 | const response = await messagingApiClient.getProfile(userId); 209 | return createSuccessResponse(response); 210 | } catch (error) { 211 | return createErrorResponse(`Failed to get profile: ${error.message}`); 212 | } 213 | }, 214 | ); 215 | 216 | server.tool( 217 | "get_message_quota", 218 | "Get the message quota and consumption of the LINE Official Account. This shows the monthly message limit and current usage.", 219 | {}, 220 | async () => { 221 | const messageQuotaResponse = await messagingApiClient.getMessageQuota(); 222 | const messageQuotaConsumptionResponse = 223 | await messagingApiClient.getMessageQuotaConsumption(); 224 | const response = { 225 | limited: messageQuotaResponse.value, 226 | totalUsage: messageQuotaConsumptionResponse.totalUsage, 227 | }; 228 | return createSuccessResponse(response); 229 | }, 230 | ); 231 | 232 | async function main() { 233 | if (!process.env.CHANNEL_ACCESS_TOKEN) { 234 | console.error("Please set CHANNEL_ACCESS_TOKEN"); 235 | process.exit(1); 236 | } 237 | 238 | const transport = new StdioServerTransport(); 239 | await server.connect(transport); 240 | } 241 | 242 | main().catch(error => { 243 | console.error("Fatal error in main():", error); 244 | process.exit(1); 245 | }); 246 | -------------------------------------------------------------------------------- /src/version.ts: -------------------------------------------------------------------------------- 1 | export const LINE_BOT_MCP_SERVER_VERSION = "0.1.0-local"; 2 | export const USER_AGENT = `@line/line-bot-mcp-server/${LINE_BOT_MCP_SERVER_VERSION}`; 3 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "ESNext", 4 | "moduleResolution": "Bundler", 5 | "target": "ES2022", 6 | "esModuleInterop": true, 7 | "noImplicitAny": true, 8 | "newLine": "LF", 9 | "sourceMap": true, 10 | "declarationMap": true, 11 | "outDir": "dist", 12 | "rootDir": "src", 13 | "declaration": true, 14 | }, 15 | "exclude": [ 16 | "node_modules", 17 | "dist", 18 | ".git" 19 | ], 20 | } 21 | --------------------------------------------------------------------------------