A powerful VSCode extension that combines the proxy and interception capabilities similar to Nginx and Charles, designed specifically for local development environments. It intelligently intercepts HTTP requests, either returning custom mock data or acting as a proxy server to forward real requests to the original server with full HTTP headers.
- 📑 Tab-based Interface: Manage multiple proxy configuration groups in separate tabs
- 🚀 Multiple Proxy Groups: Run multiple mock services simultaneously, each on its own port
- 🏗️ Microservices Ready: Perfect for microservices architecture (e.g., user service on port 8888, order service on port 8889)
- 🔄 Quick Switching: Easily switch and manage different service configurations via tabs
- 🎨 Refreshed UI: Compact buttons, responsive layout, codicon icons, clearer disabled states
- 🎯 Configure intercept prefix (e.g.,
/api) to precisely target specific request paths - 🔄 With Mock Config: Returns preset mock data for offline development
- 🌐 Without Mock Config: Acts as a proxy server, forwarding requests with complete HTTP headers to get real data
- 🔀 Smart path matching with prefix stripping and route rewrite support
- Single-segment
*:/a/b/*matches/a/b/123(not/a/b/123/456) - Multi-segment
**:/a/b/**matches/a/b/123and/a/b/123/456(not/a/b) - In-segment position:
/order/*/submitmatches/order/123/submit - Match priority: Exact path > fewer wildcards > method-specific (non-ALL) > longer pattern
- 👥 Target Users: Frontend Engineers, QA Engineers, Full-Stack Developers
- 🎨 Visual configuration UI within VSCode
- 💾 Persistent configuration with workspace-level isolation
- 🌐 Automatic CORS handling
- ⏱️ Network delay simulation support
- 🔧 Custom response status codes and headers
- 🍪 Global cookie support for authenticated APIs
- Open VSCode
- Press
Ctrl+P/Cmd+Pto open Quick Open - Type
ext install Ark65.intercept-wave - Press Enter
Or install from the Extensions view (Ctrl+Shift+X / Cmd+Shift+X).
- Click the "Intercept Wave" icon in the Activity Bar
- Use tabs at the top to switch between different proxy configuration groups
- Click the + button to add a new proxy group
- Right-click a tab or use the Settings button to:
- Edit group name and configuration
- Delete the group (at least one group must remain)
- Enable/disable the group
Start All Enabled Groups:
- Click the "Start All" button to start all enabled proxy groups simultaneously
- Each group will run on its configured port
Start Individual Group:
- Select the desired group tab
- Click the "Start Server" button within that group
- Only this specific group will start
Stop Servers:
- Click "Stop All" to stop all running servers
- Or click "Stop Server" within a specific group to stop only that one
Click the "Configure" or Settings button to set up each group:
Each proxy group has independent settings:
- Group Name: Descriptive name for this configuration (e.g., "User Service", "Dev Environment")
- Mock Port: Port for this group's mock server (e.g., 8888, 8889)
- Intercept Prefix: API path prefix to intercept (default: /api)
- Base URL: Base URL of the original server (e.g., http://localhost:8080)
- Strip Prefix: When enabled,
/api/usermatches mock path/user - Rewrite Target Path: Optional route-level target path base applied after stripping, such as
/v1 - Global Cookie: Configure global cookie value for this group's mock APIs
- Enabled: Whether this group should start when clicking "Start All"
Add mock APIs to each group:
- Path: e.g.,
/user(when stripPrefix is true) or/api/user(when false) - HTTP Method: ALL, GET, POST, PUT, DELETE, PATCH
- Status Code: HTTP response status code (default: 200)
- Delay (ms): Simulate network delay (default: 0)
- Response Template: Optional built-in success, pagination, empty, error, or auth-expired JSON shape
- Mock Data: Response data in JSON format
- Enabled: Whether to enable this mock configuration
- Use Global Cookie: Include the configured global cookie in response
Mock multiple microservices simultaneously, each service running on an independent port:
Proxy Group 1 - User Service (Port 8888):
// Frontend code for user service
fetch('http://localhost:8888/api/user/info')
.then(res => res.json())
.then(data => console.log(data));Configuration:
- Group Name: "User Service"
- Port: 8888
- Intercept Prefix:
/api - Mock API:
/user/inforeturns user data
Proxy Group 2 - Order Service (Port 8889):
// Frontend code for order service
fetch('http://localhost:8889/order-api/orders')
.then(res => res.json())
.then(data => console.log(data));Configuration:
- Group Name: "Order Service"
- Port: 8889
- Intercept Prefix:
/order-api - Mock API:
/ordersreturns order list
Both services can run simultaneously, each on its own port!
Create different proxy groups for different environments:
- Dev Environment (Port 8888): Points to
http://localhost:8080 - Test Environment (Port 8889): Points to
http://test.example.com - Staging Environment (Port 8890): Points to
http://staging.example.com
Switch between environments by selecting different tabs, and start only the environment you need.
// Frontend code
fetch('http://localhost:8888/api/user/info')
.then(res => res.json())
.then(data => console.log(data));Configuration:
- Path:
/user/info(with stripPrefix enabled) - Method:
GET - Mock Data:
{
"code": 0,
"data": {
"id": 1,
"name": "John Doe",
"email": "john@example.com"
},
"message": "success"
}// This API has no mock configuration, will be forwarded to original server
fetch('http://localhost:8888/api/posts')
.then(res => res.json())
.then(data => console.log(data));If the base URL is configured as http://api.example.com, the actual request will be: http://api.example.com/api/posts
- Set cookie in global configuration:
sessionId=abc123; userId=456 - Check "Use Global Cookie" in mock API configuration
- Mock API response will automatically include
Set-Cookieresponse header
Set delay time in mock configuration (e.g., 1000ms) to simulate slow network environment.
Configure different status codes (404, 500, etc.) to test frontend error handling logic.
Run unit tests:
npm run test:unitRun Docker-backed integration tests against intercept-wave-upstream:
docker compose -f docker/docker-compose.upstream.yml up -d upstream
npm run test:integrationThe integration suite uses these defaults:
IW_UPSTREAM_HTTP=http://localhost:9000IW_UPSTREAM_WS=ws://localhost:9003
If you also want to run the VS Code extension-host smoke tests:
npm run test:vscode-integration- Intercept Wave: Start Mock Server - Start the mock server
- Intercept Wave: Stop Mock Server - Stop the mock server
- Intercept Wave: Configure - Open configuration UI
- Intercept Wave: Open Configuration File - Open the config.json file directly
All configurations are saved in the .intercept-wave folder in your workspace:
.intercept-wave/
└── config.json # Global configuration and API mappings
{
"version": "3.0",
"proxyGroups": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "User Service",
"enabled": true,
"port": 8888,
"interceptPrefix": "/api",
"baseUrl": "http://localhost:8080",
"stripPrefix": true,
"globalCookie": "sessionId=abc123; userId=456",
"mockApis": [
{
"path": "/user/info",
"enabled": true,
"mockData": "{\"code\":0,\"data\":{\"id\":1,\"name\":\"John\"}}",
"method": "GET",
"statusCode": 200,
"useCookie": true,
"delay": 0
}
]
},
{
"id": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
"name": "Order Service",
"enabled": true,
"port": 8889,
"interceptPrefix": "/order-api",
"baseUrl": "http://localhost:8081",
"stripPrefix": true,
"globalCookie": "",
"mockApis": [
{
"path": "/orders",
"enabled": true,
"mockData": "{\"code\":0,\"data\":[]}",
"method": "GET",
"statusCode": 200,
"useCookie": false,
"delay": 0
}
]
}
]
}Note: the version field is managed by the extension and may be updated automatically to match the installed major.minor version.
Set cookie value in global configuration, multiple cookies separated by semicolons:
sessionId=abc123; userId=456; token=xyz789
Then check "Use Global Cookie" for mock APIs that need cookies, and the response will automatically include Set-Cookie header.
When creating or editing a Mock API, choose a response template and click Apply Template to replace the editable Mock Data area. The template does not change the HTTP status code or any other Mock settings, and the JSON can still be edited, formatted, validated, and saved through the existing minify flow.
Built-in templates:
{
"success": {"code":0,"message":"success","data":{}},
"pagination": {"code":0,"message":"success","data":{"list":[],"total":0,"pageNum":1,"pageSize":10}},
"empty": {"code":0,"message":"success","data":null},
"error": {"code":500,"message":"Internal Server Error","data":null},
"auth expired": {"code":401,"message":"Unauthorized","data":null}
}Mock server automatically adds the following CORS headers:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization
HTTP routes can define request and response header override rules. Request rules run immediately before proxy forwarding. Response rules run last before returning to the browser, so they apply to proxy, static, mock, and route-matched OPTIONS preflight responses after the default CORS headers are prepared.
Each rule uses the shared config shape:
{
"name": "Cache-Control",
"value": "no-store",
"operation": "SET",
"enabled": true
}Supported operations:
SET: replace the header valueADD: append to an existing value with,, or set the header when missingREMOVE: remove the header;valuecan be empty
Common recipes:
{
"name": "API",
"pathPrefix": "/api",
"targetType": "PROXY",
"targetBaseUrl": "http://localhost:9000",
"stripPrefix": true,
"requestHeaders": [
{ "name": "Authorization", "value": "Bearer local-dev-token", "operation": "SET", "enabled": true }
],
"responseHeaders": [
{ "name": "Access-Control-Allow-Origin", "value": "http://localhost:5173", "operation": "SET", "enabled": true },
{ "name": "Cache-Control", "value": "no-store", "operation": "SET", "enabled": true }
],
"enableMock": true,
"mockApis": []
}Use request rules for local auth injection or upstream feature flags. Use response rules to override CORS, disable cache, adjust Content-Type, or remove headers from proxy, static, or mock responses.
Restricted request headers are saved but skipped at runtime: host, connection, content-length, date, expect, upgrade, trailer, te.
Restricted response headers are saved but skipped at runtime: transfer-encoding, content-length, connection.
Unconfigured mock APIs will be automatically forwarded to the original server, preserving:
- Original request headers
- User-Agent
- Request body (for POST/PUT, etc.)
- Cookies (if any)
Intercept Wave can replace common local nginx reverse-proxy recipes during development. It is a local development gateway for VSCode-driven debugging, mocking, and proxying; it is not a production nginx replacement.
A typical frontend + backend nginx setup:
server {
listen 8888;
location /api/ {
proxy_pass http://localhost:9000/;
}
location / {
proxy_pass http://localhost:5173/;
try_files $uri /index.html;
}
}Equivalent Intercept Wave HTTP routes:
[
{
"name": "API",
"pathPrefix": "/api",
"targetType": "PROXY",
"targetBaseUrl": "http://localhost:9000",
"staticRoot": "",
"stripPrefix": true,
"rewriteTargetPath": "",
"spaFallbackPath": "",
"spaFallback": false,
"enableMock": true,
"mockApis": []
},
{
"name": "Frontend",
"pathPrefix": "/",
"targetType": "PROXY",
"targetBaseUrl": "http://localhost:5173",
"staticRoot": "",
"stripPrefix": false,
"rewriteTargetPath": "",
"spaFallbackPath": "/index.html",
"spaFallback": false,
"enableMock": false,
"mockApis": []
}
]This works for Vite, Next, Webpack, and similar dev servers: /api/users goes to the backend route, while /, /assets/app.js, and /dashboard/settings go to the frontend dev server route. When a browser refresh on /dashboard/settings returns an upstream 404, the frontend route can retry /index.html through spaFallbackPath.
For multiple backend services, add one route per prefix and rely on longest-prefix matching:
[
{ "name": "API", "pathPrefix": "/api", "targetBaseUrl": "http://localhost:9000", "stripPrefix": true, "rewriteTargetPath": "", "spaFallbackPath": "", "enableMock": true, "mockApis": [] },
{ "name": "Auth", "pathPrefix": "/auth", "targetBaseUrl": "http://localhost:9010", "stripPrefix": true, "rewriteTargetPath": "", "spaFallbackPath": "", "enableMock": true, "mockApis": [] },
{ "name": "Admin API", "pathPrefix": "/admin-api", "targetBaseUrl": "http://localhost:9020", "stripPrefix": true, "rewriteTargetPath": "", "spaFallbackPath": "", "enableMock": true, "mockApis": [] },
{ "name": "Frontend", "pathPrefix": "/", "targetBaseUrl": "http://localhost:5173", "stripPrefix": false, "rewriteTargetPath": "", "spaFallbackPath": "/index.html", "enableMock": false, "mockApis": [] }
]For a frontend production build, switch the frontend route to static file serving:
{
"name": "Frontend Build",
"pathPrefix": "/",
"targetType": "STATIC",
"targetBaseUrl": "http://localhost:8080",
"staticRoot": "frontend/dist",
"stripPrefix": false,
"rewriteTargetPath": "",
"spaFallbackPath": "",
"spaFallback": true,
"enableMock": false,
"mockApis": []
}Static roots are resolved from the workspace root, so shared configs should prefer project-relative values such as dist, build, or frontend/dist. Absolute external folders are allowed for local-only setups, but they make .intercept-wave/config.json machine-specific. Static routes use the same route-local path rules as proxy routes: stripPrefix first, then rewriteTargetPath; query strings are ignored for file lookup. Raw and encoded traversal attempts are rejected before files are read.
Path rewrite follows nginx-like local gateway semantics:
pathPrefix="/api",stripPrefix=true:/api/usersis matched and forwarded as/userspathPrefix="/backend",stripPrefix=true,rewriteTargetPath="/v1":/backend/usersis matched and forwarded as/v1/users
Route-level header overrides are tracked by #44, and HTTPS listener support is tracked by #40. Cross-platform roadmap links: VS Code #39, IntelliJ #150, and IntelliJ docs counterpart #157.
- Port Occupation: Ensure the configured port is not occupied by other programs
- Workspace Required: This extension requires an open workspace to function
- Security: This tool is only for local development environment, do not use in production
A: Check if the port is occupied, you can change the port number in the configuration.
A: Ensure one of your mock paths matches the request path (wildcards supported) and the mock configuration is enabled. Also check the stripPrefix setting.
A: Open the VSCode Output panel and select "Intercept Wave" from the dropdown.
A: When enabled, the interceptPrefix is removed before matching. For example:
- Request:
/api/userwith interceptPrefix/api - Match path:
/user - So your mock API path should be configured as
/user
A: rewriteTargetPath runs after stripPrefix and affects both mock matching and upstream forwarding. Query strings are preserved.
- Request:
/backend/users?active=true - Route:
pathPrefix="/backend",stripPrefix=true,rewriteTargetPath="/v1" - Match and forward path:
/v1/users?active=true
This maps common local nginx rules, for example location /backend/ { proxy_pass http://service/v1/; }, to an Intercept Wave route.
A: Use the tab interface at the top of the sidebar:
- Click the + button to add a new group
- Click on tabs to switch between groups
- Right-click a tab or use the Settings button to edit/delete groups
- Each group runs independently on its own port
A: Yes! You can either:
- Click "Start All" to start all enabled groups simultaneously
- Start individual groups one by one by selecting the tab and clicking "Start Server"
- Mix both approaches - some groups started via "Start All", others started individually
If you have any questions or suggestions, feel free to submit an Issue or Pull Request!
MIT License - see the LICENSE file for details
- Compile:
npm run compile - Lint:
npm run lint - Unit tests:
npm run test:unit - All tests:
npm run test - Webview watch (React UI):
npm run webview:watch - Standalone Webview dev server:
npm run webview:dev(http://127.0.0.1:5173) - Build Webview once:
npm run webview:build - Package extension (dev):
npm run package - Create VSIX:
npm run build:local
Notes:
- The UI is implemented with React in
webview/(no HTML templates). All Webview HTML is generated viabuildReactWebviewHtmlto ensure CSP safety. - UI types live under
webview/src/interfaces; backend types undersrc/common/server/types.ts.
