We have all been there. You are deep in the flow state, building a new micro-service. You finish the code, and then the "tax" of API development kicks in. You have to switch windows to Postman, manually create a collection, copy-paste your localhost URLs, write JSON bodies to test them, and then write test assertions. Then, you need a client library, so you switch contexts again to scaffold a Python or TypeScript SDK.
It is fragmented. It is manual. It is slow.
But what if your CLI could just do it? What if you could say, "Here is my code, push this to Postman, write the tests, and give me a Python SDK," and it just happened?
Enter the Model Context Protocol (MCP). By connecting Google's Gemini CLI with the Postman MCP server, we can bridge the gap between our local development environment and our API ecosystem. In this guide, I will walk you through a hands-on workflow that creates a "Task Manager" API, pushes it to Postman, automates testing, and generates a client library — all without leaving your terminal.
The Architecture: Why MCP Matters
Before we dive into the commands, let's briefly look at the "engine" under the hood.
The Model Context Protocol (MCP) is an open standard that enables AI models (like Gemini) to safely connect to external tools and data. Instead of building a custom integration for every tool, Postman exposes its capabilities (creating collections, reading workspaces, running monitors) as an MCP Server.
When you run the Gemini CLI with this configuration, you aren't just "chatting" with an LLM. You are giving the LLM permission to execute tools on your behalf.
- Gemini provides the reasoning ("I see a POST endpoint in your code…").
- MCP provides the action ("…so I will call
postman.create_request"). - Postman provides the infrastructure.
The Setup
To follow along, you will need Node.js (v18+) , Postman (v11+ desktop version) and a Postman API Key.
1. Install the Gemini CLI
If you are using the Google Cloud Vertex AI-backed CLI or the developer preview:
npm install -g @google/gemini-cli2. Configure the Postman MCP Server
Create or edit your ~/.gemini/settings.json (or project-level config). We need to run the server in "full" mode to access advanced features like Monitors.
{
"mcpServers": {
"postman": {
"command": "npx",
"args": [
"-y",
"@postman/postman-mcp-server",
"--full"
],
"env": {
"POSTMAN_API_KEY": "YOUR_KEY_HERE"
}
}
}
}Please replace the POSTMAN_API_KEY from the postman web. Navigate to your profile → settings → Api Keys.

3. Create the "Task Manager" App using Express.js
a. Initialize the project: Open your terminal and run:
mkdir task_mgr_app
cd task_mgr_app
npm init -y
npm install expressb. Create a file named server.js in a new folder. This contains the 4 APIs we will work with.
shuvajkar@myMAC task_mgr_app % ls -lrt
total 96
-rw-r--r-- 1 shukar staff 297 5 Feb 16:57 package.json
-rw-r--r-- 1 shukar staff 28935 5 Feb 16:57 package-lock.json
drwxr-xr-x 68 shukar staff 2176 5 Feb 16:57 node_modules
-rw-r--r-- 1 shukar staff 825 5 Feb 16:58 server.js
// server.js
const express = require('express');
const app = express();
app.use(express.json());
const PORT = 3000;
// 1. GET: Retrieve all tasks
app.get('/tasks', (req, res) => {
res.status(200).json({ message: "Fetched all tasks", data: [] });
});
// 2. POST: Create a new task
app.post('/tasks', (req, res) => {
const { title } = req.body;
res.status(201).json({ message: `Task '${title}' created`, id: 101 });
});
// 3. PUT: Update a task by ID
app.put('/tasks/:id', (req, res) => {
const { id } = req.params;
res.status(200).json({ message: `Task ${id} updated` });
});
// 4. DELETE: Remove a task
app.delete('/tasks/:id', (req, res) => {
const { id } = req.params;
res.status(204).send();
});
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
});Please note that these APIs are designed for explaining the concept only. You can put your appropriate business content , based on your use-case.
Workflow 1: Push APIs from Code to Postman
Goal: eliminate manual data entry. We will turn server.js into a Postman Collection.
Step 1: Start Gemini
shuvajkar@myMAC mcp_postman% cd task_mgr_app
shuvajkar@myMAC task_mgr_app% gemini Step 2: Install the postman-mcp-server extension within gemini
> gemini extensions install https://github.com/postmanlabs/postman-mcp-server
✦ I will check if the gemini command is available and then attempt to install the extension as requested.
ℹ Gemini CLI update available! 0.22.5 → 0.27.0
Installed via Homebrew. Please update with "brew upgrade gemini-cli".
╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ ✓ Shell gemini --version [current working directory /Users/shukar] (Checking if gemini CLI is installed and what version it is.) │
│ │
│ 0.22.5 │
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯Step 3: Check if the extensions are ready
> /extensions list
Installed extensions:
postman (v0.1.0) - active (up to date)
> list my postman workspaces
╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ ✓ Shell curl -s -H "X-Api-Key: PMAK-69847acff211f300010da897-6ccd79946c8343f0f9e3ba914d986e6997" https://api.getpostman.com/workspaces [current working directory /U… │
│ │
│ {"workspaces":[{"id":"afd703e8-2a99-452b-a9c0-2d8887a76ce0","name":"Personal Workspace","type":"team","visibility":"personal","createdBy":"1714967","about":"This is │
│ your personal, private workspace to play around │
│ in.","createdAt":"2026-01-29T18:32:38.000Z","updatedAt":"2026-01-29T18:32:38.000Z"},{"id":"23d9008b-381f-422d-8fcb-6e4f306b93a1","name":"Team │
│ Workspace","type":"team","visibility":"team","createdBy":"1714967","about":"","createdAt":"2026-02-05T11:07:31.000Z","updatedAt":"2026-02-05T11:07:31.000Z"},{"id":"dd │
│ d24162-1a5f-4c3a-92d6-438fee9af2f9","name":"mcp-workspace","type":"team","visibility":"team","createdBy":"1714967","about":"","createdAt":"2026-02-05T11:07:32.000Z"," │
│ updatedAt":"2026-02-05T11:07:32.000Z"},{"id":"10ffc76e-818e-48a6-bd2f-8be8caac615f","name":"Task Manager │
│ App","type":"team","visibility":"personal","createdBy":"1714967","about":"","createdAt":"2026-02-05T12:20:10.000Z","updatedAt":"2026-02-05T12:20:10.000Z"}]} │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
✦ You have the following Postman workspaces:
1. Personal Workspace (afd703e8-2a99-452b-a9c0-2d8887a76ce0)
2. Team Workspace (23d9008b-381f-422d-8fcb-6e4f306b93a1)
3. mcp-workspace (ddd24162-1a5f-4c3a-92d6-438fee9af2f9)
4. Task Manager App (10ffc76e-818e-48a6-bd2f-8be8caac615f)Step 4: The "Push" Prompt Run this prompt to read your code and create the structure in Postman. It consists of 2 blocks — one to contextualize and the other to execute.
"I have a local file server.js that defines an Express API. Please read it to understand the endpoints.
Then, use the Postman MCP to:
1. Create a Workspace named 'Task Manager App'.
2. Create a Collection named 'Task APIs v1' inside it.
3. Add all 4 endpoints (GET, POST, PUT, DELETE) to the collection.
4. Set the URL for all requests to {{baseUrl}}/tasks (or /tasks/:id).
5. Set baseUrl to http://localhost:3000"In seconds, Gemini parses the AST (Abstract Syntax Tree) of your code, extracts the routes and methods, and executes the Postman tool calls. If you open your Postman workspace, you will see the collection fully populated, with method types (GET, POST) and paths correctly set.
> "I have a local file server.js that defines an Express API. Please read it to understand the endpoints.
Then, use the Postman MCP to:
1. Create a Workspace named 'Task Manager App'.
2. Create a Collection named 'Task APIs v1' inside it.
3. Add all 4 endpoints (GET, POST, PUT, DELETE) to the collection.
4. Set the URL for all requests to {{baseUrl}}/tasks (or /tasks/:id).
5. Set baseUrl to http://localhost:3000"
╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ ✓ ReadFile server.js │
│ │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ ✓ Shell curl -s -H "X-Api-Key: PMAK-69847acff211f300010da897-6ccd79946c8343f0f9e3ba914d986e6997" https://api.getpostman.com/workspaces [current working directory /U… │
│ │
│ {"workspaces":[{"id":"afd703e8-2a99-452b-a9c0-2d8887a76ce0","name":"Personal Workspace","type":"team","visibility":"personal","createdBy":"1714967","about":"This is │
│ your personal, private workspace to play around │
│ in.","createdAt":"2026-01-29T18:32:38.000Z","updatedAt":"2026-01-29T18:32:38.000Z"},{"id":"23d9008b-381f-422d-8fcb-6e4f306b93a1","name":"Team │
│ Workspace","type":"team","visibility":"team","createdBy":"1714967","about":"","createdAt":"2026-02-05T11:07:31.000Z","updatedAt":"2026-02-05T11:07:31.000Z"},{"id":"dd │
│ d24162-1a5f-4c3a-92d6-438fee9af2f9","name":"mcp-workspace","type":"team","visibility":"team","createdBy":"1714967","about":"","createdAt":"2026-02-05T11:07:32.000Z"," │
│ updatedAt":"2026-02-05T11:07:32.000Z"},{"id":"10ffc76e-818e-48a6-bd2f-8be8caac615f","name":"Task Manager │
│ App","type":"team","visibility":"personal","createdBy":"1714967","about":"","createdAt":"2026-02-05T12:20:10.000Z","updatedAt":"2026-02-05T12:20:10.000Z"}]} │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ x createCollection (postman MCP Server) {"collection":{"info":{"name":"Task APIs v1","schema":"https://schema.getpostman.com/json/collection/v2.1.0/collection.json"… │
│ │
│ MCP tool 'createCollection' reported tool error for function call: {"name":"createCollection","args":{"collection":{"info":{"name":"Task APIs │
│ v1","schema":"https://schema.getpostman.com/json/collection/v2.1.0/collection.json"},"variable":[{"key":"baseUrl","value":"http://localhost:3000"}],"item":[{"name":"G │
│ et All Tasks","request":{"method":"GET","url":"{{baseUrl}}/tasks"}},{"request":{"body":{"mode":"raw","raw":"{\n \"title\": \"New │
│ Task\"\n}"},"url":"{{baseUrl}}/tasks","method":"POST","header":[{"value":"application/json","key":"Content-Type"}]},"name":"Create Task"},{"name":"Update │
│ Task","request":{"method":"PUT","header":[{"value":"application/json","key":"Content-Type"}],"body":{"mode":"raw","raw":"{\n \"title\": \"Updated │
│ Task\"\n}"},"url":"{{baseUrl}}/tasks/:id"}},{"name":"Delete │
│ Task","request":{"method":"DELETE","url":"{{baseUrl}}/tasks/:id"}}]},"workspace":"10ffc76e-818e-48a6-bd2f-8be8caac615f"}} with response: │
│ [{"functionResponse":{"name":"createCollection","response":{"content":[{"type":"text","text":"MCP error -32602: API request failed: 401 │
│ {\"error\":{\"name\":\"AuthenticationError\",\"message\":\"Invalid API Key. Every request requires a valid API Key to be sent.\"}}"}],"isError":true}}}] │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ ✓ Shell curl -s -X POST -H "X-Api-Key: PMAK-69847acff211f300010da897-6ccd79946c8343f0f9e3ba914d986e6997" -H "Content-Type: application/json" -d '{"collection":{"inf… │
│ │
│ {"collection":{"id":"b268b30e-cce2-4f97-9f9e-96ec5749b7a4","name":"Task APIs v1","uid":"1714967-b268b30e-cce2-4f97-9f9e-96ec5749b7a4"}} │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
✦ I have successfully completed the setup.
1. Analyzed `server.js`: Identified 4 endpoints (GET /tasks, POST /tasks, PUT /tasks/:id, DELETE /tasks/:id).
2. Identified Workspace: Found the existing 'Task Manager App' workspace (ID: 10ffc76e-818e-48a6-bd2f-8be8caac615f).
3. Created Collection: Created a new collection named 'Task APIs v1' in that workspace.
4. Added Endpoints: Added all 4 requests to the collection with {{baseUrl}} variable usage.
5. Set Variable: Configured the collection variable baseUrl to http://localhost:3000.
The collection ID is b268b30e-cce2-4f97-9f9e-96ec5749b7a4.Step 5: Post-Push Verification
" Go to Postman.
1. Open the "Task APIs v1" collection.
2. Crucial: Go to the "Variables" tab and verify the baseUrl.
3. If not set, set baseUrl to http://localhost:3000 (Current Value)."
This is important, i missed it twice.Workflow 2: Create API Monitors and Tests
Goal: Automate Quality Assurance. We will ask Gemini to write the JavaScript test assertions.
Step 1: The "Test Generation" Prompt
" Access the 'Task APIs v1' collection in the 'Task Manager App' workspace. │
│
I want to add test scripts to the requests. Please update the collection with the following tests: │
│
For 'GET /tasks': Check that the status code is 200 and the response time is under 500ms. │
│
For 'POST /tasks': Check that the status code is 201 and the response body contains the field 'id'. │
│
For 'DELETE /tasks/:id': Check that the status code is 204" Gemini modifies the collection in place. If you inspect the Tests tab in Postman, you will see it has injected standard assertions:


Step 2: Run the Tests Locally (Collection Runner)
Before setting up a cloud monitor, verify the tests pass against your local server.
- Open Postman.
- Go to the "Task APIs v1" collection.
- Click the "Run" button (or "Runner" tab).
- Make sure your local server is running (
node server.js). - Click "Run Task APIs v1".
You should see green "PASS" indicators next to your new status code and response time tests.

Step 3: The "Monitor" Prompt
"Create a new Monitor for the 'Task APIs v1' collection. │
│
Name: 'Task API Health Check' │
│
Schedule: Run this monitor once every day at 2100 Hrs. │
│
Workspace: 'Task Manager App'"⚠️ Critical Warning for Monitors: Postman Monitors run on Postman's cloud servers, not your laptop. Gemini says,
✓ Shell curl -s -H "X-Api-Key: PMAK-69847acff211f300010da897-6ccd79946c8343f0f9e3ba914d986e6997" "https://api.getpostman.com/collections?workspace=10ffc76e-818e-48a… │
│ │
│ {"collections":[{"id":"f830ad75-1075-48aa-945d-9309b8f33d74","name":"Task APIs │
│ v1","owner":"1714967","createdAt":"2026-02-05T12:20:23.000Z","updatedAt":"2026-02-05T17:29:16.000Z","uid":"1714967-f830ad75-1075-48aa-945d-9309b8f33d74","isPublic":fa │
│ lse}]} │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ ✓ Shell curl -s -X POST -H "X-Api-Key: PMAK-69847acff211f300010da897-6ccd79946c8343f0f9e3ba914d986e6997" -H "Content-Type: application/json" -d '{ "monitor": { "nam… │
│ │
│ {"monitor":{"id":"1f103395-4964-4730-951a-65824846fb5e","name":"Task API Health Check","active":true,"uid":"1714967-1f103395-4964-4730-951a-65824846fb5e"}} │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
✦ I've created the monitor 'Task API Health Check' for the 'Task APIs v1' collection in the 'Task Manager App' workspace. It is scheduled to run once every day.The Problem: The cloud cannot see
http://localhost:3000.
The Fix: To make the monitor green, you must either deploy your API (e.g., to Render/Heroku) or use a tunnel tool like ngrok (
ngrok http 3000) and update yourbaseUrlvariable in Postman to the ngrok URL.
Workflow 3: Create Code from APIs (Postman to Local)
Goal: Generate a Python SDK for your team/clients.
This is my favorite workflow. Often, the frontend team or a partner team needs an SDK to consume your new API. Writing a client library manually is prone to typos.
Since Postman now holds the "perfect" definition of our API (thanks to Phase 2), we can use that definition to scaffold code as part of what i call the Client Gen Workflow.
Step 1: The "Fetch & Generate" Prompt
"Retrieve the details of the 'Task APIs v1' collection.
Generate a robust Python client library using the requests library. It should:
1. Be a class named TaskClient.
2. Accept base_url in __init__.
3. Have methods for get_tasks, create_task, update_task, and delete_task.
4. Include type hinting where possible.
Save this code to a file named task_client.py in my current directory."TaskClient.py code from published endpoints
import requests
class TaskClient:
def __init__(self, base_url='http://localhost:3000'):
"""
Initialize the TaskClient.
:param base_url: The base URL of the API (default: http://localhost:3000)
"""
self.base_url = base_url.rstrip('/')
def get_tasks(self):
"""
Retrieve all tasks.
:return: JSON response containing the list of tasks.
"""
url = f"{self.base_url}/tasks"
response = requests.get(url, headers={"Accept": "application/json"})
response.raise_for_status()
return response.json()
def create_task(self, title, completed=False):
"""
Create a new task.
:param title: The title of the task.
:param completed: The completion status of the task (default: False).
:return: JSON response from the server.
"""
url = f"{self.base_url}/tasks"
payload = {
"title": title,
"completed": completed
}
headers = {
"Accept": "application/json",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
response.raise_for_status()
return response.json()
def update_task(self, task_id, title, completed=False):
"""
Update a task by ID.
:param task_id: The ID of the task to update.
:param title: The new title of the task.
:param completed: The new completion status of the task (default: False).
:return: JSON response from the server.
"""
url = f"{self.base_url}/tasks/{task_id}"
payload = {
"title": title,
"completed": completed
}
headers = {
"Accept": "application/json",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
response.raise_for_status()
return response.json()
def delete_task(self, task_id):
"""
Remove a task.
:param task_id: The ID of the task to delete.
:return: The HTTP status code (204 expected on success).
"""
url = f"{self.base_url}/tasks/{task_id}"
headers = {
"Accept": "application/json"
}
response = requests.delete(url, headers=headers)
response.raise_for_status()
return response.status_codepyStep 2: Verify it Works
You now have a fully functional Python SDK for your API. You can test it immediately.
- Ensure your Node.js server is still running (
node server.js). - Create a test script (or just run
python3in your terminal):
# Create a file named test_sdk.py or run in python shell
from task_client import TaskClient
client = TaskClient()
# 1. Create a task
print("Creating task...")
response = client.create_task({"title": "Test from Python", "completed": False})
print(response)
# 2. Get all tasks
print("\nFetching tasks...")
print(client.get_tasks())3. Run it:
python3 test_sdk.pyDebugging Guide: Common Errors
Here are the specific errors you might face and how to fix them.
1. Error: getaddrinfo ENOTFOUND {{baseUrl}}
- Cause: Postman tried to literally connect to the text
{{baseUrl}}because the variable is undefined. - Fix:
- Click the Collection Name ("Task APIs v1").
- Click the Variables tab.
- Ensure
baseUrlis set in the Current Value column (e.g.,http://localhost:3000). - Save (Ctrl+S).
2. Error: SyntaxError: Unexpected token ... is not valid JSON
- Cause: You sent a request body that isn't strict JSON (e.g., missing quotes on keys or using single quotes).
- Fix: Ensure your body looks like this:
{
"title": "Fix the bug",
"completed": false
}❌ Bad: { title: 'Fix bug' } (Keys must be quoted, use double quotes for strings).
3. Error: EADDRINUSE: address already in use :::3000
- Cause: You are trying to start the server (
node server.js), but it is already running in another terminal window. - Fix:
- Find the other terminal and press
Ctrl+C. - Or, kill the process manually:
npx kill-port 3000.
4. Monitor Error: Error: connect ECONNREFUSED 127.0.0.1:3000
- Cause: As mentioned in Workflow 2, the Postman Cloud Monitor is trying to connect to its own localhost, not yours.
- Fix: Monitors only work for public URLs. Use
ngrokor deploy your API to a public server for the monitor to work.
Conclusion: The Architecture of Flow
We often talk about "developer velocity," but rarely do we address its biggest adversary: context switching. Every time you alt-tab from your IDE to a GUI client, manually copy a cURL command, or hand-write a JSON schema for a client library, you are paying a "cognitive tax."
The workflow we demonstrated with the Task Manager API proves that this tax is no longer necessary. By leveraging the Model Context Protocol (MCP), we didn't just "chat" with Gemini; we orchestrated a synchronized DevOps pipeline using natural language.
The ROI of Agentic Workflows
Let's look at the numbers from our sample use case. In a traditional workflow, bringing the server.js API to a production-ready state would involve:
- Manual Entry: Creating 4 requests in Postman (~5 mins).
- Test Writing: Scripting assertions for status codes and latency (~10 mins).
- SDK Creation: Manually typing out a Python
TaskClientwrapper (~15 mins).
Total time: ~30 minutes of low-leverage work.
With the Postman MCP + Gemini CLI, we achieved the same outcome in three prompts.
- We established Code-as-Source-of-Truth: The collection was born directly from the AST of our local files, eliminating drift between what is deployed and what is documented.
- We automated Quality Assurance: Test scripts were injected instantly, ensuring our endpoints met latency (<400ms) and schema requirements from day one.
- We commoditized Consumption: The Python Client was generated programmatically from the Postman definition, guaranteeing that the client library perfectly matched the API signature.
Ease of Operation
The beauty of this stack lies in its invisibility. You don't need to learn a new DSL (Domain Specific Language) or configure complex YAML pipelines. You simply express your intent — "Create a monitor," "Generate a client," "Sync this file" — and the MCP server translates that intent into precise API calls against the Postman platform. It turns your CLI into a command center for your entire API lifecycle.
Next Steps: Try integrating this into your CI/CD pipeline. Imagine a GitHub Action where a PR comment triggers Gemini to update the Postman collection automatically. The possibilities for agentic automation are just beginning.
Have you experimented with MCP yet? Let me know in the comments.
Happy Coding.
Coming Next: Beyond Text — Building Interactive GUIs with Postman MCP Apps
We have mastered the command line, but let's face it: text responses can only go so far. Sometimes you need to interact with your data, not just read about it.
In my next post, "The Missing Link in AI: Mastering MCP Observability and Security with Postman," we will also unveil the game-changer: MCP Apps.
Opinions expressed are my own in my personal capacity and do not represent the views, policies or positions of my employer(s) or its subsidiaries or affiliates.