diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 0a4275f..1bc1529 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -1,4 +1,4 @@ -name: Docker +name: Docker Publish # This workflow uses actions that are not certified by GitHub. # They are provided by a third-party and are governed by @@ -7,11 +7,8 @@ name: Docker on: push: - branches: ["master"] # Publish semver tags as releases. - tags: ["v*.*"] - pull_request: - branches: ["master"] + tags: ["v*.*.*"] env: # Use docker.io for Docker Hub if empty diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index 4742978..8e9e929 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -1,4 +1,4 @@ -name: Update Version and Publish +name: Npm Publish on: release: @@ -15,7 +15,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v3 with: - node-version: "18" + node-version: "22" registry-url: "https://registry.npmjs.org" - name: Install dependencies @@ -23,7 +23,7 @@ jobs: - name: Extract version from release id: extract_version - run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV + run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV - name: Update version.ts run: | diff --git a/README.md b/README.md index 14d72ca..d089e44 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,8 @@ Now you can date a Zoom meeting with AI's help ![about.jpg](about.jpg) +[![MseeP.ai Security Assessment Badge](https://mseep.net/pr/javaprogrammerlb-zoom-mcp-server-badge.png)](https://mseep.ai/app/javaprogrammerlb-zoom-mcp-server) + ## Usage ### 1. list meetings @@ -21,6 +23,14 @@ Now you can date a Zoom meeting with AI's help - `delete the latest meeting` - `delete the 86226580854 meeting` +### 4. get a meeting detail + +- `Retrieve the latest meeting's details` +- `Retrieve 86226580854 meeting's details` + +## Usage with VS Code + [![Install with NPX in VS Code](https://img.shields.io/badge/VS_Code-NPM-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=zoom-mcp-server&inputs=%5B%7B%22type%22%3A%22promptString%22%2C%22id%22%3A%22ZOOM_ACCOUNT_ID%22%7D%2C%20%7B%22type%22%3A%22promptString%22%2C%22id%22%3A%22ZOOM_CLIENT_ID%22%7D%2C%20%7B%22type%22%3A%22promptString%22%2C%22id%22%3A%22ZOOM_CLIENT_SECRET%22%7D%5D&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40yitianyigexiangfa%2Fzoom-mcp-server%40latest%22%5D%2C%22env%22%3A%7B%22ZOOM_ACCOUNT_ID%22%3A%22%24%7Binput%3AZOOM_ACCOUNT_ID%7D%22%2C%20%22ZOOM_CLIENT_ID%22%3A%22%24%7Binput%3AZOOM_CLIENT_ID%7D%22%2C%20%22ZOOM_CLIENT_SECRET%22%3A%22%24%7Binput%3AZOOM_CLIENT_SECRET%7D%22%7D%7D) + ## 2 Steps to play with zoom-mcp-server - Get Zoom Client ID, Zoom Client Secret and Account ID @@ -41,7 +51,7 @@ Now you can date a Zoom meeting with AI's help "mcpServers": { "zoom-mcp-server": { "command": "npx", - "args": ["-y", "@yitianyigexiangfa/zoom-mcp-server"], + "args": ["-y", "@yitianyigexiangfa/zoom-mcp-server@latest"], "env": { "ZOOM_ACCOUNT_ID": "${ZOOM_ACCOUNT_ID}", "ZOOM_CLIENT_ID": "${ZOOM_CLIENT_ID}", diff --git a/common/types.ts b/common/types.ts index fa47fc8..93c26fa 100644 --- a/common/types.ts +++ b/common/types.ts @@ -109,3 +109,172 @@ export const ZoomListMeetingsSchema = z.object({ }), ), }); + +export const ZoomMeetingDetailSchema = z.object({ + assistant_id: z.string().optional(), + host_email: z.string().optional(), + host_id: z.string().optional(), + id: z.number(), + uuid: z.string(), + agenda: z.string().optional(), + created_at: z.string().optional(), + duration: z.number().optional(), + encrypted_password: z.string().optional(), + pstn_password: z.string().optional(), + h323_password: z.string().optional(), + join_url: z.string().optional(), + chat_join_url: z.string().optional(), + occurrences: z + .array( + z.object({ + duration: z.number().optional(), + occurrence_id: z.string().optional(), + start_time: z.string().optional(), + status: z.string().optional(), + }), + ) + .optional(), + password: z.string().optional(), + pmi: z.string().optional(), + pre_schedule: z.boolean().optional(), + recurrence: z + .object({ + end_date_time: z.string().optional(), + end_times: z.number().optional(), + monthly_day: z.number().optional(), + monthly_week: z.number().optional(), + monthly_week_day: z.number().optional(), + repeat_interval: z.number().optional(), + type: z.number().optional(), + weekly_days: z.string().optional(), + }) + .optional(), + settings: ZoomMeetingSettingsSchema.extend({ + approved_or_denied_countries_or_regions: z + .object({ + approved_list: z.array(z.string()).optional(), + denied_list: z.array(z.string()).optional(), + enable: z.boolean().optional(), + method: z.string().optional(), + }) + .optional(), + authentication_exception: z + .array( + z.object({ + email: z.string().optional(), + name: z.string().optional(), + join_url: z.string().optional(), + }), + ) + .optional(), + breakout_room: z + .object({ + enable: z.boolean().optional(), + rooms: z + .array( + z.object({ + name: z.string().optional(), + participants: z.array(z.string()).optional(), + }), + ) + .optional(), + }) + .optional(), + global_dial_in_numbers: z + .array( + z.object({ + city: z.string().optional(), + country: z.string().optional(), + country_name: z.string().optional(), + number: z.string().optional(), + type: z.string().optional(), + }), + ) + .optional(), + language_interpretation: z + .object({ + enable: z.boolean().optional(), + interpreters: z + .array( + z.object({ + email: z.string().optional(), + languages: z.string().optional(), + interpreter_languages: z.string().optional(), + }), + ) + .optional(), + }) + .optional(), + sign_language_interpretation: z + .object({ + enable: z.boolean().optional(), + interpreters: z + .array( + z.object({ + email: z.string().optional(), + sign_language: z.string().optional(), + }), + ) + .optional(), + }) + .optional(), + meeting_invitees: z + .array( + z.object({ + email: z.string().optional(), + internal_user: z.boolean().optional(), + }), + ) + .optional(), + continuous_meeting_chat: z + .object({ + enable: z.boolean().optional(), + auto_add_invited_external_users: z.boolean().optional(), + auto_add_meeting_participants: z.boolean().optional(), + who_is_added: z.string().optional(), + channel_id: z.string().optional(), + }) + .optional(), + resources: z + .array( + z.object({ + resource_type: z.string().optional(), + resource_id: z.string().optional(), + permission_level: z.string().optional(), + }), + ) + .optional(), + question_and_answer: z + .object({ + enable: z.boolean().optional(), + allow_submit_questions: z.boolean().optional(), + allow_anonymous_questions: z.boolean().optional(), + question_visibility: z.string().optional(), + attendees_can_comment: z.boolean().optional(), + attendees_can_upvote: z.boolean().optional(), + }) + .optional(), + auto_start_meeting_summary: z.boolean().optional(), + who_will_receive_summary: z.number().optional(), + auto_start_ai_companion_questions: z.boolean().optional(), + who_can_ask_questions: z.number().optional(), + summary_template_id: z.string().optional(), + }).optional(), + start_time: z.string().optional(), + start_url: z.string().optional(), + status: z.string().optional(), + timezone: z.string().optional(), + topic: z.string().optional(), + tracking_fields: z + .array( + z.object({ + field: z.string().optional(), + value: z.string().optional(), + visible: z.boolean().optional(), + }), + ) + .optional(), + type: z.number().optional(), + dynamic_host_key: z.string().optional(), + creation_source: z.string().optional(), +}); diff --git a/common/version.ts b/common/version.ts index d64046b..ee51168 100644 --- a/common/version.ts +++ b/common/version.ts @@ -1 +1 @@ -export const VERSION = "0.6.5"; +export const VERSION = "0.7.4"; diff --git a/index.ts b/index.ts index a82b858..819cdcc 100644 --- a/index.ts +++ b/index.ts @@ -14,6 +14,8 @@ import { CreateMeetingOptionsSchema, deleteMeeting, DeleteMeetingOptionsSchema, + getAMeetingDetails, + GetMeetingOptionsSchema, ListMeetingOptionsSchema, listMeetings, } from "./operations/meeting.js"; @@ -37,6 +39,7 @@ enum PromptName { LIST_MEETINGS = "list_meetings", CREATE_A_MEETING = "create_meeting", DELETE_A_MEETING = "delete_a_meeting", + GET_A_MEETING_DETAILS = "get_a_meeting_details", } server.setRequestHandler(ListPromptsRequestSchema, async () => { @@ -54,6 +57,10 @@ server.setRequestHandler(ListPromptsRequestSchema, async () => { name: PromptName.DELETE_A_MEETING, description: "A prompt to delete a meeting", }, + { + name: PromptName.GET_A_MEETING_DETAILS, + description: "A prompt to get a meeting's details", + }, ], }; }); @@ -97,6 +104,18 @@ server.setRequestHandler(GetPromptRequestSchema, async (request) => { }, ], }; + } else if (name === PromptName.GET_A_MEETING_DETAILS) { + return { + messages: [ + { + role: "user", + content: { + type: "text", + text: "Get a zoom meeting's details", + }, + }, + ], + }; } throw new Error(`Unknown prompt: ${name}`); }); @@ -115,10 +134,15 @@ server.setRequestHandler(ListToolsRequestSchema, async () => { inputSchema: zodToJsonSchema(ListMeetingOptionsSchema), }, { - name: "delete_meeting", + name: "delete_a_meeting", description: "Delete a meeting with a given ID", inputSchema: zodToJsonSchema(DeleteMeetingOptionsSchema), }, + { + name: "get_a_meeting_details", + description: "Retrieve the meeting's details with a given ID", + inputSchema: zodToJsonSchema(GetMeetingOptionsSchema), + }, ], }; }); @@ -145,13 +169,21 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => { }; } - case "delete_meeting": { + case "delete_a_meeting": { const args = DeleteMeetingOptionsSchema.parse(request.params.arguments); const result = await deleteMeeting(args); return { content: [{ type: "text", text: result }], }; } + + case "get_a_meeting_details": { + const args = GetMeetingOptionsSchema.parse(request.params.arguments); + const result = await getAMeetingDetails(args); + return { + content: [{ type: "text", text: JSON.stringify(result, null, 2) }], + }; + } } } catch (error) { if (error instanceof z.ZodError) { diff --git a/operations/meeting.ts b/operations/meeting.ts index 342f198..0ebda2c 100644 --- a/operations/meeting.ts +++ b/operations/meeting.ts @@ -1,6 +1,10 @@ import { z } from "zod"; import { zoomRequest } from "../common/util.js"; -import { ZoomListMeetingsSchema, ZoomMeetingSchema } from "../common/types.js"; +import { + ZoomListMeetingsSchema, + ZoomMeetingDetailSchema, + ZoomMeetingSchema, +} from "../common/types.js"; export const CreateMeetingOptionsSchema = z.object({ agenda: z @@ -37,9 +41,14 @@ export const DeleteMeetingOptionsSchema = z.object({ id: z.number().describe("The ID of the meeting to delete."), }); +export const GetMeetingOptionsSchema = z.object({ + id: z.number().describe("The ID of the meeting."), +}); + export type CreateMeetingOptions = z.infer; export type ListMeetingOptions = z.infer; export type DeleteMeetingOptions = z.infer; +export type GetMeetingOptions = z.infer; export async function createMeeting(options: CreateMeetingOptions) { const response = await zoomRequest( @@ -78,3 +87,13 @@ export async function deleteMeeting(options: DeleteMeetingOptions) { ); return response; } + +export async function getAMeetingDetails(options: GetMeetingOptions) { + const response = await zoomRequest( + `https://api.zoom.us/v2/meetings/${options.id}`, + { + method: "GET", + }, + ); + return ZoomMeetingDetailSchema.parse(response); +} diff --git a/package.json b/package.json index a9c319a..1c19d9d 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,12 @@ { "name": "@yitianyigexiangfa/zoom-mcp-server", - "version": "0.6.5", + "version": "0.7.4", "description": "Now you can date a ZOOM meeting with AI's help.", "scripts": { "build": "tsc && shx chmod +x dist/*.js", "prepare": "husky", "watch": "tsc --watch", - "inspector": "npx @modelcontextprotocol/inspector dist/index.js" + "inspector": "npx @modelcontextprotocol/inspector -- node dist/index.js -e ZOOM_ACCOUNT_ID=$ZOOM_ACCOUNT_ID -e ZOOM_CLIENT_ID=$ZOOM_CLIENT_ID -e ZOOM_CLIENT_SECRET=$ZOOM_CLIENT_SECRET" }, "repository": { "type": "git", pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy