MCPcopy Index your code
hub / github.com/F4RAN/cuimp-ts

github.com/F4RAN/cuimp-ts @v2.0.2

Chat with this repo
repository ↗ · DeepWiki ↗ · release v2.0.2 ↗ · + Follow
175 symbols 553 edges 49 files 32 documented · 18%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Cuimp

A powerful Node.js wrapper for curl-impersonate

npm version npm downloads License: MIT Node.js Version TypeScript GitHub Release GitHub Stars GitHub Issues

Make HTTP requests that mimic real browser behavior and bypass anti-bot protections with ease.

FeaturesInstallationQuick StartDocumentationExamples


✨ Features

  • 🚀 Browser Impersonation: Mimic Chrome, Firefox, Safari, and Edge browsers
  • 🔧 Easy to Use: Simple API similar to axios/fetch
  • 📦 Zero Dependencies: Only requires tar for binary extraction
  • 🎯 TypeScript Support: Full type definitions included
  • 🔄 Auto Binary Management: Automatically downloads and manages curl-impersonate binaries
  • 🌐 Cross-Platform: Works on Linux, macOS, and Windows
  • 🔒 Proxy Support: Built-in support for HTTP, HTTPS, and SOCKS proxies with authentication
  • 📁 Clean Installation: Binaries stored in package directory, not your project root
  • 🍪 Cookie Management: Automatic cookie storage and sending across requests
  • Error Response Bodies: Returns full HTTP response body on 4xx/5xx errors (like axios/Postman)

📑 Table of Contents

📦 Installation

npm install cuimp

🚀 Quick Start

import { get, post, createCuimpHttp } from 'cuimp'

// Simple GET request
const response = await get('https://httpbin.org/headers')
console.log(response.data)

// POST with data
const result = await post('https://httpbin.org/post', {
  name: 'John Doe',
  email: 'john@example.com',
})

// Using HTTP client instance
const client = createCuimpHttp({
  descriptor: { browser: 'chrome', version: '123' },
})

const data = await client.get('https://api.example.com/users')

Project Usage Examples

Web Scraping with Browser Impersonation

import { get, createCuimpHttp } from 'cuimp'

// Create a client that mimics Chrome 123
const scraper = createCuimpHttp({
  descriptor: { browser: 'chrome', version: '123' },
})

// Scrape a website that blocks regular requests
const response = await scraper.get('https://example.com/protected-content', {
  headers: {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
    Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
  },
})

console.log('Scraped content:', response.data)

API Testing with Different Browsers

import { createCuimpHttp } from 'cuimp'

// Test your API with different browser signatures
const browsers = ['chrome', 'firefox', 'safari', 'edge']

for (const browser of browsers) {
  const client = createCuimpHttp({
    descriptor: { browser, version: 'latest' },
  })

  const response = await client.get('https://your-api.com/test')
  console.log(`${browser}: ${response.status}`)
}

Automatic Cookie Management

import { createCuimpHttp } from 'cuimp'

// Enable automatic cookie management
const client = createCuimpHttp({
  descriptor: { browser: 'chrome', version: '123' },
  cookieJar: true, // Cookies are automatically stored and sent
})

// First request - server sets cookies
await client.get('https://httpbin.org/cookies/set/session_id/abc123')

// Second request - cookies are automatically included
const response = await client.get('https://httpbin.org/cookies')
console.log(response.data.cookies) // { session_id: 'abc123' }

// Access cookies programmatically
const cookieJar = client.getCookieJar()
const cookies = cookieJar.getCookies()

// Clear cookies
client.clearCookies()

// Clean up when done (removes temp cookie file)
client.destroy()

Using with Proxies

import { request } from 'cuimp'

// HTTP proxy
const response1 = await request({
  url: 'https://httpbin.org/ip',
  proxy: 'http://proxy.example.com:8080',
})

// SOCKS5 proxy with authentication
const response2 = await request({
  url: 'https://httpbin.org/ip',
  proxy: 'socks5://user:pass@proxy.example.com:1080',
})

// Automatic proxy detection from environment variables
// HTTP_PROXY, HTTPS_PROXY, ALL_PROXY
const response3 = await request({
  url: 'https://httpbin.org/ip',
  // Will automatically use HTTP_PROXY if set
})

Streaming Responses

import { requestStream } from 'cuimp'

await requestStream(
  { url: 'https://httpbin.org/stream/3', extraCurlArgs: ['--no-buffer'] },
  {
    onHeaders: ({ status, headers }) => {
      console.log('status', status)
      console.log('content-type', headers['Content-Type'])
    },
    onData: chunk => {
      process.stdout.write(chunk)
    },
    onEnd: info => {
      console.log('done', info.status)
    },
    onError: err => {
      console.error('stream error', err)
    },
  }
)

Note: For streaming (SSE or chunked responses), include --no-buffer in extraCurlArgs so curl flushes output immediately. You can also set it on the client defaults:

const client = createCuimpHttp({ extraCurlArgs: ['--no-buffer'] })
await client.requestStream({ url: 'https://httpbin.org/stream/3' }, { onData: chunk => {} })

If you want the full body, enable buffering:

const res = await requestStream({ url: 'https://httpbin.org/stream/3' }, { collectBody: true })
console.log(res.rawBody?.toString('utf8'))

Pre-downloading Binaries

import { Cuimp, downloadBinary } from 'cuimp'

// Method 1: Using Cuimp class
const cuimp = new Cuimp({ descriptor: { browser: 'chrome' } })
const binaryInfo = await cuimp.download()
console.log('Downloaded:', binaryInfo.binaryPath)

// Method 2: Using convenience function
const info = await downloadBinary({
  descriptor: { browser: 'firefox', version: '133' },
})

// Pre-download multiple browsers for offline use
const browsers = ['chrome', 'firefox', 'safari', 'edge']
for (const browser of browsers) {
  await downloadBinary({ descriptor: { browser } })
  console.log(`${browser} binary ready`)
}

Custom Logging

import { createCuimpHttp } from 'cuimp'

// Suppress all logs
const silentLogger = {
  info: () => {},
  warn: () => {},
  error: () => {},
  debug: () => {},
}

const client = createCuimpHttp({
  descriptor: { browser: 'chrome' },
  logger: silentLogger,
})

// Or use a structured logger (Winston, Pino, etc.)
const client = createCuimpHttp({
  descriptor: { browser: 'chrome' },
  logger: myStructuredLogger,
})

API Reference

Convenience Functions

get(url, config?)

Make a GET request.

const response = await get('https://api.example.com/users')

post(url, data?, config?)

Make a POST request.

const response = await post('https://api.example.com/users', {
  name: 'John Doe',
  email: 'john@example.com',
})

put(url, data?, config?)

Make a PUT request.

patch(url, data?, config?)

Make a PATCH request.

del(url, config?)

Make a DELETE request.

head(url, config?)

Make a HEAD request.

options(url, config?)

Make an OPTIONS request.

downloadBinary(options?)

Download curl-impersonate binary without making HTTP requests.

// Download default binary
const info = await downloadBinary()

// Download specific browser binary
const chromeInfo = await downloadBinary({
  descriptor: { browser: 'chrome', version: '123' },
})

HTTP Client

createCuimpHttp(options?)

Create an HTTP client instance.

const client = createCuimpHttp({
  descriptor: { browser: 'chrome', version: '123' },
  path: '/custom/path/to/binary',
})

// Use the client
const response = await client.get('https://api.example.com/data')

request(config)

Make a request with full configuration.

const response = await request({
  url: 'https://api.example.com/users',
  method: 'POST',
  headers: {
    Authorization: 'Bearer token',
    'Content-Type': 'application/json',
  },
  data: { name: 'John Doe' },
  timeout: 5000,
})

requestStream(config, handlers?)

Stream a response body incrementally with callbacks.

const res = await requestStream(
  { url: 'https://httpbin.org/stream/3' },
  {
    onHeaders: ({ status }) => console.log('status', status),
    onData: chunk => process.stdout.write(chunk),
    onEnd: info => console.log('done', info.status),
    onError: err => console.error(err),
  }
)

handlers supports:

interface CuimpStreamHandlers {
  onHeaders?: (info: {
    status: number
    statusText: string
    headers: Record<string, string>
  }) => void
  onData?: (chunk: Buffer) => void
  onEnd?: (info: CuimpStreamResponse) => void
  onError?: (error: Error) => void
  collectBody?: boolean
}

Core Classes

Cuimp

The core class for managing curl-impersonate binaries and descriptors.

import { Cuimp } from 'cuimp'

const cuimp = new Cuimp({
  descriptor: { browser: 'chrome', version: '123' },
  path: '/custom/path',
})

// Verify binary
const info = await cuimp.verifyBinary()

// Build command preview
const command = cuimp.buildCommandPreview('https://example.com', 'GET')

// Download binary without verification
const binaryInfo = await cuimp.download()

CuimpHttp

HTTP client class that wraps the Cuimp core.

import { CuimpHttp, Cuimp } from 'cuimp'

const core = new Cuimp()
const client = new CuimpHttp(core, {
  baseURL: 'https://api.example.com',
  timeout: 10000,
})

CuimpHttp also supports streaming via client.requestStream(config, handlers).

Configuration

CuimpDescriptor

Configure which browser to impersonate:

interface CuimpDescriptor {
  browser?: 'chrome' | 'firefox' | 'edge' | 'safari'
  version?: string // e.g., '136', '2601', '133a', or 'latest' (default)
  architecture?: 'x64' | 'arm64' | 'arm'
  platform?: 'linux' | 'windows' | 'macos' | 'ios' | 'android'
  forceDownload?: boolean // Force re-download even if binary exists
}

Platform values are lowercase (ios, macos); aliases like iOS or macOS are normalized automatically.

When you set platform: 'ios' or platform: 'android' on a desktop host, cuimp downloads the host OS binary (e.g. macOS on a Mac) and selects the browser fingerprint via browser + version (e.g. curl_safari2601). Native iOS/Android binaries are used when running on that OS, or set path to a preinstalled binary.

CuimpRequestConfig

Request configuration options:

interface CuimpRequestConfig {
  url: string
  method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS'
  headers?: Record<string, string>
  data?: any
  timeout?: number
  maxRedirects?: number
  proxy?: string // HTTP, HTTPS, or SOCKS proxy URL
  insecureTLS?: boolean // Skip TLS certificate verification
  signal?: AbortSignal // Request cancellation
}

CuimpOptions

Core options:

interface CuimpOptions {
  descriptor?: CuimpDescriptor
  path?: string // Custom path to curl-impersonate binary
  extraCurlArgs?: string[] // Global curl arguments applied to all requests
  logger?: Logger // Custom logger for binary download/verification messages
  proxy?: string // Default proxy for all requests (HTTP, HTTPS, or SOCKS URL)
  cookieJar?: boolean | string // Enable automatic cookie management
  autoDownload?: boolean // If false, throw error instead of auto-downloading binaries (default: true)
}

Proxy Configuration

Set a default proxy for all requests when creating the client. Per-request proxy in CuimpRequestConfig overrides this.

// Session-level proxy: all requests use this proxy by default
const client = createCuimpHttp({
  proxy: 'http://proxy.example.com:8080',
})

await client.get('https://api.example.com/data') // Uses the proxy

// Override for a single request
await client.get('https://api.example.com/other', {
  proxy: 'socks5://other-proxy:1080',
})

Supported proxy URL formats: http://host:port, https://host:port, socks4://host:port, socks5://host:port, or host:port (defaults to HTTP). Authentication: http://user:pass@host:port.

Cookie Jar Configuration

The cookieJar option enables automatic cookie management:

```typescript // Option 1: Automatic temp file (cleaned up on destroy) const client = createCuimpHttp({ cookieJar: true, })

// Option 2: Custom file path (persists between runs) // Recommended: Use user home directory for security import os from 'os' import path from 'path'

const cookiePath = path.join(os.homedir(), '.

Extension points exported contracts — how you extend this code

CuimpInstance (Interface)
(no doc) [2 implementers]
src/types/cuimpTypes.ts
User (Interface)
(no doc)
test/api.test.ts
User (Interface)
(no doc)
test/integration/index.test.ts
BinaryTarget (Interface)
(no doc)
src/helpers/descriptorNormalize.ts
CuimpDescriptorInput (Interface)
(no doc)
src/types/cuimpTypes.ts
DownloadResult (Interface)
(no doc)
src/helpers/parser.ts
CuimpDescriptor (Interface)
(no doc)
src/types/cuimpTypes.ts
ParsedHttpHeaders (Interface)
(no doc)
src/helpers/parser.ts

Core symbols most depended-on inside this repo

push
called by 82
src/helpers/parser.ts
get
called by 44
src/types/cuimpTypes.ts
runBinary
called by 39
src/runner.ts
createCuimpHttp
called by 36
src/index.ts
error
called by 32
src/types/cuimpTypes.ts
validateDescriptor
called by 25
src/validations/descriptorValidation.ts
setCookie
called by 23
src/helpers/cookieJar.ts
request
called by 21
src/types/cuimpTypes.ts

Shape

Function 91
Method 55
Interface 20
Class 8
Enum 1

Languages

TypeScript100%

Modules by API surface

src/helpers/parser.ts27 symbols
src/types/cuimpTypes.ts24 symbols
src/client.ts22 symbols
src/helpers/cookieJar.ts16 symbols
src/cuimp.ts13 symbols
src/index.ts12 symbols
src/runner.ts11 symbols
src/helpers/descriptorNormalize.ts10 symbols
src/types/curlErrors.ts4 symbols
test/setup.ts3 symbols
src/helpers/connector.ts3 symbols
test/unit/runner.test.ts2 symbols

For agents

$ claude mcp add cuimp-ts \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact