sourcesyncai-mcp
Version:
[](https://smithery.ai/server/@pbteja1998/sourcesyncai-mcp)
415 lines (414 loc) • 11.9 kB
JavaScript
import { WretchClient } from './wretch.js';
import { toLowerKebabCase } from './utils.js';
const SOURCESYNC_API_HOST_URL = 'https://api.sourcesync.ai';
/**
* Log SourceSync API errors with detailed information
*/
export function logSourceSyncApiError(error, message) {
console.error(`SourceSync API Error: ${message}`, {
status: error.status,
message: error.message,
response: error.response,
text: error.text,
json: error.json,
});
}
/**
* SourceSync API client for interacting with the SourceSync.ai API
*/
export class SourceSyncApiClient {
static CHUNK_CONFIG = {
chunkSize: 400,
chunkOverlap: 50,
};
namespaceId;
client;
/**
* Create a new SourceSync API client
*/
constructor({ apiKey, tenantId, namespaceId, baseUrl = SOURCESYNC_API_HOST_URL, }) {
this.namespaceId = namespaceId;
this.client = WretchClient(baseUrl)
.auth(`Bearer ${apiKey}`)
.headers(tenantId ? { 'X-Tenant-ID': tenantId } : {})
// eslint-disable-next-line promise/prefer-await-to-callbacks
.catcher(400, (error) => {
logSourceSyncApiError(error, 'Validation Error');
throw new Error('Validation Error');
})
// eslint-disable-next-line promise/prefer-await-to-callbacks
.catcher(401, (error) => {
logSourceSyncApiError(error, 'Authentication Error');
throw new Error('Authentication Error');
})
// eslint-disable-next-line promise/prefer-await-to-callbacks
.catcher(403, (error) => {
logSourceSyncApiError(error, 'Forbidden Error');
throw new Error('Forbidden Error');
})
// eslint-disable-next-line promise/prefer-await-to-callbacks
.catcher(404, (error) => {
logSourceSyncApiError(error, 'Not Found Error');
throw new Error('Not Found Error');
})
// eslint-disable-next-line promise/prefer-await-to-callbacks
.catcher(405, (error) => {
logSourceSyncApiError(error, 'Method Not Allowed Error');
throw new Error('Method Not Allowed Error');
})
// eslint-disable-next-line promise/prefer-await-to-callbacks
.catcher(429, (error) => {
logSourceSyncApiError(error, 'Too Many Requests Error');
throw new Error('Too Many Requests Error');
})
// eslint-disable-next-line promise/prefer-await-to-callbacks
.catcher(500, (error) => {
logSourceSyncApiError(error, 'Server Error');
throw new Error('Server Error');
})
// eslint-disable-next-line promise/prefer-await-to-callbacks
.catcherFallback((error) => {
logSourceSyncApiError(error, 'Server Error');
throw new Error('Server Error');
});
}
/**
* Get a namespace identifier from a brand ID
*/
static getNamespaceIdentifier({ brandId, }) {
return `sitegpt_${brandId}`;
}
/**
* Create a new namespace
*/
async createNamespace({ name, fileStorageConfig, vectorStorageConfig, embeddingModelConfig, webScraperConfig, }) {
return this.client
.url('/v1/namespaces')
.json({
name,
fileStorageConfig,
vectorStorageConfig,
embeddingModelConfig,
webScraperConfig,
})
.post()
.json();
}
/**
* List all namespaces
*/
async listNamespaces() {
return this.client
.url('/v1/namespaces')
.get()
.json();
}
/**
* Get a namespace by ID
*/
async getNamespace() {
return this.client
.url(`/v1/namespaces/${this.namespaceId}`)
.get()
.json();
}
/**
* Update a namespace
*/
async updateNamespace({ fileStorageConfig, vectorStorageConfig, embeddingModelConfig, webScraperConfig, notionConfig, googleDriveConfig, dropboxConfig, onedriveConfig, boxConfig, sharepointConfig, }) {
return this.client
.url(`/v1/namespaces/${this.namespaceId}`)
.json({
fileStorageConfig,
vectorStorageConfig,
embeddingModelConfig,
webScraperConfig,
notionConfig,
googleDriveConfig,
dropboxConfig,
onedriveConfig,
boxConfig,
sharepointConfig,
})
.patch()
.json();
}
/**
* Delete a namespace
*/
async deleteNamespace() {
return this.client
.url(`/v1/namespaces/${this.namespaceId}`)
.delete()
.json();
}
/**
* Create a new connection
*/
async createConnection({ name, connector, clientRedirectUrl, }) {
return this.client
.url('/v1/connections')
.json({
namespaceId: this.namespaceId,
name,
connector,
clientRedirectUrl,
})
.post()
.json();
}
/**
* List all connections
*/
async listConnections({ connector, }) {
return this.client
.url('/v1/connections')
.query({ namespaceId: this.namespaceId, connector })
.get()
.json();
}
/**
* Get a connection by ID
*/
async getConnection({ connectionId, }) {
return this.client
.url(`/v1/connections/${connectionId}`)
.query({ namespaceId: this.namespaceId })
.get()
.json();
}
/**
* Update a connection
*/
async updateConnection({ connectionId, name, clientRedirectUrl, }) {
return this.client
.url(`/v1/connections/${connectionId}`)
.json({
namespaceId: this.namespaceId,
name,
clientRedirectUrl,
})
.patch()
.json();
}
/**
* Revoke a connection
*/
async revokeConnection({ connectionId, }) {
return this.client
.url(`/v1/connections/${connectionId}/revoke`)
.json({
namespaceId: this.namespaceId,
})
.post()
.json();
}
/**
* Ingest text content
*/
async ingestText({ ingestConfig, }) {
return this.client
.url('/v1/ingest/text')
.json({
namespaceId: this.namespaceId,
ingestConfig: {
...ingestConfig,
chunkConfig: SourceSyncApiClient.CHUNK_CONFIG,
},
})
.post()
.json();
}
/**
* Ingest a file
*/
async ingestFile({ file, metadata, }) {
return this.client
.url('/v1/ingest/file')
.formData({
namespaceId: this.namespaceId,
file,
metadata: JSON.stringify(metadata),
chunkConfig: JSON.stringify(SourceSyncApiClient.CHUNK_CONFIG),
})
.post()
.json();
}
/**
* Ingest URLs
*/
async ingestUrls({ ingestConfig, }) {
return this.client
.url('/v1/ingest/urls')
.json({
namespaceId: this.namespaceId,
ingestConfig: {
...ingestConfig,
chunkConfig: SourceSyncApiClient.CHUNK_CONFIG,
},
})
.post()
.json();
}
/**
* Ingest a sitemap
*/
async ingestSitemap({ ingestConfig, }) {
return this.client
.url('/v1/ingest/sitemap')
.json({
namespaceId: this.namespaceId,
ingestConfig: {
...ingestConfig,
chunkConfig: SourceSyncApiClient.CHUNK_CONFIG,
},
})
.post()
.json();
}
/**
* Ingest a website
*/
async ingestWebsite({ ingestConfig, }) {
return this.client
.url('/v1/ingest/website')
.json({
namespaceId: this.namespaceId,
ingestConfig: {
...ingestConfig,
chunkConfig: SourceSyncApiClient.CHUNK_CONFIG,
},
})
.post()
.json();
}
/**
* Ingest content from a connector
*/
async ingestConnector({ ingestConfig, }) {
return this.client
.url(`/v1/ingest/${toLowerKebabCase(ingestConfig.source)}`)
.json({
namespaceId: this.namespaceId,
ingestConfig: {
...ingestConfig,
chunkConfig: SourceSyncApiClient.CHUNK_CONFIG,
},
})
.post()
.json();
}
/**
* Get the status of an ingest job run
*/
async getIngestJobRunStatus({ ingestJobRunId, }) {
return this.client
.url(`/v1/ingest-job-runs/${ingestJobRunId}`)
.query({ namespaceId: this.namespaceId })
.get()
.json();
}
/**
* Get documents
*/
async getDocuments({ filterConfig, includeConfig, pagination, }) {
const response = await this.client
.url(`/v1/documents`)
.json({
namespaceId: this.namespaceId,
filterConfig,
includeConfig,
pagination,
})
.post()
.json();
return {
data: response.data.documents,
hasNextPage: response.data.hasNextPage,
nextCursor: response.data.nextCursor,
statsBySource: response.data.statsBySource,
statsByStatus: response.data.statsByStatus,
};
}
/**
* Update documents
*/
async updateDocuments({ filterConfig, data, }) {
return this.client
.url(`/v1/documents`)
.json({
namespaceId: this.namespaceId,
filterConfig,
data,
})
.patch()
.json();
}
/**
* Delete documents
*/
async deleteDocuments({ filterConfig, }) {
return this.client
.url(`/v1/documents`)
.json({
namespaceId: this.namespaceId,
filterConfig,
})
.delete()
.json();
}
/**
* Resync documents
*/
async resyncDocuments({ filterConfig, }) {
return this.client
.url(`/v1/documents/resync`)
.json({
namespaceId: this.namespaceId,
filterConfig,
})
.post()
.json();
}
/**
* Perform a semantic search
*/
async semanticSearch({ query, topK, scoreThreshold, filter, searchType, }) {
return this.client
.url('/v1/search')
.json({
query,
namespaceId: this.namespaceId,
topK,
scoreThreshold,
filter,
searchType,
})
.post()
.json();
}
/**
* Perform a hybrid search
*/
async hybridSearch({ query, topK, scoreThreshold, filter, hybridConfig, searchType, }) {
return this.client
.url('/v1/search/hybrid')
.json({
query,
namespaceId: this.namespaceId,
topK,
scoreThreshold,
filter,
hybridConfig,
searchType,
})
.post()
.json();
}
}
/**
* Create a new SourceSync API client
*/
export function sourcesync({ apiKey, tenantId, namespaceId, }) {
return new SourceSyncApiClient({ apiKey, tenantId, namespaceId });
}