graphor 0.17.0 → 0.19.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,38 +1,18 @@
1
- <<<<<<< HEAD
2
1
  # Graphor TypeScript SDK
3
- =======
4
- # Graphor TypeScript API Library
5
- >>>>>>> origin/generated--merge-conflict
6
2
 
7
- [![NPM version](https://img.shields.io/npm/v/graphor.svg?label=npm%20(stable))](https://npmjs.org/package/graphor)
3
+ [![NPM version](<https://img.shields.io/npm/v/graphor.svg?label=npm%20(stable)>)](https://npmjs.org/package/graphor)
8
4
  [![TypeScript](https://img.shields.io/badge/TypeScript-4.9+-blue.svg)](https://www.typescriptlang.org/)
9
5
 
10
- <<<<<<< HEAD
11
6
  The official TypeScript SDK for the [Graphor](https://graphorlm.com) API. Build intelligent document applications with ease.
12
7
 
13
8
  **Features:**
9
+
14
10
  - 📄 **Document Ingestion** — Upload files, web pages, GitHub repos, and YouTube videos
15
11
  - 💬 **Document Chat** — Ask questions with conversational memory
16
12
  - 📊 **Structured Extraction** — Extract data using JSON Schema
17
13
  - 🔍 **Semantic Search** — Retrieve relevant chunks for custom RAG pipelines
18
14
  - 🔒 **Type Safety** — Complete TypeScript definitions for all params and responses
19
15
  - 🌐 **Multi-Runtime** — Works in Node.js, Deno, Bun, and browsers
20
- =======
21
- This library provides convenient access to the Graphor REST API from server-side TypeScript or JavaScript.
22
-
23
- The REST API documentation can be found on [docs.graphorlm.com](https://docs.graphorlm.com). The full API of this library can be found in [api.md](api.md).
24
-
25
- It is generated with [Stainless](https://www.stainless.com/).
26
- >>>>>>> origin/generated--merge-conflict
27
-
28
- ## MCP Server
29
-
30
- Use the Graphor MCP Server to enable AI assistants to interact with this API, allowing them to explore endpoints, make test requests, and use documentation to help integrate this SDK into your application.
31
-
32
- [![Add to Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en-US/install-mcp?name=graphor-mcp&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsImdyYXBob3ItbWNwIl0sImVudiI6eyJHUkFQSE9SX0FQSV9LRVkiOiJNeSBBUEkgS2V5In19)
33
- [![Install in VS Code](https://img.shields.io/badge/_-Add_to_VS_Code-blue?style=for-the-badge&logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9Im5vbmUiIHZpZXdCb3g9IjAgMCA0MCA0MCI+PHBhdGggZmlsbD0iI0VFRSIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMzAuMjM1IDM5Ljg4NGEyLjQ5MSAyLjQ5MSAwIDAgMS0xLjc4MS0uNzNMMTIuNyAyNC43OGwtMy40NiAyLjYyNC0zLjQwNiAyLjU4MmExLjY2NSAxLjY2NSAwIDAgMS0xLjA4Mi4zMzggMS42NjQgMS42NjQgMCAwIDEtMS4wNDYtLjQzMWwtMi4yLTJhMS42NjYgMS42NjYgMCAwIDEgMC0yLjQ2M0w3LjQ1OCAyMCA0LjY3IDE3LjQ1MyAxLjUwNyAxNC41N2ExLjY2NSAxLjY2NSAwIDAgMSAwLTIuNDYzbDIuMi0yYTEuNjY1IDEuNjY1IDAgMCAxIDIuMTMtLjA5N2w2Ljg2MyA1LjIwOUwyOC40NTIuODQ0YTIuNDg4IDIuNDg4IDAgMCAxIDEuODQxLS43MjljLjM1MS4wMDkuNjk5LjA5MSAxLjAxOS4yNDVsOC4yMzYgMy45NjFhMi41IDIuNSAwIDAgMSAxLjQxNSAyLjI1M3YuMDk5LS4wNDVWMzMuMzd2LS4wNDUuMDk1YTIuNTAxIDIuNTAxIDAgMCAxLTEuNDE2IDIuMjU3bC04LjIzNSAzLjk2MWEyLjQ5MiAyLjQ5MiAwIDAgMS0xLjA3Ny4yNDZabS43MTYtMjguOTQ3LTExLjk0OCA5LjA2MiAxMS45NTIgOS4wNjUtLjAwNC0xOC4xMjdaIi8+PC9zdmc+)](https://vscode.stainless.com/mcp/%7B%22name%22%3A%22graphor-mcp%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22graphor-mcp%22%5D%2C%22env%22%3A%7B%22GRAPHOR_API_KEY%22%3A%22My%20API%20Key%22%7D%7D)
34
-
35
- > Note: You may need to set environment variables in your MCP client.
36
16
 
37
17
  ## Documentation
38
18
 
@@ -46,25 +26,9 @@ npm install graphor
46
26
 
47
27
  Or with your preferred package manager:
48
28
 
49
- <<<<<<< HEAD
50
29
  ```bash
51
30
  yarn add graphor
52
31
  pnpm add graphor
53
- =======
54
- The full API of this library can be found in [api.md](api.md).
55
-
56
- <!-- prettier-ignore -->
57
- ```js
58
- import Graphor from 'graphor';
59
-
60
- const client = new Graphor({
61
- apiKey: process.env['GRAPHOR_API_KEY'], // This is the default and can be omitted
62
- });
63
-
64
- const response = await client.sources.ingestURL({ url: 'url' });
65
-
66
- console.log(response.build_id);
67
- >>>>>>> origin/generated--merge-conflict
68
32
  ```
69
33
 
70
34
  ## Quick Start
@@ -73,28 +37,21 @@ console.log(response.build_id);
73
37
  import Graphor from 'graphor';
74
38
  import fs from 'fs';
75
39
 
76
- <<<<<<< HEAD
77
- const client = new Graphor(); // Uses GRAPHOR_API_KEY env var
40
+ const client = new Graphor(); // Uses GRAPHOR_API_KEY env var
78
41
 
79
42
  // Upload a document
80
43
  const source = await client.sources.upload({ file: fs.createReadStream('document.pdf') });
81
44
  console.log(`Uploaded: ${source.file_name}`);
82
45
 
46
+ // Process with a parsing strategy
47
+ await client.sources.parse({
48
+ file_name: source.file_name,
49
+ partition_method: 'graphorlm', // Options: basic (Fast), hi_res (Balanced), hi_res_ft (Accurate), mai (VLM), graphorlm (Agentic)
50
+ });
51
+
83
52
  // Ask questions about your documents
84
53
  const response = await client.sources.ask({ question: 'What are the main topics?' });
85
54
  console.log(`Answer: ${response.answer}`);
86
- =======
87
- <!-- prettier-ignore -->
88
- ```ts
89
- import Graphor from 'graphor';
90
-
91
- const client = new Graphor({
92
- apiKey: process.env['GRAPHOR_API_KEY'], // This is the default and can be omitted
93
- });
94
-
95
- const params: Graphor.SourceIngestURLParams = { url: 'url' };
96
- const response: Graphor.SourceIngestURLResponse = await client.sources.ingestURL(params);
97
- >>>>>>> origin/generated--merge-conflict
98
55
  ```
99
56
 
100
57
  ## Authentication
@@ -108,7 +65,7 @@ export GRAPHOR_API_KEY="grlm_your_api_key_here"
108
65
  ```typescript
109
66
  import Graphor from 'graphor';
110
67
 
111
- const client = new Graphor(); // Automatically uses GRAPHOR_API_KEY
68
+ const client = new Graphor(); // Automatically uses GRAPHOR_API_KEY
112
69
  ```
113
70
 
114
71
  Or pass it directly:
@@ -154,7 +111,7 @@ Reprocess documents with different OCR/parsing methods:
154
111
  // Reprocess with high-resolution parsing
155
112
  const source = await client.sources.parse({
156
113
  file_name: 'document.pdf',
157
- partition_method: 'hi_res' // Options: basic, hi_res, hi_res_ft, mai, graphorlm
114
+ partition_method: 'hi_res', // Options: basic, hi_res, hi_res_ft, mai, graphorlm
158
115
  });
159
116
  ```
160
117
 
@@ -167,21 +124,21 @@ Ask questions about your documents with conversational memory:
167
124
  ```typescript
168
125
  // Ask a question
169
126
  const response = await client.sources.ask({
170
- question: 'What are the key findings?'
127
+ question: 'What are the key findings?',
171
128
  });
172
129
  console.log(response.answer);
173
130
 
174
131
  // Follow-up question (maintains context)
175
132
  const followUp = await client.sources.ask({
176
133
  question: 'Can you elaborate on the first point?',
177
- conversation_id: response.conversation_id
134
+ conversation_id: response.conversation_id,
178
135
  });
179
136
  console.log(followUp.answer);
180
137
 
181
138
  // Scope to specific documents
182
139
  const scopedResponse = await client.sources.ask({
183
140
  question: 'Compare these two reports',
184
- file_names: ['report-2023.pdf', 'report-2024.pdf']
141
+ file_names: ['report-2023.pdf', 'report-2024.pdf'],
185
142
  });
186
143
  ```
187
144
 
@@ -206,12 +163,12 @@ const result = await client.sources.extract({
206
163
  type: 'object',
207
164
  properties: {
208
165
  description: { type: 'string' },
209
- amount: { type: 'number' }
210
- }
211
- }
212
- }
213
- }
214
- }
166
+ amount: { type: 'number' },
167
+ },
168
+ },
169
+ },
170
+ },
171
+ },
215
172
  });
216
173
 
217
174
  console.log(result.structured_output);
@@ -227,7 +184,7 @@ Build custom RAG pipelines with semantic search:
227
184
  ```typescript
228
185
  // Retrieve relevant chunks
229
186
  const result = await client.sources.retrieveChunks({
230
- query: 'What are the payment terms?'
187
+ query: 'What are the payment terms?',
231
188
  });
232
189
 
233
190
  for (const chunk of result.chunks) {
@@ -238,7 +195,7 @@ for (const chunk of result.chunks) {
238
195
  }
239
196
 
240
197
  // Use with your preferred LLM
241
- const context = result.chunks.map(c => c.text).join('\n');
198
+ const context = result.chunks.map((c) => c.text).join('\n');
242
199
  // Pass context to OpenAI, Anthropic, etc.
243
200
  ```
244
201
 
@@ -259,7 +216,7 @@ for (const source of sources) {
259
216
  const elements = await client.sources.loadElements({
260
217
  file_name: 'document.pdf',
261
218
  page: 1,
262
- page_size: 50
219
+ page_size: 50,
263
220
  });
264
221
 
265
222
  // Delete a source
@@ -276,7 +233,6 @@ import Graphor, { toFile } from 'graphor';
276
233
 
277
234
  const client = new Graphor();
278
235
 
279
- <<<<<<< HEAD
280
236
  // Using fs.createReadStream (Node.js)
281
237
  await client.sources.upload({ file: fs.createReadStream('/path/to/file') });
282
238
 
@@ -288,20 +244,6 @@ await client.sources.upload({ file: await fetch('https://somesite/file') });
288
244
 
289
245
  // Using toFile helper
290
246
  await client.sources.upload({ file: await toFile(Buffer.from('my bytes'), 'file') });
291
- =======
292
- // If you have access to Node `fs` we recommend using `fs.createReadStream()`:
293
- await client.sources.ingestFile({ file: fs.createReadStream('/path/to/file') });
294
-
295
- // Or if you have the web `File` API you can pass a `File` instance:
296
- await client.sources.ingestFile({ file: new File(['my bytes'], 'file') });
297
-
298
- // You can also pass a `fetch` `Response`:
299
- await client.sources.ingestFile({ file: await fetch('https://somesite/file') });
300
-
301
- // Finally, if none of the above are convenient, you can use our `toFile` helper:
302
- await client.sources.ingestFile({ file: await toFile(Buffer.from('my bytes'), 'file') });
303
- await client.sources.ingestFile({ file: await toFile(new Uint8Array([0, 1, 2]), 'file') });
304
- >>>>>>> origin/generated--merge-conflict
305
247
  ```
306
248
 
307
249
  ## Error Handling
@@ -309,7 +251,6 @@ await client.sources.ingestFile({ file: await toFile(new Uint8Array([0, 1, 2]),
309
251
  ```typescript
310
252
  import Graphor from 'graphor';
311
253
 
312
- <<<<<<< HEAD
313
254
  const client = new Graphor();
314
255
 
315
256
  try {
@@ -331,69 +272,35 @@ try {
331
272
  throw err;
332
273
  }
333
274
  }
334
- =======
335
- <!-- prettier-ignore -->
336
- ```ts
337
- const response = await client.sources.ingestURL({ url: 'url' }).catch(async (err) => {
338
- if (err instanceof Graphor.APIError) {
339
- console.log(err.status); // 400
340
- console.log(err.name); // BadRequestError
341
- console.log(err.headers); // {server: 'nginx', ...}
342
- } else {
343
- throw err;
344
- }
345
- });
346
- >>>>>>> origin/generated--merge-conflict
347
275
  ```
348
276
 
349
- | Status Code | Error Type |
350
- |-------------|------------|
351
- | 400 | `BadRequestError` |
352
- | 401 | `AuthenticationError` |
353
- | 403 | `PermissionDeniedError` |
354
- | 404 | `NotFoundError` |
355
- | 422 | `UnprocessableEntityError` |
356
- | 429 | `RateLimitError` |
357
- | ≥500 | `InternalServerError` |
358
- | N/A | `APIConnectionError` |
277
+ | Status Code | Error Type |
278
+ | ----------- | -------------------------- |
279
+ | 400 | `BadRequestError` |
280
+ | 401 | `AuthenticationError` |
281
+ | 403 | `PermissionDeniedError` |
282
+ | 404 | `NotFoundError` |
283
+ | 422 | `UnprocessableEntityError` |
284
+ | 429 | `RateLimitError` |
285
+ | ≥500 | `InternalServerError` |
286
+ | N/A | `APIConnectionError` |
359
287
 
360
288
  ## Configuration
361
289
 
362
290
  ### Retries
363
291
 
364
- <<<<<<< HEAD
365
292
  Requests are automatically retried twice with exponential backoff:
366
- =======
367
- Certain errors will be automatically retried 0 times by default, with a short exponential backoff.
368
- Connection errors (for example, due to a network connectivity problem), 408 Request Timeout, 409 Conflict,
369
- 429 Rate Limit, and >=500 Internal errors will all be retried by default.
370
- >>>>>>> origin/generated--merge-conflict
371
293
 
372
294
  ```typescript
373
295
  // Configure default retries
374
296
  const client = new Graphor({ maxRetries: 5 });
375
297
 
376
- <<<<<<< HEAD
377
298
  // Or per-request
378
299
  await client.sources.ask({ question: '...' }, { maxRetries: 3 });
379
- =======
380
- <!-- prettier-ignore -->
381
- ```js
382
- // Configure the default for all requests:
383
- const client = new Graphor({
384
- maxRetries: 0, // default is 2
385
- });
386
-
387
- // Or, configure per-request:
388
- await client.sources.ingestURL({ url: 'url' }, {
389
- maxRetries: 5,
390
- });
391
- >>>>>>> origin/generated--merge-conflict
392
300
  ```
393
301
 
394
302
  ### Timeouts
395
303
 
396
- <<<<<<< HEAD
397
304
  Default timeout is 60 seconds:
398
305
 
399
306
  ```typescript
@@ -403,7 +310,7 @@ const client = new Graphor({ timeout: 120 * 1000 });
403
310
  // Or per-request
404
311
  await client.sources.parse(
405
312
  { file_name: 'large-document.pdf', partition_method: 'graphorlm' },
406
- { timeout: 300 * 1000 }
313
+ { timeout: 300 * 1000 },
407
314
  );
408
315
  ```
409
316
 
@@ -422,33 +329,17 @@ console.log(`✅ Uploaded: ${source.file_name}`);
422
329
  // 2. Process with advanced parsing
423
330
  const processed = await client.sources.parse({
424
331
  file_name: source.file_name,
425
- partition_method: 'hi_res'
426
- =======
427
- Requests time out after 10 minutes by default. You can configure this with a `timeout` option:
428
-
429
- <!-- prettier-ignore -->
430
- ```ts
431
- // Configure the default for all requests:
432
- const client = new Graphor({
433
- timeout: 20 * 1000, // 20 seconds (default is 10 minutes)
434
- >>>>>>> origin/generated--merge-conflict
332
+ partition_method: 'hi_res',
435
333
  });
436
334
  console.log(`✅ Processed: ${processed.status}`);
437
335
 
438
- <<<<<<< HEAD
439
336
  // 3. Ask questions
440
337
  const response = await client.sources.ask({
441
338
  question: 'What are the key terms of this contract?',
442
- file_names: [source.file_name]
443
- =======
444
- // Override per-request:
445
- await client.sources.ingestURL({ url: 'url' }, {
446
- timeout: 5 * 1000,
447
- >>>>>>> origin/generated--merge-conflict
339
+ file_names: [source.file_name],
448
340
  });
449
341
  console.log(`📝 Answer: ${response.answer}`);
450
342
 
451
- <<<<<<< HEAD
452
343
  // 4. Extract structured data
453
344
  const extracted = await client.sources.extract({
454
345
  file_names: [source.file_name],
@@ -459,260 +350,128 @@ const extracted = await client.sources.extract({
459
350
  parties: { type: 'array', items: { type: 'string' } },
460
351
  effective_date: { type: 'string' },
461
352
  termination_date: { type: 'string' },
462
- total_value: { type: 'number' }
463
- }
464
- }
465
- =======
466
- On timeout, an `APIConnectionTimeoutError` is thrown.
467
-
468
- Note that requests which time out will be [retried twice by default](#retries).
469
-
470
- ## Advanced Usage
471
-
472
- ### Accessing raw Response data (e.g., headers)
473
-
474
- The "raw" `Response` returned by `fetch()` can be accessed through the `.asResponse()` method on the `APIPromise` type that all methods return.
475
- This method returns as soon as the headers for a successful response are received and does not consume the response body, so you are free to write custom parsing or streaming logic.
476
-
477
- You can also use the `.withResponse()` method to get the raw `Response` along with the parsed data.
478
- Unlike `.asResponse()` this method consumes the body, returning once it is parsed.
479
-
480
- <!-- prettier-ignore -->
481
- ```ts
482
- const client = new Graphor();
483
-
484
- const response = await client.sources.ingestURL({ url: 'url' }).asResponse();
485
- console.log(response.headers.get('X-My-Header'));
486
- console.log(response.statusText); // access the underlying Response object
487
-
488
- const { data: response, response: raw } = await client.sources
489
- .ingestURL({ url: 'url' })
490
- .withResponse();
491
- console.log(raw.headers.get('X-My-Header'));
492
- console.log(response.build_id);
493
- ```
494
-
495
- ### Logging
496
-
497
- > [!IMPORTANT]
498
- > All log messages are intended for debugging only. The format and content of log messages
499
- > may change between releases.
500
-
501
- #### Log levels
502
-
503
- The log level can be configured in two ways:
504
-
505
- 1. Via the `GRAPHOR_LOG` environment variable
506
- 2. Using the `logLevel` client option (overrides the environment variable if set)
507
-
508
- ```ts
509
- import Graphor from 'graphor';
510
-
511
- const client = new Graphor({
512
- logLevel: 'debug', // Show all log messages
513
- >>>>>>> origin/generated--merge-conflict
353
+ total_value: { type: 'number' },
354
+ },
355
+ },
514
356
  });
515
357
  console.log(`📊 Extracted: ${JSON.stringify(extracted.structured_output)}`);
516
358
 
517
- <<<<<<< HEAD
518
359
  // 5. Build custom RAG
519
360
  const chunks = await client.sources.retrieveChunks({
520
361
  query: 'payment obligations',
521
- file_names: [source.file_name]
522
- =======
523
- Available log levels, from most to least verbose:
524
-
525
- - `'debug'` - Show debug messages, info, warnings, and errors
526
- - `'info'` - Show info messages, warnings, and errors
527
- - `'warn'` - Show warnings and errors (default)
528
- - `'error'` - Show only errors
529
- - `'off'` - Disable all logging
530
-
531
- At the `'debug'` level, all HTTP requests and responses are logged, including headers and bodies.
532
- Some authentication-related headers are redacted, but sensitive data in request and response bodies
533
- may still be visible.
534
-
535
- #### Custom logger
536
-
537
- By default, this library logs to `globalThis.console`. You can also provide a custom logger.
538
- Most logging libraries are supported, including [pino](https://www.npmjs.com/package/pino), [winston](https://www.npmjs.com/package/winston), [bunyan](https://www.npmjs.com/package/bunyan), [consola](https://www.npmjs.com/package/consola), [signale](https://www.npmjs.com/package/signale), and [@std/log](https://jsr.io/@std/log). If your logger doesn't work, please open an issue.
539
-
540
- When providing a custom logger, the `logLevel` option still controls which messages are emitted, messages
541
- below the configured level will not be sent to your logger.
542
-
543
- ```ts
544
- import Graphor from 'graphor';
545
- import pino from 'pino';
546
-
547
- const logger = pino();
548
-
549
- const client = new Graphor({
550
- logger: logger.child({ name: 'Graphor' }),
551
- logLevel: 'debug', // Send all messages to pino, allowing it to filter
552
- >>>>>>> origin/generated--merge-conflict
362
+ file_names: [source.file_name],
553
363
  });
554
364
  console.log(`🔍 Found ${chunks.total} relevant chunks`);
555
365
  ```
556
366
 
557
- ## API Reference
367
+ ## MCP Server
558
368
 
559
- ### Sources
369
+ Use the Graphor MCP Server to enable AI assistants to interact with this API, allowing them to explore endpoints, make test requests, and use documentation to help integrate this SDK into your application.
560
370
 
561
- | Method | Description | Docs |
562
- |--------|-------------|------|
563
- | `sources.upload()` | Upload a local file | [📖](https://docs.graphorlm.com/sdk/sources/upload#upload-a-file) |
564
- | `sources.uploadUrl()` | Upload from web URL | [📖](https://docs.graphorlm.com/sdk/sources/upload#upload-from-url) |
565
- | `sources.uploadGithub()` | Upload from GitHub | [📖](https://docs.graphorlm.com/sdk/sources/upload#upload-from-github) |
566
- | `sources.uploadYoutube()` | Upload from YouTube | [📖](https://docs.graphorlm.com/sdk/sources/upload#upload-from-youtube) |
567
- | `sources.parse()` | Reprocess with different method | [📖](https://docs.graphorlm.com/sdk/sources/process) |
568
- | `sources.list()` | List all sources | [📖](https://docs.graphorlm.com/sdk/sources/list) |
569
- | `sources.delete()` | Delete a source | [📖](https://docs.graphorlm.com/sdk/sources/delete) |
570
- | `sources.loadElements()` | Get parsed elements | [📖](https://docs.graphorlm.com/sdk/sources/list-elements) |
371
+ [![Add to Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en-US/install-mcp?name=graphor-mcp&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsImdyYXBob3ItbWNwIl0sImVudiI6eyJHUkFQSE9SX0FQSV9LRVkiOiJNeSBBUEkgS2V5In19)
372
+ [![Install in VS Code](https://img.shields.io/badge/_-Add_to_VS_Code-blue?style=for-the-badge&logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9Im5vbmUiIHZpZXdCb3g9IjAgMCA0MCA0MCI+PHBhdGggZmlsbD0iI0VFRSIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMzAuMjM1IDM5Ljg4NGEyLjQ5MSAyLjQ5MSAwIDAgMS0xLjc4MS0uNzNMMTIuNyAyNC43OGwtMy40NiAyLjYyNC0zLjQwNiAyLjU4MmExLjY2NSAxLjY2NSAwIDAgMS0xLjA4Mi4zMzggMS42NjQgMS42NjQgMCAwIDEtMS4wNDYtLjQzMWwtMi4yLTJhMS42NjYgMS42NjYgMCAwIDEgMC0yLjQ2M0w3LjQ1OCAyMCA0LjY3IDE3LjQ1MyAxLjUwNyAxNC41N2ExLjY2NSAxLjY2NSAwIDAgMSAwLTIuNDYzbDIuMi0yYTEuNjY1IDEuNjY1IDAgMCAxIDIuMTMtLjA5N2w2Ljg2MyA1LjIwOUwyOC40NTIuODQ0YTIuNDg4IDIuNDg4IDAgMCAxIDEuODQxLS43MjljLjM1MS4wMDkuNjk5LjA5MSAxLjAxOS4yNDVsOC4yMzYgMy45NjFhMi41IDIuNSAwIDAgMSAxLjQxNSAyLjI1M3YuMDk5LS4wNDVWMzMuMzd2LS4wNDUuMDk1YTIuNTAxIDIuNTAxIDAgMCAxLTEuNDE2IDIuMjU3bC04LjIzNSAzLjk2MWEyLjQ5MiAyLjQ5MiAwIDAgMS0xLjA3Ny4yNDZabS43MTYtMjguOTQ3LTExLjk0OCA5LjA2MiAxMS45NTIgOS4wNjUtLjAwNC0xOC4xMjdaIi8+PC9zdmc+)](https://vscode.stainless.com/mcp/%7B%22name%22%3A%22graphor-mcp%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22graphor-mcp%22%5D%2C%22env%22%3A%7B%22GRAPHOR_API_KEY%22%3A%22My%20API%20Key%22%7D%7D)
571
373
 
572
- ### Chat & AI
374
+ Or manually add it to your MCP client's configuration:
573
375
 
574
- | Method | Description | Docs |
575
- |--------|-------------|------|
576
- | `sources.ask()` | Ask questions about documents | [📖](https://docs.graphorlm.com/sdk/chat) |
577
- | `sources.extract()` | Extract structured data | [📖](https://docs.graphorlm.com/sdk/extract) |
578
- | `sources.retrieveChunks()` | Retrieve chunks for RAG | [📖](https://docs.graphorlm.com/sdk/prebuilt-rag) |
376
+ ```json
377
+ {
378
+ "mcpServers": {
379
+ "graphor_api": {
380
+ "command": "npx",
381
+ "args": ["-y", "graphor-mcp@latest"],
382
+ "env": {
383
+ "GRAPHOR_API_KEY": "grlm_your_api_key_here"
384
+ }
385
+ }
386
+ }
387
+ }
388
+ ```
579
389
 
580
- ## TypeScript Support
390
+ > Note: You may need to set environment variables in your MCP client.
581
391
 
582
- This library includes complete TypeScript definitions for all request params and response fields:
392
+ ### Remote MCP Server (Web Apps & Agentic Workflows)
583
393
 
584
- ```typescript
585
- import Graphor from 'graphor';
394
+ For web-based AI clients (e.g. [Claude.ai](https://claude.ai)) or agentic frameworks (e.g. LangChain, CrewAI) that cannot run local `npx` processes, use the hosted remote MCP server. Authentication is handled via **OAuth** — a browser window will open for you to log in.
586
395
 
587
- const client = new Graphor();
588
-
589
- // Type-safe params and responses
590
- const params: Graphor.SourceUploadParams = { file: fs.createReadStream('path/to/file') };
591
- const source: Graphor.PublicSource = await client.sources.upload(params);
592
396
  ```
593
-
594
- <<<<<<< HEAD
595
- Documentation for each method, request param, and response field are available in docstrings and will appear on hover in most modern editors.
596
- =======
597
- #### Undocumented request params
598
-
599
- To make requests using undocumented parameters, you may use `// @ts-expect-error` on the undocumented
600
- parameter. This library doesn't validate at runtime that the request matches the type, so any extra values you
601
- send will be sent as-is.
602
-
603
- ```ts
604
- client.sources.ingestURL({
605
- // ...
606
- // @ts-expect-error baz is not yet public
607
- baz: 'undocumented option',
608
- });
397
+ https://mcp.graphor.workers.dev/sse
609
398
  ```
610
399
 
611
- For requests with the `GET` verb, any extra params will be in the query, all other requests will send the
612
- extra param in the body.
613
-
614
- If you want to explicitly send an extra argument, you can do so with the `query`, `body`, and `headers` request
615
- options.
400
+ **Web apps (e.g. Claude.ai)** in Claude.ai, go to **Settings > Connectors > Add custom connector**, fill in the name and the remote MCP server URL. You will be redirected to log in through the OAuth flow:
616
401
 
617
- #### Undocumented response properties
618
-
619
- To access undocumented response properties, you may access the response object with `// @ts-expect-error` on
620
- the response object, or cast the response object to the requisite type. Like the request params, we do not
621
- validate or strip extra properties from the response from the API.
622
-
623
- ### Customizing the fetch client
624
-
625
- By default, this library expects a global `fetch` function is defined.
626
-
627
- If you want to use a different `fetch` function, you can either polyfill the global:
628
-
629
- ```ts
630
- import fetch from 'my-fetch';
631
-
632
- globalThis.fetch = fetch;
633
402
  ```
634
-
635
- Or pass it to the client:
636
-
637
- ```ts
638
- import Graphor from 'graphor';
639
- import fetch from 'my-fetch';
640
-
641
- const client = new Graphor({ fetch });
403
+ https://mcp.graphor.workers.dev/sse
642
404
  ```
643
405
 
644
- ### Fetch options
645
-
646
- If you want to set custom `fetch` options without overriding the `fetch` function, you can provide a `fetchOptions` object when instantiating the client or making a request. (Request-specific options override client options.)
647
-
648
- ```ts
649
- import Graphor from 'graphor';
406
+ **Desktop clients (e.g. Claude Desktop)** — use [`mcp-remote`](https://www.npmjs.com/package/mcp-remote) as a local proxy:
650
407
 
651
- const client = new Graphor({
652
- fetchOptions: {
653
- // `RequestInit` options
654
- },
655
- });
408
+ ```json
409
+ {
410
+ "mcpServers": {
411
+ "graphor_api": {
412
+ "command": "npx",
413
+ "args": ["mcp-remote", "https://mcp.graphor.workers.dev/sse"]
414
+ }
415
+ }
416
+ }
656
417
  ```
657
418
 
658
- #### Configuring proxies
659
-
660
- To modify proxy behavior, you can provide custom `fetchOptions` that add runtime-specific proxy
661
- options to requests:
662
-
663
- <img src="https://raw.githubusercontent.com/stainless-api/sdk-assets/refs/heads/main/node.svg" align="top" width="18" height="21"> **Node** <sup>[[docs](https://github.com/nodejs/undici/blob/main/docs/docs/api/ProxyAgent.md#example---proxyagent-with-fetch)]</sup>
419
+ **Agentic workflows (e.g. LangChain)** — connect via SSE transport:
664
420
 
665
- ```ts
666
- import Graphor from 'graphor';
667
- import * as undici from 'undici';
421
+ ```typescript
422
+ import { MultiServerMCPClient } from '@langchain/mcp-adapters';
668
423
 
669
- const proxyAgent = new undici.ProxyAgent('http://localhost:8888');
670
- const client = new Graphor({
671
- fetchOptions: {
672
- dispatcher: proxyAgent,
424
+ const client = new MultiServerMCPClient({
425
+ graphor: {
426
+ url: 'https://mcp.graphor.workers.dev/sse',
427
+ transport: 'sse',
673
428
  },
674
429
  });
430
+
431
+ const tools = await client.getTools();
432
+ // Use tools with your LangChain agent
675
433
  ```
676
434
 
677
- <img src="https://raw.githubusercontent.com/stainless-api/sdk-assets/refs/heads/main/bun.svg" align="top" width="18" height="21"> **Bun** <sup>[[docs](https://bun.sh/guides/http/proxy)]</sup>
435
+ See the [MCP Server README](./packages/mcp-server/README.md) for more details.
678
436
 
679
- ```ts
680
- import Graphor from 'graphor';
437
+ ## API Reference
681
438
 
682
- const client = new Graphor({
683
- fetchOptions: {
684
- proxy: 'http://localhost:8888',
685
- },
686
- });
687
- ```
439
+ ### Sources
688
440
 
689
- <img src="https://raw.githubusercontent.com/stainless-api/sdk-assets/refs/heads/main/deno.svg" align="top" width="18" height="21"> **Deno** <sup>[[docs](https://docs.deno.com/api/deno/~/Deno.createHttpClient)]</sup>
441
+ | Method | Description | Docs |
442
+ | ------------------------- | ------------------------------- | ----------------------------------------------------------------------- |
443
+ | `sources.upload()` | Upload a local file | [📖](https://docs.graphorlm.com/sdk/sources/upload#upload-a-file) |
444
+ | `sources.uploadUrl()` | Upload from web URL | [📖](https://docs.graphorlm.com/sdk/sources/upload#upload-from-url) |
445
+ | `sources.uploadGithub()` | Upload from GitHub | [📖](https://docs.graphorlm.com/sdk/sources/upload#upload-from-github) |
446
+ | `sources.uploadYoutube()` | Upload from YouTube | [📖](https://docs.graphorlm.com/sdk/sources/upload#upload-from-youtube) |
447
+ | `sources.parse()` | Reprocess with different method | [📖](https://docs.graphorlm.com/sdk/sources/process) |
448
+ | `sources.list()` | List all sources | [📖](https://docs.graphorlm.com/sdk/sources/list) |
449
+ | `sources.delete()` | Delete a source | [📖](https://docs.graphorlm.com/sdk/sources/delete) |
450
+ | `sources.loadElements()` | Get parsed elements | [📖](https://docs.graphorlm.com/sdk/sources/list-elements) |
690
451
 
691
- ```ts
692
- import Graphor from 'npm:graphor';
452
+ ### Chat & AI
693
453
 
694
- const httpClient = Deno.createHttpClient({ proxy: { url: 'http://localhost:8888' } });
695
- const client = new Graphor({
696
- fetchOptions: {
697
- client: httpClient,
698
- },
699
- });
700
- ```
454
+ | Method | Description | Docs |
455
+ | -------------------------- | ----------------------------- | ------------------------------------------------- |
456
+ | `sources.ask()` | Ask questions about documents | [📖](https://docs.graphorlm.com/sdk/chat) |
457
+ | `sources.extract()` | Extract structured data | [📖](https://docs.graphorlm.com/sdk/extract) |
458
+ | `sources.retrieveChunks()` | Retrieve chunks for RAG | [📖](https://docs.graphorlm.com/sdk/prebuilt-rag) |
701
459
 
702
- ## Frequently Asked Questions
460
+ ## TypeScript Support
703
461
 
704
- ## Semantic versioning
462
+ This library includes complete TypeScript definitions for all request params and response fields:
705
463
 
706
- This package generally follows [SemVer](https://semver.org/spec/v2.0.0.html) conventions, though certain backwards-incompatible changes may be released as minor versions:
464
+ ```typescript
465
+ import Graphor from 'graphor';
707
466
 
708
- 1. Changes that only affect static types, without breaking runtime behavior.
709
- 2. Changes to library internals which are technically public but not intended or documented for external use. _(Please open a GitHub issue to let us know if you are relying on such internals.)_
710
- 3. Changes that we do not expect to impact the vast majority of users in practice.
467
+ const client = new Graphor();
711
468
 
712
- We take backwards-compatibility seriously and work hard to ensure you can rely on a smooth upgrade experience.
469
+ // Type-safe params and responses
470
+ const params: Graphor.SourceUploadParams = { file: fs.createReadStream('path/to/file') };
471
+ const source: Graphor.PublicSource = await client.sources.upload(params);
472
+ ```
713
473
 
714
- We are keen for your feedback; please open an [issue](https://www.github.com/synapseops/graphor-typescript-sdk/issues) with questions, bugs, or suggestions.
715
- >>>>>>> origin/generated--merge-conflict
474
+ Documentation for each method, request param, and response field are available in docstrings and will appear on hover in most modern editors.
716
475
 
717
476
  ## Requirements
718
477