CorpusIQ API Reference
Complete technical reference for the CorpusIQ Apps SDK MCP server.
Table of Contents
HTTP Endpoints
Core Endpoints
GET /
Health check endpoint.
Response:
{
"status": "ok",
"service": "CorpusIQ Apps SDK",
"version": "0.1.0"
}
Status Codes:
200 OK: Service is healthy
POST /mcp
Main MCP protocol endpoint. Handles all MCP requests including tool invocations.
Headers:
Content-Type: application/json(required)Authorization: Bearer <token>(required in production)
Request Body:
{
"jsonrpc": "2.0",
"id": "request-id",
"method": "tools/call",
"params": {
"name": "corpus_search",
"arguments": {
"query": "search query",
"maxResults": 10
}
}
}
Response:
{
"jsonrpc": "2.0",
"id": "request-id",
"result": {
"content": [
{
"type": "text",
"text": "Search results..."
}
],
"isError": false
}
}
Status Codes:
200 OK: Request successful400 Bad Request: Invalid request format401 Unauthorized: Missing or invalid auth token429 Too Many Requests: Rate limit exceeded500 Internal Server Error: Server error
GET /.well-known/oauth-protected-resource
OAuth 2.1 protected resource metadata endpoint (RFC 9728).
Response:
{
"resource": "https://your-domain.com",
"authorization_servers": [
"https://your-auth-provider.com"
],
"scopes_supported": [
"corpus:read",
"corpus:search",
"connectors:read",
"connectors:write"
],
"resource_documentation": "https://your-domain.com/docs"
}
Status Codes:
200 OK: Metadata returned500 Internal Server Error: Configuration error
GET /.well-known/oauth-authorization-server
OAuth 2.0 authorization server metadata endpoint (RFC 8414).
Response:
{
"issuer": "https://your-auth-provider.com",
"authorization_endpoint": "https://your-auth-provider.com/authorize",
"token_endpoint": "https://your-auth-provider.com/token",
"jwks_uri": "https://your-auth-provider.com/.well-known/jwks.json",
"response_types_supported": ["code"],
"grant_types_supported": ["authorization_code"],
"code_challenge_methods_supported": ["S256"],
"token_endpoint_auth_methods_supported": ["client_secret_basic"]
}
Status Codes:
200 OK: Metadata returned500 Internal Server Error: Configuration error
Debug Endpoints
These endpoints are only available when CORPUSIQ_DEBUG_MODE=true.
GET /debug/tools
List all available MCP tools.
Response:
{
"tools": [
{
"name": "corpus_search",
"title": "Search Corpus",
"description": "Search across connected data sources",
"inputSchema": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Search query"
},
"maxResults": {
"type": "integer",
"description": "Maximum results",
"default": 5
}
},
"required": ["query"]
}
}
]
}
Status Codes:
200 OK: Tools list returned404 Not Found: Debug mode disabled
GET /debug/ping
Simple connectivity check.
Response:
{
"pong": "ok",
"timestamp": "2026-01-02T16:29:08.696Z"
}
Status Codes:
200 OK: Server is responding404 Not Found: Debug mode disabled
API Service Endpoints
GET /api/auth/health
Authentication service health check.
Response:
{
"status": "healthy",
"service": "auth"
}
Status Codes:
200 OK: Auth service is healthy503 Service Unavailable: Auth service has issues
GET /api/connectors/health
Connectors service health check.
Response:
{
"status": "healthy",
"service": "connectors"
}
Status Codes:
200 OK: Connectors service is healthy503 Service Unavailable: Connectors service has issues
MCP Protocol
CorpusIQ implements the Model Context Protocol (MCP) specification.
Protocol Version
Supported Versions: 1.0, 1.0.0
JSON-RPC 2.0
All MCP messages use JSON-RPC 2.0 format:
{
"jsonrpc": "2.0",
"id": "unique-request-id",
"method": "method-name",
"params": { ... }
}
MCP Methods
initialize
Initialize the MCP session.
Request:
{
"jsonrpc": "2.0",
"id": "1",
"method": "initialize",
"params": {
"protocolVersion": "1.0",
"clientInfo": {
"name": "ChatGPT",
"version": "1.0"
}
}
}
Response:
{
"jsonrpc": "2.0",
"id": "1",
"result": {
"protocolVersion": "1.0",
"serverInfo": {
"name": "CorpusIQ",
"version": "0.1.0"
},
"capabilities": {
"tools": {}
}
}
}
tools/list
List available tools.
Request:
{
"jsonrpc": "2.0",
"id": "2",
"method": "tools/list",
"params": {}
}
Response:
{
"jsonrpc": "2.0",
"id": "2",
"result": {
"tools": [
{
"name": "corpus_search",
"title": "Search Corpus",
"description": "Search across connected data sources",
"inputSchema": { ... }
}
]
}
}
tools/call
Invoke a tool.
Request:
{
"jsonrpc": "2.0",
"id": "3",
"method": "tools/call",
"params": {
"name": "corpus_search",
"arguments": {
"query": "quarterly reports",
"maxResults": 10
}
}
}
Response:
{
"jsonrpc": "2.0",
"id": "3",
"result": {
"content": [
{
"type": "text",
"text": "Search results..."
}
],
"isError": false
}
}
Tools
corpus_search
Search across all connected data sources.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
query |
string | Yes | - | Natural language search query |
maxResults |
integer | No | 5 | Maximum results (1-20) |
Input Validation
query:- Must not be empty or whitespace only
- Maximum length: 1000 characters
- Automatically trimmed
maxResults:- Minimum: 1
- Maximum: 20
- Default: 5
Example Request
{
"name": "corpus_search",
"arguments": {
"query": "Find emails about the Q4 budget",
"maxResults": 10
}
}
Example Response
{
"content": [
{
"type": "text",
"text": "Found 10 results:\n\n1. Email from John: Q4 Budget Review\n Source: Gmail\n Date: 2024-12-15\n Snippet: ...budget discussion...\n\n2. Document: Q4 Financial Plan\n Source: Google Drive\n Date: 2024-12-10\n Snippet: ...planning details...\n\n..."
}
],
"isError": false
}
Widget Output
The tool returns an HTML widget with interactive search results when invoked from ChatGPT.
Error Responses
{
"content": [
{
"type": "text",
"text": "Error: Query cannot be empty"
}
],
"isError": true
}
open_connectors
Open the connector management interface.
Parameters
None.
Example Request
{
"name": "open_connectors",
"arguments": {}
}
Example Response
{
"content": [
{
"type": "text",
"text": "Opening connectors interface..."
}
],
"isError": false
}
Widget Output
Opens an interactive widget showing:
- List of available connectors
- Connection status
- Add/remove buttons
- Configuration options
Configuration
Environment Variables
All configuration is done via environment variables, typically set in .env file.
Core Settings
| Variable | Type | Default | Description |
|---|---|---|---|
CORPUSIQ_CORS_ALLOW_ORIGINS_CSV |
string | "" |
Comma-separated list of allowed CORS origins |
CORPUSIQ_DEBUG_MODE |
boolean | false |
Enable debug endpoints and verbose logging |
CORPUSIQ_LOG_LEVEL |
string | INFO |
Logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL) |
Rate Limiting
| Variable | Type | Default | Description |
|---|---|---|---|
CORPUSIQ_RATE_LIMIT_REQUESTS_PER_MINUTE |
integer | 60 |
Maximum requests per minute per IP |
OAuth Configuration
| Variable | Type | Default | Description |
|---|---|---|---|
CORPUSIQ_OAUTH_RESOURCE_URL |
string | https://example.com |
Your server’s public URL |
CORPUSIQ_OAUTH_ISSUER |
string | https://auth.example.com |
OAuth issuer URL |
CORPUSIQ_OAUTH_AUTHORIZATION_ENDPOINT |
string | - | OAuth authorization endpoint |
CORPUSIQ_OAUTH_TOKEN_ENDPOINT |
string | - | OAuth token endpoint |
CORPUSIQ_OAUTH_JWKS_URI |
string | - | OAuth JWKS endpoint |
Performance
| Variable | Type | Default | Description |
|---|---|---|---|
CORPUSIQ_MAX_REQUEST_SIZE |
integer | 2097152 |
Maximum request size in bytes (2MB) |
CORPUSIQ_REQUEST_TIMEOUT |
integer | 30 |
Request timeout in seconds |
Data Models
Pydantic Models
CorpusSearchArgs
Input validation model for corpus_search tool.
class CorpusSearchArgs(BaseModel):
query: str = Field(
...,
description="Question to ask your connected corpus.",
max_length=1000,
)
max_results: int = Field(
default=5,
ge=1,
le=20,
description="Maximum number of results to return.",
)
Validation:
query: Non-empty, max 1000 characters, trimmedmax_results: Between 1 and 20
MCP Types
CorpusIQ uses standard MCP types from the mcp.types module:
Tool: Tool definitionToolAnnotations: Tool metadataCallToolResult: Tool invocation resultTextContent: Text content typeEmbeddedResource: Embedded resource (widget)ServerResult: Server response wrapper
Error Codes
HTTP Status Codes
| Code | Meaning | Common Causes |
|---|---|---|
| 200 | OK | Request successful |
| 400 | Bad Request | Invalid request format, validation error |
| 401 | Unauthorized | Missing or invalid auth token |
| 404 | Not Found | Endpoint doesn’t exist, debug mode disabled |
| 429 | Too Many Requests | Rate limit exceeded |
| 500 | Internal Server Error | Server error, configuration issue |
| 503 | Service Unavailable | Service temporarily down |
MCP Error Codes
| Code | Meaning |
|---|---|
| -32700 | Parse error |
| -32600 | Invalid request |
| -32601 | Method not found |
| -32602 | Invalid params |
| -32603 | Internal error |
Application Error Messages
| Message | Cause | Solution |
|---|---|---|
| “Query cannot be empty” | Empty query string | Provide a non-empty query |
| “Query length exceeds maximum” | Query too long | Shorten query to ≤1000 chars |
| “Rate limit exceeded” | Too many requests | Wait before retrying |
| “Unauthorized” | Missing/invalid token | Check authentication |
| “Tool not found” | Unknown tool name | Use tools/list to see available tools |
Headers
Required Headers
All MCP requests must include:
Content-Type: application/json
Production deployments should also require:
Authorization: Bearer <token>
Security Headers
CorpusIQ automatically sets these response headers:
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Strict-Transport-Security: max-age=31536000; includeSubDomains
CORS Headers
When CORS is configured:
Access-Control-Allow-Origin: https://chat.openai.com
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization
Rate Limiting
Algorithm
Token bucket algorithm per IP address.
Headers
Rate limit responses include:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1704214148
Retry-After: 60
429 Response
{
"error": "Rate limit exceeded",
"retry_after": 60
}
Logging
Log Format
Structured JSON logs:
{
"timestamp": "2026-01-02T16:29:08.696Z",
"level": "INFO",
"logger": "corpusiq.mcp_server",
"message": "Processing corpus_search request",
"request_id": "abc123",
"client_ip": "192.168.1.1",
"tool": "corpus_search"
}
Log Levels
- DEBUG: Detailed diagnostic info
- INFO: General informational messages
- WARNING: Warning messages
- ERROR: Error conditions
- CRITICAL: Critical failures
Versioning
API Version
Current version: 0.1.0
Protocol Version
MCP protocol version: 1.0
Version Negotiation
Clients specify desired protocol version in initialize request. Server responds with supported version.
Compatibility
CorpusIQ maintains backward compatibility within major versions.
Examples
Complete Request/Response Flow
1. Initialize Session
Request:
curl -X POST https://your-domain.com/mcp \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": "1",
"method": "initialize",
"params": {
"protocolVersion": "1.0"
}
}'
Response:
{
"jsonrpc": "2.0",
"id": "1",
"result": {
"protocolVersion": "1.0",
"serverInfo": {
"name": "CorpusIQ",
"version": "0.1.0"
}
}
}
2. List Tools
Request:
curl -X POST https://your-domain.com/mcp \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": "2",
"method": "tools/list"
}'
3. Call Tool
Request:
curl -X POST https://your-domain.com/mcp \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": "3",
"method": "tools/call",
"params": {
"name": "corpus_search",
"arguments": {
"query": "quarterly reports",
"maxResults": 5
}
}
}'
Client Libraries
Python
from mcp import ClientSession
async with ClientSession("https://your-domain.com/mcp") as session:
await session.initialize()
result = await session.call_tool(
"corpus_search",
{"query": "test", "maxResults": 5}
)
print(result)
TypeScript
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
const client = new Client({
url: "https://your-domain.com/mcp"
});
await client.connect();
const result = await client.callTool("corpus_search", {
query: "test",
maxResults: 5
});
Additional Resources
- MCP Specification: https://modelcontextprotocol.io/
- OpenAI Apps SDK: https://developers.openai.com/apps-sdk
- FastAPI Documentation: https://fastapi.tiangolo.com/
- Pydantic Documentation: https://docs.pydantic.dev/
Last Updated: January 2026
API Version: 0.1.0
Protocol Version: 1.0