CrawlForge MCP
Alat AsasHandle Hasil1 credit

read_result

Baca semula hasil yang terlalu besar untuk dikembalikan sebaris. Apabila JSON sesuatu alat melebihi max_inline_chars, responsnya membawa preview, result_handle dan truncated: true; hantar handle itu ke sini untuk menghiris teks, mencarinya, menelusurinya mengikut baris atau membaca satu laluan JSON — tanpa mengambil semula halaman atau membayar harga alat itu buat kali kedua.

Kes Penggunaan

Cari Bahagian yang Anda Perlukan

Jalankan search untuk tajuk atau frasa, kemudian slice dari offset padanan — dua panggilan yang membaca satu bahagian halaman panjang dan bukannya keseluruhan hasil.

Telusuri Teks Panjang

lines mengembalikan tetingkap baris dengan has_more, jadi dokumen markdown yang besar dibaca dalam tetingkap yang muat dalam konteks anda.

Tarik Satu Medan daripada JSON Besar

json_path membaca satu laluan daripada hasil crawl_deep, batch_scrape atau deep_research yang tersimpan, atau daripada badan terhurai sesuatu fetch_url JSON.

Jangan Sesekali Ambil Semula

Hasil tersimpan ialah hasil yang sudah anda bayar. Membacanya berkos 1 credit setiap panggilan; menjalankan semula alat itu berkos harga penuhnya dan mengunjungi tapak sekali lagi.

Endpoint

POST/api/v1/tools/read_result
Auth Required
1 req/s pada pelan Free
1 credit

Parameters

handle datang daripada respons dengan truncated: true — alat ini tidak pernah mengambil halaman, ia hanya membaca hasil yang sudah anda miliki. Handle luput 1 jam selepas hasil disimpan.
NameTypeRequiredDefaultDescription
handle
stringRequired-
`result_handle` daripada respons yang terpotong (`res_` diikuti UUID). Hanya boleh dibaca oleh akaun yang menciptanya, selama 1 jam.
Example: res_9f2c1e6a-4b7d-4c3e-8a5f-1d2e3f4a5b6c
operation
stringRequired-
`slice` mengembalikan julat aksara paparan teks; `search` mencari subrentetan literal tanpa mengira huruf besar kecil (bukan regex) dan mengembalikan setiap padanan dengan konteks; `lines` mengembalikan tetingkap baris; `json_path` membaca satu laluan daripada JSON tersimpan.
Example: search
offset
numberOptional0
`slice`: aksara pertama yang dikembalikan. `lines`: indeks baris pertama yang dikembalikan.
Example: 18240
length
numberOptional10000
`slice`: bilangan aksara yang dikembalikan (lalai 10,000). `lines`: bilangan baris yang dikembalikan (lalai 200, paling banyak 5,000).
Example: 4000
query
stringOptional-
Untuk `search` sahaja, dan wajib di situ: teks literal yang dicari, dipadankan tanpa mengira huruf besar kecil.
Example: rate limits
max_matches
numberOptional20
`search`: bilangan maksimum padanan yang dikembalikan, 1-100. `truncated: true` dalam respons bermakna lebih banyak yang sepadan daripada yang dikembalikan.
Example: 5
path
stringOptional-
Untuk `json_path` sahaja, dan wajib di situ: kunci bertitik dan indeks tatasusunan, dalam bentuk titik atau kurungan (`pages.0.url` atau `pages[0].url`); tiada kad bebas, penapis atau hirisan. Dibaca daripada objek hasil tersimpan — atau daripada badan terhurai apabila teks tersimpan ialah JSON, seperti badan `fetch_url`.
Example: pages.0.url
max_inline_chars
numberOptional40000
Jumlah teks terbesar yang dikembalikan sebaris, 1,000-10,000,000 aksara; setiap operasi mengehadkan teks yang dikembalikannya di sini. Bagi `json_path`, `value` yang lebih besar kembali sebagai `value: null` dengan `preview`, `truncated: true` dan amaran untuk menyempitkan laluan.
Example: 40000

Operasi

Setiap respons membawa handle, tool, operation, view, view_path, total_chars dan expires_at, kemudian medan bagi operasi yang anda minta.

slice
Julat aksara paparan teks: offset, length, text dan has_more. Lalai kepada 10,000 aksara pertama.
search
Padanan subrentetan literal tanpa mengira huruf besar kecil, bukan regex: query, matches (setiap satu dengan offset, length, context_offset dan context — 200 aksara di kedua-dua belah), total_matches dan truncated.
lines
Tetingkap baris: first_line, line_count, total_lines, char_offset, lines dan has_more. offset ialah indeks baris pertama, length ialah bilangan baris (lalai 200, paling banyak 5,000).
json_path
Satu laluan daripada objek hasil tersimpan: path, value dan value_chars. Melebihi max_inline_chars, nilai digantikan dengan value: null, preview dan truncated: true, dengan amaran untuk menyempitkan laluan.

Di mana hasil tersimpan berada

Pada API REST, hasil tersimpan ialah nilai setiap akaun yang disimpan selama 1 jam dan hanya boleh dibaca oleh akaun yang menciptanya. Pada pelayan MCP hos sendiri, storan berada pada mesin anda sendiri di bawah ~/.crawlforge/results/ (TTL 1 jam, LRU 200 MB) dan tiada apa-apa dimuat naik. Respons ralat tidak pernah disimpan, dan kerja batch_scrape berkongsi storan yang sama.

Contoh Permintaan

cURL

terminalBash
# 1. A scrape whose JSON exceeded max_inline_chars (default 40,000) came back
#    with a preview instead of the markdown:
#      "truncated": true,
#      "result_handle": "res_9f2c1e6a-4b7d-4c3e-8a5f-1d2e3f4a5b6c",
#      "total_chars": 182406

# 2. Search the stored result for the section you need (1 credit)
curl -X POST https://crawlforge.dev/api/v1/tools/read_result \
  -H "X-API-Key: cf_test_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "handle": "res_9f2c1e6a-4b7d-4c3e-8a5f-1d2e3f4a5b6c",
    "operation": "search",
    "query": "rate limits",
    "max_matches": 5
  }'

# 3. Read the section at the first match offset (1 credit) — no second fetch
curl -X POST https://crawlforge.dev/api/v1/tools/read_result \
  -H "X-API-Key: cf_test_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "handle": "res_9f2c1e6a-4b7d-4c3e-8a5f-1d2e3f4a5b6c",
    "operation": "slice",
    "offset": 18240,
    "length": 4000
  }'

TypeScript

readResult.tsTypescript
// npm install crawlforge-sdk
import { CrawlForge } from 'crawlforge-sdk';

const client = new CrawlForge({ apiKey: process.env.CRAWLFORGE_API_KEY });

// 1. Scrape a long page. Over max_inline_chars (default 40,000 characters of
//    JSON) the markdown is replaced by a preview and a result_handle.
const page = await client.scrape({
  url: 'https://example.com/docs/api',
  formats: ['markdown'],
});

// page.data is untyped in crawlforge-sdk 0.1 — a truncated result carries the
// handle fields shown in the cURL tab instead of the markdown.
const scraped = page.data as
  | { truncated: true; result_handle: string; total_chars: number }
  | { truncated?: false; formats: { markdown: string } };

if (scraped.truncated) {
  const { result_handle, total_chars } = scraped;
  console.log('Stored ' + total_chars + ' characters as ' + result_handle);

  // 2. Search the stored markdown for the section you need (1 credit).
  const found = await client.readResult({
    handle: result_handle,
    operation: 'search',
    query: 'rate limits',
    max_matches: 5,
  });

  // result.data is untyped in crawlforge-sdk 0.1 — its shape is the Response Example below.
  const { matches } = found.data as { matches: { offset: number }[] };

  // 3. Slice from the first match offset (1 credit) — no second fetch.
  const [first] = matches;
  if (first) {
    const section = await client.readResult({
      handle: result_handle,
      operation: 'slice',
      offset: first.offset,
      length: 4000,
    });
    const { text, has_more } = section.data as { text: string; has_more: boolean };
    console.log(text);
    console.log('More after this slice:', has_more);
  }
} else {
  console.log(scraped.formats.markdown); // small enough to arrive inline
}

Python

read_result.pyPython
# pip install crawlforge
from crawlforge import CrawlForge

client = CrawlForge()  # reads CRAWLFORGE_API_KEY

# 1. Scrape a long page. Over max_inline_chars (default 40,000 characters of
#    JSON) the markdown is replaced by a preview and a result_handle.
page = client.scrape(url='https://example.com/docs/api', formats=['markdown'])

# result.data is a plain dict — its shape is the Response Example below.
if page.data.get('truncated'):
    handle = page.data['result_handle']
    print(f"Stored {page.data['total_chars']} characters as {handle}")

    # 2. Search the stored markdown for the section you need (1 credit).
    found = client.read_result(
        handle=handle,
        operation='search',
        query='rate limits',
        max_matches=5,
    )

    # 3. Slice from the first match offset (1 credit) - no second fetch.
    if found.data['matches']:
        first = found.data['matches'][0]
        section = client.read_result(
            handle=handle,
            operation='slice',
            offset=first['offset'],
            length=4000,
        )
        print(section.data['text'])
        print('More after this slice:', section.data['has_more'])
else:
    print(page.data['formats']['markdown'])  # small enough to arrive inline

Contoh Respons

200 OK42ms
{
"success": true,
"data": {
"handle": "res_9f2c1e6a-4b7d-4c3e-8a5f-1d2e3f4a5b6c",
"tool": "scrape",
"operation": "search",
"view": "text",
"view_path": "markdown",
"total_chars": 182406,
"expires_at": "2026-09-05T15:42:10.000Z",
"query": "rate limits",
"matches": [
{
"offset": 18240,
"length": 11,
"context_offset": 18040,
"context": "…request. Every plan is metered per API key.\n\n## Rate limits\n\nEach key may make one request per second on the Free plan…"
},
{
"offset": 61377,
"length": 11,
"context_offset": 61177,
"context": "…returns 429 with a Retry-After header; see the rate limits table above for the per-plan ceilings…"
}
],
"total_matches": 2,
"truncated": false
},
"credits_used": 1,
"credits_remaining": 998,
"processing_time": 42
}
Field Descriptions
data.handleHandle yang anda hantar, dikembalikan semula
data.toolAlat yang menghasilkan hasil tersimpan itu
data.view`text` apabila operasi membaca paparan teks (markdown bagi scrape, badan bagi fetch_url); `json` bagi `json_path`
data.view_pathMedan hasil asal yang menjadi paparan teks
data.total_charsSaiz paparan teks tersimpan, dalam aksara
data.expires_atBila hasil tersimpan dipadamkan — 1 jam selepas ia disimpan
data.matchesSatu entri bagi setiap padanan: `offset` dan `length` merujuk paparan teks; `context` membawa sehingga 200 aksara di kedua-dua belah, bermula pada `context_offset`
data.total_matchesBerapa banyak padanan wujud kesemuanya; `truncated` bernilai true apabila lebih banyak yang sepadan daripada yang dibenarkan `max_matches`
credits_usedCredits yang ditolak bagi permintaan ini (1 setiap bacaan)
credits_remainingBaki credits anda

Pengendalian Ralat

Input Tidak Sah (400 Bad Request)

handle tiada, operation bukan salah satu daripada slice, search, lines atau json_path, search dihantar tanpa query, json_path tanpa path, atau max_matches berada di luar julat 1-100 (VALIDATION_ERROR).

Laluan Tidak Ditemui (400 Bad Request)

json_path tidak dapat menyelesaikan path (PATH_NOT_FOUND); ralat itu menamakan kunci yang tersedia di tempat ia berhenti. Credits tidak ditolak.

Hasil Tidak Ditemui (404 Not Found)

Handle hasil tidak dikenali atau telah luput (RESULT_NOT_FOUND) — hasil disimpan selama 1 jam dan hanya boleh dibaca oleh akaun yang menciptanya. Credits tidak ditolak.

Storan Tidak Tersedia (503 Service Unavailable)

Storan hasil tidak dapat dicapai (STORAGE_UNAVAILABLE). Cuba semula sebentar lagi; tiada caj bagi bacaan yang tidak selesai.

Credits Tidak Mencukupi (402 Payment Required)

Akaun anda tidak mempunyai credits yang mencukupi. Beli lebih banyak credits atau naik taraf pelan anda.

Had Kadar Dilampaui (429 Too Many Requests)

Anda telah melampaui had kadar pelan anda. Tunggu sebentar atau naik taraf pelan anda untuk had yang lebih tinggi.

Petua Pro: search, kemudian slice pada offset padanan, membaca satu bahagian dengan 2 credits. Menelusuri keseluruhan hasil dalam hirisan 10,000 aksara berkos 1 credit setiap hirisan, dan menjalankan semula alat itu berkos harga penuhnya ditambah satu lagi ambilan tapak.

Kos Credits

1 credit
1 credit setiap permintaan
Setiap permintaan read_result berkos 1 credit, apa pun operasinya dan berapa banyak pun yang dikembalikan. Pengikisan itu sendiri sudah dibilkan oleh alat yang menyimpan hasil itu.

Pelan Free: 1,000 credits sekali sahaja = 1,000 permintaan

Pelan Hobby: 5,000 credits/bulan = 5,000 permintaan (USD 19/bulan)

Pelan Professional: 50,000 credits/bulan = 50,000 permintaan (USD 99/bulan)

Pelan Business: 250,000 credits/bulan = 250,000 permintaan (USD 399/bulan)

Alat Berkaitan

scrape
Sumber biasa result_handle — max_inline_chars menetapkan berapa banyak yang tiba sebaris (2 credits)
crawl_deep
Perayapan berbilang halaman ialah hasil terbesar; json_path membaca satu halaman daripada perayapan tersimpan (4 credits)
fetch_url
Badan JSON yang melebihi had sebaris turut disimpan; json_path membaca badan terhurainya (1 credit)
get_batch_results
Menelusuri kerja batch_scrape; hasil tersimpan kelompok itu berkongsi storan 1 jam yang sama (1 credit)
Sedia mencuba read_result? Daftar secara percuma dan dapatkan 1,000 credits untuk mula membina.

Footer

CrawlForge MCP

Web scraping gred perusahaan untuk Ejen AI. 30 alat MCP khusus yang direka untuk pembangun moden yang membina sistem pintar.

Produk

  • Ciri
  • Playground
  • Harga
  • Kes Penggunaan
  • Integrasi
  • Alternatif
  • Changelog

Sumber

  • Mula Bekerja
  • Rujukan API
  • Templat
  • Panduan
  • Blog
  • Glosari
  • Soalan Lazim
  • Peta Laman

Pembangun

  • Protokol MCP
  • Claude Desktop
  • Cursor IDE
  • LangChain
  • LlamaIndex

Syarikat

  • Tentang
  • Hubungi
  • Privasi
  • Terma
  • Penggunaan Boleh Diterima
  • Keselamatan
  • Cookies

Kekal dikemas kini

Dapatkan kemas kini terkini tentang alat dan ciri baharu.

Dibina dengan Next.js dan protokol MCP

© 2025-2026 CrawlForge. Hak cipta terpelihara.