Install
$ agentstack add skill-claude-dev-suite-claude-dev-suite-http-clients ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
HTTP Clients Core Knowledge
> Full Reference: See [advanced.md](advanced.md) for token refresh flow, retry with exponential backoff, request cancellation, and type-safe API client patterns.
> Deep Knowledge: Use mcp__documentation__fetch_docs with technology: http-clients for comprehensive documentation.
Axios Setup
import axios, { AxiosError, InternalAxiosRequestConfig } from 'axios';
const api = axios.create({
baseURL: process.env.NEXT_PUBLIC_API_URL,
timeout: 10000,
headers: { 'Content-Type': 'application/json' },
});
// Request interceptor - add auth token
api.interceptors.request.use(
(config: InternalAxiosRequestConfig) => {
const token = localStorage.getItem('accessToken');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error) => Promise.reject(error)
);
// Response interceptor - handle errors
api.interceptors.response.use(
(response) => response,
(error: AxiosError) => {
if (error.response?.status === 401) {
window.location.href = '/login';
}
return Promise.reject(error);
}
);
Fetch API Wrapper
class ApiError extends Error {
constructor(public status: number, public statusText: string, public data?: unknown) {
super(`${status}: ${statusText}`);
}
}
async function fetchWithTimeout(url: string, options: RequestInit & { timeout?: number } = {}): Promise {
const { timeout = 10000, ...fetchOptions } = options;
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeout);
try {
return await fetch(url, { ...fetchOptions, signal: controller.signal });
} finally {
clearTimeout(timeoutId);
}
}
export async function apiFetch(endpoint: string, options: RequestInit = {}): Promise {
const token = localStorage.getItem('accessToken');
const headers: HeadersInit = {
'Content-Type': 'application/json',
...(token && { Authorization: `Bearer ${token}` }),
};
const response = await fetchWithTimeout(`${API_URL}${endpoint}`, { ...options, headers });
if (!response.ok) {
throw new ApiError(response.status, response.statusText);
}
return response.json();
}
ky (Modern Fetch Wrapper)
import ky from 'ky';
const api = ky.create({
prefixUrl: process.env.NEXT_PUBLIC_API_URL,
timeout: 10000,
retry: {
limit: 2,
methods: ['get', 'put', 'delete'],
statusCodes: [408, 429, 500, 502, 503, 504],
},
hooks: {
beforeRequest: [
(request) => {
const token = localStorage.getItem('accessToken');
if (token) {
request.headers.set('Authorization', `Bearer ${token}`);
}
},
],
},
});
// Usage
const users = await api.get('users').json();
const user = await api.post('users', { json: newUser }).json();
ofetch (Universal Fetch)
import { ofetch } from 'ofetch';
const api = ofetch.create({
baseURL: process.env.NUXT_PUBLIC_API_URL,
retry: 2,
retryDelay: 500,
timeout: 10000,
async onRequest({ options }) {
const token = localStorage.getItem('accessToken');
if (token) {
options.headers = { ...options.headers, Authorization: `Bearer ${token}` };
}
},
});
// Works in Node.js and browser
const users = await api('/users');
When NOT to Use This Skill
- Axios-specific configuration (use
axiosskill) - GraphQL client setup (use
graphql-codegenskill) - tRPC client configuration (use
trpcskill) - WebSocket or Server-Sent Events
Anti-Patterns
| Anti-Pattern | Why It's Bad | Solution | |--------------|--------------|----------| | No timeout configured | Hanging requests | Set timeout on all clients | | Hardcoded API URLs | Environment coupling | Use environment variables | | No retry logic | Poor UX on transient failures | Implement exponential backoff | | Ignoring token expiration | 401 errors | Implement token refresh flow | | Not canceling on unmount | Memory leaks | Use AbortController cleanup | | Not typing responses | Runtime errors | Use TypeScript generics |
Quick Troubleshooting
| Issue | Possible Cause | Solution | |-------|----------------|----------| | CORS errors | Server misconfiguration | Configure CORS on backend | | 401 after some time | Token expired | Implement token refresh | | Memory leaks | Not aborting on unmount | Add cleanup in useEffect | | Network timeout | Server slow | Increase timeout, add retry | | Infinite refresh loop | Refresh returns 401 | Exclude refresh from interceptor |
Production Checklist
- [ ] Base URL via environment
- [ ] Request timeout configured
- [ ] Auth token interceptor
- [ ] Token refresh logic
- [ ] Error response handling
- [ ] Retry with exponential backoff
- [ ] Request cancellation on unmount
- [ ] Type-safe API methods
Reference Documentation
- [Axios Configuration](quick-ref/axios.md)
- [Fetch Patterns](quick-ref/fetch.md)
- [ky and ofetch](quick-ref/ky-ofetch.md)
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: claude-dev-suite
- Source: claude-dev-suite/claude-dev-suite
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.