UNPKG

@postman/postman-mcp-server

Version:

Postman MCP Server — connect AI agents (Claude Code, Cursor, VS Code Copilot, Gemini CLI) to your Postman collections, specifications, and environments via Model Context Protocol (MCP)

103 lines (102 loc) • 4.88 kB
import { z } from 'zod'; import { ContentType } from '../clients/postman.js'; import { asMcpError, McpError } from './utils/toolHelpers.js'; export const method = 'postApiCatalogDiscoveryServices'; export const title = 'Add discovered services to the API Catalog'; export const description = 'Registers services with the API Catalog as discovered services, for sources Postman\ncannot detect on its own. Accepts up to 20 services per call; each needs at least a\n\\`name\\`. Supply \\`apiDefinition\\` to attach an OpenAPI definition, or \\`endpoints\\` to list\nendpoints directly — if you send both, \\`endpoints\\` is ignored. Without\n\\`providerServiceId\\` the system derives one from \\`{name}:{version}\\`, so pass it\nexplicitly when you need a stable identifier across calls.\nDo not use this tool to create a Postman API specification or collection; it only adds\ncatalog discovery records. Requires a Postman Enterprise plan.\n'; export const parameters = z.object({ discoveredServices: z .array(z .object({ name: z.string().describe("The service's name."), version: z.string().describe("The service's version.").optional(), providerServiceId: z .string() .describe('The ID of the service in the source registry. If you do not pass this property, the system uses the `{name}:{version}` value.') .optional(), description: z.string().describe("The service's description.").optional(), sourceEnvironment: z.string().describe("The service's source environment.").optional(), apiDefinition: z .object({ content: z .string() .describe('A Base64-encoded JSON API definition. Cannot exceed 2 MB after decoding.') .optional(), }) .describe('The API definition (specification) for the service. If you pass this with the `endpoints` array, this object is given preference and `endpoints` is ignored.') .optional(), endpoints: z .array(z .object({ method: z.string().describe("The endpoint's HTTP method.").optional(), path: z.string().describe("The endpoint's URL path.").optional(), description: z .string() .nullable() .describe("The endpoint's description.") .optional(), host: z.string().describe("The endpoint's host.").optional(), }) .describe("Information about a service's endpoint.")) .max(100) .describe("A list of the service's endpoints. If you pass this with the `apiDefinition` array, this array is ignored.") .optional(), tags: z .array(z.string()) .max(50) .describe('A list of tags associated with the service.') .optional(), providerMetadata: z .object({ commitSha: z.string().describe('A commit hash ID.').optional(), branch: z.string().describe("The source provider's branch name.").optional(), gitRepoUrl: z.string().describe("The source provider's Git repo URL.").optional(), deployedAt: z .string() .datetime({ offset: true }) .describe('The date and time at which the service was deployed.') .optional(), }) .describe('Additional metadata from the discovery source provider.') .optional(), }) .describe('Information about the discovered service.')) .describe('A list of discovered services to add to the API Catalog.'), }); export const annotations = { title: 'Add discovered services to the API Catalog', readOnlyHint: false, openWorldHint: true, destructiveHint: false, idempotentHint: false, }; export async function handler(args, extra) { try { const endpoint = `/api-catalog/discovery-services`; const query = new URLSearchParams(); const url = query.toString() ? `${endpoint}?${query.toString()}` : endpoint; const bodyPayload = {}; if (args.discoveredServices !== undefined) bodyPayload.discoveredServices = args.discoveredServices; const options = { body: JSON.stringify(bodyPayload), contentType: ContentType.Json, headers: extra.headers, }; const result = await extra.client.post(url, options); return { content: [ { type: 'text', text: `${typeof result === 'string' ? result : JSON.stringify(result, null, 2)}`, }, ], }; } catch (e) { if (e instanceof McpError) { throw e; } throw asMcpError(e); } }