Skip to main content
Glama

export_postman_collection

Export saved HTTP requests as a Postman Collection v2.1 JSON file, importable directly into Postman. Optionally filter by tag and resolve environment variables.

Instructions

Exporta los requests guardados como una Postman Collection v2.1 (JSON). Escribe el archivo en disco, importable directamente en Postman.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
nameNoNombre de la colección (default: "API Testing Collection")
tagNoFiltrar requests por tag
output_dirNoDirectorio donde guardar el archivo (default: ./postman/)
resolve_variablesNoResolver {{variables}} del entorno activo (default: false)

Implementation Reference

  • The main handler for the 'export_postman_collection' tool. It lists saved requests (optionally filtered by tag), groups them by tags into folders, builds Postman v2.1 collection JSON, and writes it to disk. Uses helper functions buildPostmanItem, buildPostmanRequest, buildPostmanHeaders, buildPostmanUrl, and buildPostmanAuth.
    // ── export_postman_collection ──
    
    server.tool(
      'export_postman_collection',
      'Exporta los requests guardados como una Postman Collection v2.1 (JSON). Escribe el archivo en disco, importable directamente en Postman.',
      {
        name: z
          .string()
          .optional()
          .describe('Nombre de la colección (default: "API Testing Collection")'),
        tag: z.string().optional().describe('Filtrar requests por tag'),
        output_dir: z
          .string()
          .optional()
          .describe('Directorio donde guardar el archivo (default: ./postman/)'),
        resolve_variables: z
          .boolean()
          .optional()
          .describe('Resolver {{variables}} del entorno activo (default: false)'),
      },
      async (params) => {
        try {
          const collections = await storage.listCollections(params.tag)
          if (collections.length === 0) {
            return {
              content: [
                {
                  type: 'text' as const,
                  text: params.tag
                    ? `No hay requests guardados con tag '${params.tag}'.`
                    : 'No hay requests guardados en la colección.',
                },
              ],
            }
          }
    
          const resolveVars = params.resolve_variables ?? false
          const variables = resolveVars ? await storage.getActiveVariables() : {}
    
          // Load full requests
          const savedRequests: SavedRequest[] = []
          for (const item of collections) {
            const saved = await storage.getCollection(item.name)
            if (saved) savedRequests.push(saved)
          }
    
          // Group by tags for folder structure
          const tagged = new Map<string, SavedRequest[]>()
          const untagged: SavedRequest[] = []
    
          for (const saved of savedRequests) {
            if (saved.tags && saved.tags.length > 0) {
              const tag = saved.tags[0]
              if (!tagged.has(tag)) tagged.set(tag, [])
              tagged.get(tag)!.push(saved)
            } else {
              untagged.push(saved)
            }
          }
    
          // Build Postman items
          const items: unknown[] = []
    
          for (const [tag, requests] of tagged) {
            items.push({
              name: tag,
              item: requests.map((r) => buildPostmanItem(r, variables, resolveVars)),
            })
          }
    
          for (const saved of untagged) {
            items.push(buildPostmanItem(saved, variables, resolveVars))
          }
    
          // Include environment variables as collection variables
          const activeVars = await storage.getActiveVariables()
          const collectionVars = Object.entries(activeVars).map(([key, value]) => ({
            key,
            value,
            type: 'string',
          }))
    
          const collectionName = params.name ?? 'API Testing Collection'
    
          const postmanCollection = {
            info: {
              name: collectionName,
              schema: 'https://schema.getpostman.com/json/collection/v2.1.0/collection.json',
            },
            item: items,
            variable: collectionVars,
          }
    
          const json = JSON.stringify(postmanCollection, null, 2)
    
          // Write to file
          const outputDir = params.output_dir ?? join(process.cwd(), 'postman')
          await mkdir(outputDir, { recursive: true })
          const fileName = collectionName.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '') + '.postman_collection.json'
          const filePath = join(outputDir, fileName)
          await writeFile(filePath, json, 'utf-8')
    
          return {
            content: [
              {
                type: 'text' as const,
                text: `Postman Collection v2.1 exportada (${savedRequests.length} requests).\n\nArchivo: ${filePath}\n\nImporta este archivo en Postman: File → Import → selecciona el archivo.`,
              },
            ],
          }
        } catch (error) {
          const message = error instanceof Error ? error.message : String(error)
          return {
            content: [{ type: 'text' as const, text: `Error: ${message}` }],
            isError: true,
          }
        }
      },
    )
  • Zod schema defining the input parameters for export_postman_collection: name (optional string), tag (optional string filter), output_dir (optional string, default ./postman/), resolve_variables (optional boolean, default false).
    {
      name: z
        .string()
        .optional()
        .describe('Nombre de la colección (default: "API Testing Collection")'),
      tag: z.string().optional().describe('Filtrar requests por tag'),
      output_dir: z
        .string()
        .optional()
        .describe('Directorio donde guardar el archivo (default: ./postman/)'),
      resolve_variables: z
        .boolean()
        .optional()
        .describe('Resolver {{variables}} del entorno activo (default: false)'),
    },
  • Registration of the tool via server.tool('export_postman_collection', ...) inside the registerUtilityTools function, which is called from src/server.ts line 68.
    // ── export_postman_collection ──
    
    server.tool(
      'export_postman_collection',
      'Exporta los requests guardados como una Postman Collection v2.1 (JSON). Escribe el archivo en disco, importable directamente en Postman.',
      {
        name: z
          .string()
          .optional()
          .describe('Nombre de la colección (default: "API Testing Collection")'),
        tag: z.string().optional().describe('Filtrar requests por tag'),
        output_dir: z
          .string()
          .optional()
          .describe('Directorio donde guardar el archivo (default: ./postman/)'),
        resolve_variables: z
          .boolean()
          .optional()
          .describe('Resolver {{variables}} del entorno activo (default: false)'),
      },
      async (params) => {
        try {
          const collections = await storage.listCollections(params.tag)
          if (collections.length === 0) {
            return {
              content: [
                {
                  type: 'text' as const,
                  text: params.tag
                    ? `No hay requests guardados con tag '${params.tag}'.`
                    : 'No hay requests guardados en la colección.',
                },
              ],
            }
          }
    
          const resolveVars = params.resolve_variables ?? false
          const variables = resolveVars ? await storage.getActiveVariables() : {}
    
          // Load full requests
          const savedRequests: SavedRequest[] = []
          for (const item of collections) {
            const saved = await storage.getCollection(item.name)
            if (saved) savedRequests.push(saved)
          }
    
          // Group by tags for folder structure
          const tagged = new Map<string, SavedRequest[]>()
          const untagged: SavedRequest[] = []
    
          for (const saved of savedRequests) {
            if (saved.tags && saved.tags.length > 0) {
              const tag = saved.tags[0]
              if (!tagged.has(tag)) tagged.set(tag, [])
              tagged.get(tag)!.push(saved)
            } else {
              untagged.push(saved)
            }
          }
    
          // Build Postman items
          const items: unknown[] = []
    
          for (const [tag, requests] of tagged) {
            items.push({
              name: tag,
              item: requests.map((r) => buildPostmanItem(r, variables, resolveVars)),
            })
          }
    
          for (const saved of untagged) {
            items.push(buildPostmanItem(saved, variables, resolveVars))
          }
    
          // Include environment variables as collection variables
          const activeVars = await storage.getActiveVariables()
          const collectionVars = Object.entries(activeVars).map(([key, value]) => ({
            key,
            value,
            type: 'string',
          }))
    
          const collectionName = params.name ?? 'API Testing Collection'
    
          const postmanCollection = {
            info: {
              name: collectionName,
              schema: 'https://schema.getpostman.com/json/collection/v2.1.0/collection.json',
            },
            item: items,
            variable: collectionVars,
          }
    
          const json = JSON.stringify(postmanCollection, null, 2)
    
          // Write to file
          const outputDir = params.output_dir ?? join(process.cwd(), 'postman')
          await mkdir(outputDir, { recursive: true })
          const fileName = collectionName.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '') + '.postman_collection.json'
          const filePath = join(outputDir, fileName)
          await writeFile(filePath, json, 'utf-8')
    
          return {
            content: [
              {
                type: 'text' as const,
                text: `Postman Collection v2.1 exportada (${savedRequests.length} requests).\n\nArchivo: ${filePath}\n\nImporta este archivo en Postman: File → Import → selecciona el archivo.`,
              },
            ],
          }
        } catch (error) {
          const message = error instanceof Error ? error.message : String(error)
          return {
            content: [{ type: 'text' as const, text: `Error: ${message}` }],
            isError: true,
          }
        }
      },
    )
  • Helper function buildPostmanItem: converts a SavedRequest into a Postman collection item (name + request). Optionally resolves {{variables}} via resolveUrl and interpolateRequest.
    function buildPostmanItem(
      saved: SavedRequest,
      variables: Record<string, string>,
      resolveVars: boolean,
    ): unknown {
      let config = saved.request
      if (resolveVars) {
        const resolvedUrl = resolveUrl(config.url, variables)
        config = { ...config, url: resolvedUrl }
        config = interpolateRequest(config, variables)
      }
    
      const item: Record<string, unknown> = {
        name: saved.name,
        request: buildPostmanRequest(config),
      }
    
      return item
    }
  • Helper function buildPostmanRequest: converts a RequestConfig into a Postman request object with method, headers, URL, optional body (raw JSON), and optional auth.
    function buildPostmanRequest(config: RequestConfig): unknown {
      const request: Record<string, unknown> = {
        method: config.method,
        header: buildPostmanHeaders(config.headers),
        url: buildPostmanUrl(config.url, config.query),
      }
    
      if (config.body !== undefined && config.body !== null) {
        request.body = {
          mode: 'raw',
          raw: typeof config.body === 'string' ? config.body : JSON.stringify(config.body, null, 2),
          options: { raw: { language: 'json' } },
        }
        // Add Content-Type header if not already present
        const headers = request.header as Array<{ key: string; value: string }>
        if (!headers.some((h) => h.key.toLowerCase() === 'content-type')) {
          headers.push({ key: 'Content-Type', value: 'application/json' })
        }
      }
    
      if (config.auth) {
        request.auth = buildPostmanAuth(config.auth)
      }
    
      return request
    }
Behavior3/5

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

No annotations provided, so description carries burden. States it writes a JSON file to disk, but lacks details on overwrite behavior, permissions, or side effects. Additional traits like default output directory are noted.

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

Conciseness5/5

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

Two concise sentences with front-loaded key action (export format) and immediate outcome (write to disk, importable in Postman). No filler.

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

Completeness3/5

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

Adequate for basic understanding but missing details on return value, parameter interactions, file overwrite policy, and handling of optional parameters. Could provide more context for a file-writing tool.

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

Parameters3/5

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

Schema description coverage is 100%, so parameters are well-documented structurally. The description adds minimal extra meaning (e.g., 'saved requests' context). Baseline 3 is appropriate.

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

Purpose5/5

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

The description clearly states the tool exports saved requests as a Postman Collection v2.1 JSON file, specifying both the export format and the resource. It differentiates from sibling tools like export_curl and import_postman_collection by focusing on Postman Collection export to disk.

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

Usage Guidelines2/5

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

No guidance on when to use this tool versus alternatives (e.g., export_collection, export_curl). No mention of prerequisites or context for selecting this specific export method.

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

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/cocaxcode/api-testing-mcp'

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