The SQLite MCP extension supports connecting to MCP servers with optional custom HTTP headers in JSON format. This allows you to add multiple headers like Authorization, X-MCP-Readonly, or any custom headers your MCP server requires.
Connect to an MCP server with optional custom headers.
Parameters:
server_url(required): URL of the MCP server (e.g., "http://localhost:8000/mcp")headers_json(optional): JSON string with custom headers (e.g.,{"Authorization": "Bearer token", "X-MCP-Readonly": "true"})legacy_sse(optional): Transport type - 0 for streamable HTTP (default), 1 for SSE
Returns: JSON string with connection status
-- Simple syntax with Authorization header
SELECT mcp_connect(
'https://api.githubcopilot.com/mcp/',
0, -- Use streamable HTTP
'{"Authorization": "Bearer ghp_your_github_personal_access_token"}'
);-- Add multiple custom headers
SELECT mcp_connect(
'https://api.githubcopilot.com/mcp/',
0,
'{"Authorization": "Bearer ghp_token", "X-MCP-Readonly": "true", "X-Custom": "value"}'
);-- No auth needed
SELECT mcp_connect('http://localhost:8000/mcp');
-- Or explicitly specify parameters
SELECT mcp_connect('http://localhost:8000/mcp', NULL, 0);- Never hardcode tokens in SQL scripts
- Store tokens in secure files with restricted permissions
- Use HTTPS in production to encrypt tokens
- Rotate API tokens regularly
Example loading token from environment variable in your application code:
// C code example
char headers_json[512];
const char* token = getenv("API_TOKEN");
snprintf(headers_json, sizeof(headers_json),
"{\"Authorization\": \"Bearer %s\"}", token);
// Pass headers_json to mcp_connectHeaders must be provided as a valid JSON object string with header names as keys and header values as values:
{
"Authorization": "Bearer your_token",
"X-MCP-Readonly": "true",
"X-Custom-Header": "custom_value"
}When passing to SQL, escape quotes properly:
SELECT mcp_connect('http://localhost:8000/mcp', 0, '{"Authorization": "Bearer token"}');Instead of manually parsing JSON with json_each(), use the mcp_list_tools_respond virtual table:
-- Connect first
SELECT mcp_connect('http://localhost:8000/mcp');
-- Get all tools as rows
SELECT name, description FROM mcp_list_tools_respond;
-- Filter tools
SELECT name, description
FROM mcp_list_tools_respond
WHERE name LIKE 'search%';
-- Extract inputSchema for a specific tool
SELECT name, inputSchema
FROM mcp_list_tools_respond
WHERE name = 'airbnb_search';The mcp_call_tool_respond virtual table extracts text results automatically from the result.content array:
-- Call a tool and get text results
SELECT text FROM mcp_call_tool_respond('search', '{"query": "SQLite"}');
-- Multiple text results become multiple rows
SELECT text FROM mcp_call_tool_respond('analyze_data', '{"dataset": "sales"}');Expected result structure from MCP:
{
"result": {
"content": [
{"type": "text", "text": "First result"},
{"type": "text", "text": "Second result"}
]
}
}The mcp_call_tool virtual table provides streaming access to tool results, delivering text chunks as they arrive instead of waiting for the complete response. This is ideal for long-running operations or when you need immediate feedback.
Basic streaming syntax:
-- Stream results from a tool call
SELECT text FROM mcp_call_tool('browser_navigate', '{"url": "https://sqlite.ai"}');
-- Stream search results
SELECT text FROM mcp_call_tool('search', '{"query": "SQLite MCP"}');When to use streaming:
- Long-running tool operations (web scraping, large data processing)
- Real-time feedback needed (progress updates, partial results)
- Memory-efficient processing of large responses
- Interactive applications requiring immediate output
Comparison: Streaming vs Non-Streaming
| Feature | mcp_call_tool (streaming) |
mcp_call_tool_respond (cached) |
|---|---|---|
| Response delivery | Real-time chunks | Complete response |
| Memory usage | Low (streaming) | Higher (full result) |
| Use case | Long operations | Quick queries |
| Latency | Immediate first chunk | Wait for completion |
Example - Processing large dataset:
-- Streaming approach - get results as they arrive
SELECT text FROM mcp_call_tool('analyze_logs', '{"file": "large.log"}');
-- Non-streaming approach - wait for complete analysis
SELECT text FROM mcp_call_tool_respond('analyze_logs', '{"file": "large.log"}');Using JSON functions (more complex):
SELECT json_extract(value, '$.name') as name
FROM json_each((SELECT mcp_list_tools_json()), '$.tools')
WHERE json_extract(value, '$.name') LIKE 'search%';Using virtual tables (simpler):
SELECT name FROM mcp_list_tools_respond
WHERE name LIKE 'search%';Use virtual tables when:
- You need to filter results with WHERE clauses
- You want to join MCP data with other tables
- You're processing multiple tools or results
- You prefer SQL syntax over JSON manipulation
Use scalar functions when:
- You need the complete JSON response
- You're passing results to another system
- You need to preserve the exact response structure
- You want to use
json_extract()to access specific fields