# Directory Structure
```
├── .changeset
│ ├── config.json
│ └── update-tyme4ts.md
├── .github
│ └── workflows
│ ├── release.yml
│ └── update-tyme4ts.yml
├── .gitignore
├── .nvmrc
├── biome.json
├── CHANGELOG.md
├── Dockerfile
├── icon.svg
├── LICENSE
├── package.json
├── pnpm-lock.yaml
├── README.en.md
├── README.md
├── rslib.config.ts
├── smithery.yaml
├── src
│ ├── almanac.ts
│ ├── index.ts
│ ├── server.ts
│ ├── types.ts
│ └── utils.ts
├── tests
│ ├── index.test.ts
│ └── tsconfig.json
├── tsconfig.json
└── vitest.config.ts
```
# Files
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
```
1 | 18
```
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
```
1 | # Local
2 | .DS_Store
3 | *.local
4 | *.log*
5 |
6 | # Dist
7 | node_modules
8 | dist/
9 |
10 | # IDE
11 | .vscode/*
12 | !.vscode/extensions.json
13 | .idea
14 |
```
--------------------------------------------------------------------------------
/README.en.md:
--------------------------------------------------------------------------------
```markdown
1 | # Tung Shing MCP Server
2 |
3 | [](https://smithery.ai/server/@baranwang/mcp-tung-shing)
4 | [](https://www.npmjs.com/package/mcp-tung-shing)
5 | [](https://github.com/baranwang/mcp-tung-shing/blob/main/LICENSE)
6 |
7 | [中文文档](./README.md) | English
8 |
9 | > Chinese Traditional Almanac calculation service based on Model Context Protocol (MCP)
10 |
11 | ## ✨ Features
12 |
13 | - 📅 **Calendar Conversion** - Convert between Gregorian and Chinese lunar calendar
14 | - 🍀 **Daily Guidance** - Detailed information on recommended and avoided activities for each day
15 | - 🕐 **Time Periods** - Fortune information for the twelve traditional Chinese time periods
16 | - 🔮 **Metaphysical Elements** - Detailed data on five elements, deities, star constellations and other traditional metaphysical information
17 |
18 | ## 🚀 Installation & Usage
19 |
20 | Add the following to your MCP configuration file:
21 |
22 | ```json
23 | {
24 | "mcpServers": {
25 | "tung-shing": {
26 | "command": "npx",
27 | "args": [
28 | "-y",
29 | "mcp-tung-shing@latest"
30 | ]
31 | }
32 | }
33 | }
34 | ```
35 |
36 | ## ⚙️ Tools
37 |
38 | ### get-tung-shing
39 |
40 | Get almanac information for specified date(s)
41 |
42 | **Parameters:**
43 |
44 | | Parameter | Type | Required | Default | Description |
45 | |-----------|------|----------|---------|-------------|
46 | | `startDate` | String | No | Today | Start date, format: "YYYY-MM-DD" |
47 | | `days` | Number | No | 1 | Number of days to retrieve |
48 | | `includeHours` | Boolean | No | false | Whether to include hourly information |
49 | | `tabooFilters` | Array | No | - | Filter for recommended and avoided activities, conditions are in OR relationship |
50 | | `tabooFilters[].type` | 1 \| 2 | Yes | - | Filter type: recommends(1), avoids(2) |
51 | | `tabooFilters[].value` | String | Yes | - | The activity to filter |
52 |
53 | ## 🤝 Contributing
54 |
55 | Issues and Pull Requests are welcome to improve this project.
56 |
```
--------------------------------------------------------------------------------
/.changeset/update-tyme4ts.md:
--------------------------------------------------------------------------------
```markdown
1 | ---
2 | "mcp-tung-shing": patch
3 | ---
4 |
5 | bump tyme4ts version to 1.3.4
6 |
```
--------------------------------------------------------------------------------
/tests/tsconfig.json:
--------------------------------------------------------------------------------
```json
1 | {
2 | "extends": "../tsconfig.json",
3 | "include": [".", "../vitest.setup.ts"]
4 | }
5 |
```
--------------------------------------------------------------------------------
/vitest.config.ts:
--------------------------------------------------------------------------------
```typescript
1 | import { defineConfig } from 'vitest/config';
2 |
3 | export default defineConfig({
4 | // Configure Vitest (https://vitest.dev/config/)
5 | test: {},
6 | });
7 |
```
--------------------------------------------------------------------------------
/.changeset/config.json:
--------------------------------------------------------------------------------
```json
1 | {
2 | "$schema": "https://unpkg.com/@changesets/[email protected]/schema.json",
3 | "changelog": "@changesets/cli/changelog",
4 | "commit": false,
5 | "fixed": [],
6 | "linked": [],
7 | "access": "public",
8 | "baseBranch": "main",
9 | "updateInternalDependencies": "patch",
10 | "ignore": []
11 | }
12 |
```
--------------------------------------------------------------------------------
/smithery.yaml:
--------------------------------------------------------------------------------
```yaml
1 | # Smithery configuration file: https://smithery.ai/docs/config#smitheryyaml
2 | startCommand:
3 | type: stdio
4 | configSchema:
5 | {}
6 | commandFunction:
7 | # A JS function that produces the CLI command based on the given config to start the MCP on stdio.
8 | |-
9 | (config) => ({
10 | command: 'node',
11 | args: ['dist/index.cjs'],
12 | })
13 |
```
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
```json
1 | {
2 | "compilerOptions": {
3 | "lib": ["ES2021"],
4 | "module": "ESNext",
5 | "noEmit": true,
6 | "strict": true,
7 | "skipLibCheck": true,
8 | "isolatedModules": true,
9 | "resolveJsonModule": true,
10 | "moduleResolution": "bundler",
11 | "useDefineForClassFields": true,
12 | "allowImportingTsExtensions": true
13 | },
14 | "include": ["src"]
15 | }
16 |
```
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
```dockerfile
1 | FROM node:18-alpine as builder
2 |
3 | WORKDIR /app
4 |
5 | RUN npm install -g pnpm
6 |
7 | COPY package.json pnpm-lock.yaml ./
8 |
9 | RUN pnpm install --frozen-lockfile
10 |
11 | COPY . .
12 |
13 | RUN pnpm run build
14 |
15 |
16 | FROM node:18-alpine as runner
17 |
18 | WORKDIR /app
19 |
20 | COPY --from=builder /app/dist ./dist
21 | COPY --from=builder /app/package.json ./package.json
22 |
23 | CMD ["node", "dist/index.cjs"]
24 |
```
--------------------------------------------------------------------------------
/rslib.config.ts:
--------------------------------------------------------------------------------
```typescript
1 | import { defineConfig } from '@rslib/core';
2 | import { version } from "./package.json";
3 |
4 | export default defineConfig({
5 | lib: [
6 | {
7 | format: 'esm',
8 | syntax: 'es2021',
9 | dts: true,
10 | },
11 | {
12 | format: 'cjs',
13 | syntax: 'es2021',
14 | },
15 | ],
16 | source: {
17 | define: {
18 | 'process.env.PACKAGE_VERSION': JSON.stringify(version),
19 | }
20 | }
21 | });
22 |
```
--------------------------------------------------------------------------------
/biome.json:
--------------------------------------------------------------------------------
```json
1 | {
2 | "$schema": "https://biomejs.dev/schemas/1.8.0/schema.json",
3 | "organizeImports": {
4 | "enabled": true
5 | },
6 | "vcs": {
7 | "enabled": true,
8 | "clientKind": "git",
9 | "useIgnoreFile": true
10 | },
11 | "formatter": {
12 | "indentStyle": "space"
13 | },
14 | "javascript": {
15 | "formatter": {
16 | "quoteStyle": "single"
17 | }
18 | },
19 | "css": {
20 | "parser": {
21 | "cssModules": true
22 | }
23 | },
24 | "linter": {
25 | "enabled": true,
26 | "rules": {
27 | "recommended": true
28 | }
29 | }
30 | }
31 |
```
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
```typescript
1 | #!/usr/bin/env node
2 |
3 | import dayjs from 'dayjs';
4 | import { PluginLunar } from 'dayjs-plugin-lunar';
5 | import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
6 | import { createServer } from './server';
7 |
8 | // 初始化日期插件
9 | dayjs.extend(PluginLunar);
10 |
11 | // 启动服务器
12 | (async () => {
13 | try {
14 | const server = createServer();
15 | const transport = new StdioServerTransport();
16 | await server.connect(transport);
17 | console.error('Tung Shing MCP server started');
18 | } catch (error) {
19 | console.error('Failed to start Tung Shing MCP server:', error);
20 | process.exit(1);
21 | }
22 | })();
23 |
```
--------------------------------------------------------------------------------
/tests/index.test.ts:
--------------------------------------------------------------------------------
```typescript
1 | import { Client } from '@modelcontextprotocol/sdk/client/index.js';
2 | import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
3 | import { beforeAll, expect, test } from 'vitest';
4 |
5 | const transport = new StdioClientTransport({
6 | command: "node",
7 | args: ["."]
8 | });
9 |
10 | const client = new Client({
11 | name: 'test-client',
12 | version: '0.0.0',
13 | });
14 |
15 | beforeAll(async () => {
16 | await client.connect(transport);
17 | });
18 |
19 | test('get-tung-shing', async () => {
20 | const resp = await client.callTool({
21 | name: 'get-tung-shing',
22 | arguments: {
23 | startDate: '2025-01-21'
24 | }
25 | })
26 |
27 | expect(resp.content).toBeInstanceOf(Array);
28 | });
29 |
```
--------------------------------------------------------------------------------
/icon.svg:
--------------------------------------------------------------------------------
```
1 | <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
2 | <g transform="translate(256, 256)">
3 | <g>
4 | <path d="M0,-220 A220,220 0 0,1 0,220 A110,110 0 0,0 0,0 A110,110 0 0,1 0,-220" fill="#111" />
5 | <path d="M0,220 A220,220 0 0,1 0,-220 A110,110 0 0,0 0,0 A110,110 0 0,1 0,220" fill="#fff" />
6 |
7 | <circle cx="0" cy="-110" r="35" fill="#fff" />
8 | <circle cx="0" cy="110" r="35" fill="#111" />
9 |
10 | <animateTransform
11 | attributeName="transform"
12 | attributeType="XML"
13 | type="rotate"
14 | from="0"
15 | to="360"
16 | dur="24s"
17 | repeatCount="indefinite"
18 | />
19 | </g>
20 | </g>
21 | </svg>
22 |
```
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
```yaml
1 | name: Release
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 |
8 | jobs:
9 | release:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - uses: actions/checkout@v4
13 | with:
14 | fetch-depth: 0
15 |
16 | - uses: pnpm/action-setup@v4
17 |
18 | - uses: actions/setup-node@v4
19 | with:
20 | node-version-file: .nvmrc
21 | cache: pnpm
22 |
23 | - run: pnpm install
24 |
25 | - uses: changesets/action@v1
26 | id: changesets
27 | with:
28 | publish: pnpm run release
29 | title: "chore: version packages"
30 | commit: "chore: version packages"
31 | env:
32 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
33 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
```
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
```json
1 | {
2 | "name": "mcp-tung-shing",
3 | "version": "1.7.1",
4 | "description": "A Model Context Protocol plugin for Chinese Tung Shing (黄历/通勝/通胜) almanac calculations",
5 | "type": "module",
6 | "exports": {
7 | ".": {
8 | "types": "./dist/index.d.ts",
9 | "import": "./dist/index.js",
10 | "require": "./dist/index.cjs"
11 | }
12 | },
13 | "main": "./dist/index.cjs",
14 | "module": "./dist/index.js",
15 | "types": "./dist/index.d.ts",
16 | "bin": {
17 | "mcp-tung-shing": "./dist/index.cjs"
18 | },
19 | "files": [
20 | "dist"
21 | ],
22 | "keywords": [
23 | "mcp",
24 | "tung shing",
25 | "almanac",
26 | "calendar",
27 | "lunar",
28 | "chinese"
29 | ],
30 | "repository": {
31 | "type": "git",
32 | "url": "https://github.com/baranwang/mcp-tung-shing"
33 | },
34 | "bugs": {
35 | "url": "https://github.com/baranwang/mcp-tung-shing/issues"
36 | },
37 | "license": "MIT",
38 | "scripts": {
39 | "build": "rslib build",
40 | "check": "biome check --write",
41 | "dev": "rslib build --watch",
42 | "format": "biome format --write",
43 | "inspect": "mcp-inspector",
44 | "pretest": "rslib build",
45 | "test": "vitest run",
46 | "prerelease": "npm run build",
47 | "release": "changeset publish"
48 | },
49 | "dependencies": {
50 | "@modelcontextprotocol/sdk": "^1.7.0",
51 | "dayjs": "^1.11.13",
52 | "dayjs-plugin-lunar": "^1.4.0",
53 | "tyme4ts": "1.3.4",
54 | "zod": "^3.24.1",
55 | "zod-to-json-schema": "^3.24.1"
56 | },
57 | "devDependencies": {
58 | "@biomejs/biome": "1.9.2",
59 | "@changesets/cli": "^2.28.1",
60 | "@modelcontextprotocol/inspector": "^0.8.0",
61 | "@rslib/core": "^0.5.4",
62 | "@types/node": "^22.8.1",
63 | "typescript": "^5.7.3",
64 | "vitest": "^3.0.1"
65 | },
66 | "packageManager": "[email protected]"
67 | }
68 |
```
--------------------------------------------------------------------------------
/.github/workflows/update-tyme4ts.yml:
--------------------------------------------------------------------------------
```yaml
1 | name: Update tyme4ts
2 |
3 | on:
4 | schedule:
5 | - cron: '0 0 * * 1'
6 | workflow_dispatch:
7 |
8 | jobs:
9 | update-dependency:
10 | runs-on: ubuntu-latest
11 | permissions:
12 | contents: write
13 | steps:
14 | - uses: actions/checkout@v4
15 | with:
16 | fetch-depth: 0
17 |
18 | - uses: pnpm/action-setup@v4
19 |
20 | - uses: actions/setup-node@v4
21 | with:
22 | node-version-file: .nvmrc
23 | cache: pnpm
24 |
25 | - run: pnpm install
26 |
27 | - name: Check tyme4ts version
28 | id: check-version
29 | run: |
30 | # 获取当前依赖的版本
31 | CURRENT_VERSION=$(node -p "require('./package.json').dependencies.tyme4ts.replace('^', '')")
32 | echo "current_version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
33 |
34 | # 获取最新版本
35 | LATEST_VERSION=$(npm view tyme4ts version)
36 | echo "latest_version=$LATEST_VERSION" >> $GITHUB_OUTPUT
37 |
38 | # 比较版本
39 | if [ "$CURRENT_VERSION" != "$LATEST_VERSION" ]; then
40 | echo "needs_update=true" >> $GITHUB_OUTPUT
41 | else
42 | echo "needs_update=false" >> $GITHUB_OUTPUT
43 | fi
44 |
45 | - name: Update tyme4ts
46 | if: steps.check-version.outputs.needs_update == 'true'
47 | run: |
48 | # 更新依赖版本
49 | pnpm add tyme4ts@${{ steps.check-version.outputs.latest_version }}
50 |
51 | # 创建 changeset
52 | cat << EOF > .changeset/update-tyme4ts.md
53 | ---
54 | "mcp-tung-shing": patch
55 | ---
56 |
57 | bump tyme4ts version to ${{ steps.check-version.outputs.latest_version }}
58 | EOF
59 |
60 | - name: Commit and push changes
61 | if: steps.check-version.outputs.needs_update == 'true'
62 | run: |
63 | git config --global user.name "github-actions[bot]"
64 | git config --global user.email "github-actions[bot]@users.noreply.github.com"
65 | git add package.json pnpm-lock.yaml .changeset/
66 | git commit -m "chore: bump tyme4ts version to ${{ steps.check-version.outputs.latest_version }}"
67 | git push origin main
68 | env:
69 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```
--------------------------------------------------------------------------------
/src/almanac.ts:
--------------------------------------------------------------------------------
```typescript
1 | import dayjs from 'dayjs';
2 | import { PluginLunar } from 'dayjs-plugin-lunar';
3 | import type { AlmanacContentItem, DailyAlmanac } from './types';
4 | import { ContentType } from './types';
5 | import { handleDirection } from './utils';
6 | import 'dayjs/locale/zh-cn.js';
7 |
8 | dayjs.extend(PluginLunar);
9 |
10 | /**
11 | * 获取时辰黄历信息
12 | */
13 | export function getHourlyAlmanac(date: dayjs.Dayjs): AlmanacContentItem {
14 | const lunarHour = date.toLunarHour();
15 | const sixtyCycle = lunarHour.getSixtyCycle();
16 | const heavenStem = sixtyCycle.getHeavenStem();
17 | const earthBranch = sixtyCycle.getEarthBranch();
18 |
19 | return {
20 | [ContentType.宜]: lunarHour.getRecommends().map((item) => item.getName()),
21 | [ContentType.忌]: lunarHour.getAvoids().map((item) => item.getName()),
22 | [ContentType.吉凶]: lunarHour
23 | .getTwelveStar()
24 | .getEcliptic()
25 | .getLuck()
26 | .toString(),
27 | [ContentType.值神]: lunarHour.getTwelveStar().toString(),
28 | [ContentType.五行]: sixtyCycle.getSound().toString(),
29 | [ContentType.冲煞]: `冲${earthBranch.getOpposite().getZodiac()}煞${earthBranch.getOminous()}`,
30 | [ContentType.方位]: [
31 | `喜神${handleDirection(heavenStem.getJoyDirection().toString())}`,
32 | `财神${handleDirection(heavenStem.getWealthDirection().toString())}`,
33 | `福神${handleDirection(heavenStem.getMascotDirection().toString())}`,
34 | ],
35 | };
36 | }
37 |
38 | /**
39 | * 获取每日黄历信息
40 | */
41 | export function getDailyAlmanac(
42 | date: dayjs.Dayjs,
43 | includeHours = false,
44 | ): DailyAlmanac {
45 | const parsedDate = dayjs(date);
46 | if (!parsedDate.isValid()) {
47 | throw new Error('Invalid date');
48 | }
49 |
50 | const lunarDay = parsedDate.toLunarDay();
51 | const solarDay = lunarDay.getSolarDay();
52 | const sixtyCycle = lunarDay.getSixtyCycle();
53 | const earthBranch = sixtyCycle.getEarthBranch();
54 | const twentyEightStar = lunarDay.getTwentyEightStar();
55 | const gods = lunarDay.getGods().reduce(
56 | (acc, god) => {
57 | const category =
58 | god.getLuck().getName() === '吉' ? 'auspicious' : 'inauspicious';
59 | acc[category].push(god.getName());
60 | return acc;
61 | },
62 | { auspicious: [] as string[], inauspicious: [] as string[] },
63 | );
64 |
65 | const result: DailyAlmanac = {
66 | 公历: parsedDate.locale('zh-cn').format('YYYY 年 M 月 D日(ddd)'),
67 | 农历: parsedDate.format('LY年LMLD'),
68 | 节日: lunarDay.getFestival()?.getName(),
69 | 节气: solarDay.getTermDay().toString(),
70 | 七十二候: solarDay.getPhenologyDay().toString(),
71 | 当日: {
72 | [ContentType.宜]: lunarDay.getRecommends().map((item) => item.getName()),
73 | [ContentType.忌]: lunarDay.getAvoids().map((item) => item.getName()),
74 | [ContentType.吉凶]: lunarDay
75 | .getTwelveStar()
76 | .getEcliptic()
77 | .getLuck()
78 | .toString(),
79 | [ContentType.五行]: sixtyCycle.getSound().toString(),
80 | [ContentType.冲煞]: `冲${earthBranch.getOpposite().getZodiac()}煞${earthBranch.getOminous()}`,
81 | [ContentType.值神]: lunarDay.getTwelveStar().toString(),
82 | [ContentType.建除十二神]: lunarDay.getDuty().toString(),
83 | [ContentType.二十八星宿]: `${twentyEightStar}${twentyEightStar.getSevenStar()}${twentyEightStar.getAnimal()}(${twentyEightStar.getLuck()})`,
84 | [ContentType.吉神宜趋]: gods.auspicious,
85 | [ContentType.凶煞宜忌]: gods.inauspicious,
86 | [ContentType.彭祖百忌]: `${sixtyCycle.getHeavenStem().getPengZuHeavenStem()} ${earthBranch.getPengZuEarthBranch()}`,
87 | },
88 | };
89 |
90 | if (includeHours) {
91 | result.分时 = {};
92 | for (let i = 0; i < 12; i++) {
93 | const hour = parsedDate.addLunar(i, 'dual-hour');
94 | result.分时[hour.format('LH')] = getHourlyAlmanac(hour);
95 | }
96 | }
97 |
98 | return result;
99 | }
100 |
```
--------------------------------------------------------------------------------
/src/server.ts:
--------------------------------------------------------------------------------
```typescript
1 | import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2 | import {
3 | CallToolRequestSchema,
4 | GetPromptRequestSchema,
5 | ListPromptsRequestSchema,
6 | ListToolsRequestSchema,
7 | } from '@modelcontextprotocol/sdk/types.js';
8 | import dayjs from 'dayjs';
9 | import { zodToJsonSchema } from 'zod-to-json-schema';
10 | import { getDailyAlmanac } from './almanac';
11 | import { ContentType, TabooType, getTungShingParamsSchema } from './types';
12 | import { getDayTabooNames } from './utils';
13 |
14 | /**
15 | * 创建并配置MCP服务器
16 | */
17 | export function createServer() {
18 | const mcpServer = new McpServer(
19 | {
20 | name: 'Tung Shing',
21 | version: process.env.PACKAGE_VERSION ?? '0.0.0',
22 | },
23 | {
24 | capabilities: {
25 | tools: {},
26 | prompts: {},
27 | },
28 | },
29 | );
30 |
31 | // 注册工具列表处理器
32 | mcpServer.server.setRequestHandler(ListToolsRequestSchema, () => ({
33 | tools: [
34 | {
35 | name: 'get-tung-shing',
36 | description: '获取通胜黄历,包括公历、农历、宜忌、吉凶、冲煞等信息',
37 | inputSchema: zodToJsonSchema(getTungShingParamsSchema),
38 | },
39 | ],
40 | }));
41 |
42 | // 注册工具调用处理器
43 | mcpServer.server.setRequestHandler(CallToolRequestSchema, async (request) => {
44 | switch (request.params.name) {
45 | case 'get-tung-shing': {
46 | const {
47 | startDate,
48 | days,
49 | includeHours,
50 | tabooFilters = [],
51 | } = getTungShingParamsSchema.parse(request.params.arguments);
52 | const start = dayjs(startDate);
53 | if (!start.isValid()) {
54 | return {
55 | content: [
56 | {
57 | type: 'text',
58 | text: 'Invalid date',
59 | },
60 | ],
61 | isError: true,
62 | };
63 | }
64 |
65 | return {
66 | content: Array.from({ length: days }, (_, i) => {
67 | const almanac = getDailyAlmanac(start.add(i, 'day'), includeHours);
68 |
69 | // 如果没有指定taboo过滤,直接返回结果
70 | if (!tabooFilters.length) {
71 | return {
72 | type: 'text',
73 | text: JSON.stringify(almanac),
74 | };
75 | }
76 |
77 | // 提取宜忌内容
78 | const recommends = (almanac.当日[ContentType.宜] as string[]) || [];
79 | const avoids = (almanac.当日[ContentType.忌] as string[]) || [];
80 |
81 | // 根据tabooFilters进行过滤,条件之间为或的关系
82 | const hasMatch = tabooFilters.some((filter) => {
83 | // 宜事项过滤
84 | if (filter.type === TabooType.宜) {
85 | return recommends.includes(filter.value);
86 | }
87 | // 忌事项过滤
88 | if (filter.type === TabooType.忌) {
89 | return avoids.includes(filter.value);
90 | }
91 | return false;
92 | });
93 |
94 | if (hasMatch) {
95 | return {
96 | type: 'text',
97 | text: JSON.stringify(almanac),
98 | };
99 | }
100 | return null;
101 | }).filter(Boolean),
102 | };
103 | }
104 | default: {
105 | return {
106 | content: [
107 | {
108 | type: 'text',
109 | text: `Unknown tool: ${request.params.name}`,
110 | },
111 | ],
112 | isError: true,
113 | };
114 | }
115 | }
116 | });
117 |
118 | mcpServer.server.setRequestHandler(ListPromptsRequestSchema, () => ({
119 | prompts: [
120 | {
121 | name: 'get-taboo',
122 | description: '获取宜忌事项类型',
123 | },
124 | ],
125 | }));
126 |
127 | mcpServer.server.setRequestHandler(GetPromptRequestSchema, (request) => {
128 | switch (request.params.name) {
129 | case 'get-taboo': {
130 | return {
131 | messages: [
132 | {
133 | role: 'assistant',
134 | content: {
135 | type: 'text',
136 | text: `宜忌事项类型清单\n${getDayTabooNames()
137 | .map((name) => `- ${name}`)
138 | .join('\n')}`,
139 | },
140 | },
141 | ],
142 | };
143 | }
144 | default: {
145 | return {
146 | messages: [],
147 | };
148 | }
149 | }
150 | });
151 |
152 | return mcpServer;
153 | }
154 |
```