6.7 KiB
TRUEREF-0010 — REST API (Search & Context Endpoints)
Priority: P0 Status: Pending Depends On: TRUEREF-0006, TRUEREF-0009 Blocks: TRUEREF-0011
Overview
Implement the public-facing REST API endpoints that replicate context7's /api/v2/libs/search and /api/v2/context interfaces. These are the endpoints that the MCP server, CLI tools, and external integrations call. The response format is designed to be compatible with context7's API surface so that tools built for context7 can be pointed at TrueRef with minimal changes.
Acceptance Criteria
GET /api/v1/libs/search— search libraries by name (equivalent to context7's/api/v2/libs/search)GET /api/v1/context— fetch documentation for a library (equivalent to context7's/api/v2/context)- Both endpoints support
type=json(structured) andtype=txt(plain text for LLMs) libraryIdsupports/owner/repo(default branch) and/owner/repo/version(specific version)- Rules from
trueref.jsonare prepended to context responses - CORS headers set (allow all origins) for browser-accessible usage
- Response times < 500ms p99 for typical queries
- Integration tests covering both endpoints
Endpoint: GET /api/v1/libs/search
Equivalent to: GET https://context7.com/api/v2/libs/search
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
libraryName |
string | Yes | Library name to search for |
query |
string | No | User's question for relevance ranking |
limit |
integer | No | Max results (default: 10, max: 50) |
Response 200 (type=json, default):
{
"results": [
{
"id": "/facebook/react",
"title": "React",
"description": "A JavaScript library for building user interfaces",
"branch": "main",
"lastUpdateDate": "2026-03-22T10:00:00Z",
"state": "finalized",
"totalTokens": 142000,
"totalSnippets": 1247,
"stars": 228000,
"trustScore": 9.2,
"benchmarkScore": 87,
"versions": ["v18.3.0", "v17.0.2"],
"source": "https://github.com/facebook/react"
}
]
}
Note: state: "finalized" maps from TrueRef's state: "indexed" for compatibility.
State Mapping
| TrueRef state | context7 state |
|---|---|
pending |
initial |
indexing |
initial |
indexed |
finalized |
error |
error |
Endpoint: GET /api/v1/context
Equivalent to: GET https://context7.com/api/v2/context
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
libraryId |
string | Yes | Library ID, e.g. /facebook/react or /facebook/react/v18.3.0 |
query |
string | Yes | Specific question about the library |
type |
string | No | json (default) or txt (plain text for LLM injection) |
tokens |
integer | No | Approximate max token count for response (default: 10000) |
Response 200 (type=json):
{
"snippets": [
{
"type": "code",
"title": "Basic Component",
"description": "Getting Started > Components",
"language": "tsx",
"codeList": [
{
"language": "tsx",
"code": "function MyComponent() {\n return <div>Hello</div>;\n}"
}
],
"id": "uuid",
"tokenCount": 45,
"pageTitle": "Getting Started"
},
{
"type": "info",
"text": "React components let you split the UI into independent...",
"breadcrumb": "Core Concepts > Components",
"pageId": "uuid",
"tokenCount": 120
}
],
"rules": ["Always use functional components", "..."],
"totalTokens": 2840
}
Response 200 (type=txt):
Plain text formatted for direct LLM context injection:
## Library Rules
- Always use functional components
- Use hooks for state management
---
### Basic Component
*Getting Started > Components*
```tsx
function MyComponent() {
return <div>Hello</div>;
}
React components let you split the UI...
Core Concepts > Components
React components let you split the UI into independent, reusable pieces...
---
## LibraryId Parsing
```typescript
function parseLibraryId(libraryId: string): {
repositoryId: string; // "/facebook/react"
version?: string; // "v18.3.0"
} {
// Match: /owner/repo or /owner/repo/version
const match = libraryId.match(/^(\/[^/]+\/[^/]+)(\/(.+))?$/);
if (!match) throw new Error(`Invalid libraryId: ${libraryId}`);
return {
repositoryId: match[1],
version: match[3],
};
}
Token Budget
The tokens parameter limits the total response size. Snippets are added greedily until the budget is exhausted:
function selectSnippetsWithinBudget(
snippets: Snippet[],
maxTokens: number
): Snippet[] {
const selected: Snippet[] = [];
let usedTokens = 0;
for (const snippet of snippets) {
if (usedTokens + (snippet.tokenCount ?? 0) > maxTokens) break;
selected.push(snippet);
usedTokens += snippet.tokenCount ?? 0;
}
return selected;
}
Default token budget: 10,000 tokens (~7,500 words) — enough for ~20 medium snippets.
Error Responses
// 400 Bad Request
{ "error": "libraryId is required", "code": "MISSING_PARAMETER" }
// 404 Not Found
{ "error": "Library /facebook/react not found or not yet indexed", "code": "LIBRARY_NOT_FOUND" }
// 503 Service Unavailable
{ "error": "Library is currently being indexed, please try again shortly", "code": "INDEXING_IN_PROGRESS" }
CORS Configuration
All API routes include:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PATCH, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization
Set via src/hooks.server.ts handle function.
SvelteKit Route Structure
src/routes/api/v1/
libs/
search/
+server.ts — GET /api/v1/libs/search
+server.ts — GET (list), POST (add)
[id]/
+server.ts — GET, PATCH, DELETE
index/
+server.ts — POST (trigger indexing)
context/
+server.ts — GET /api/v1/context
jobs/
+server.ts — GET (list jobs)
[id]/
+server.ts — GET (single job)
settings/
embedding/
+server.ts — GET, PUT
Files to Create
src/routes/api/v1/libs/search/+server.tssrc/routes/api/v1/context/+server.tssrc/lib/server/api/formatters.ts— JSON ↔ txt response formattingsrc/lib/server/api/library-id.ts— ID parsingsrc/lib/server/api/token-budget.tssrc/hooks.server.ts— CORS + startup recovery- Integration tests in
src/lib/server/api/*.test.ts