github-mcp 0.4.1

GitHub v3 REST API MCP server, generated by mcpify.
Documentation
// GitHub v3 REST API MCP server — generated by mcpify. Do not hand-edit.

use rusqlite::Connection;

use crate::data::store::search_endpoints;
use crate::services::embedding_service::embed;

/// Semantic similarity lookup matching a natural-language query against
/// candidate API operations (PRD §1.5) — so an LLM never needs the full
/// OpenAPI spec in context to find the right operation.
pub fn search_operations(
    conn: &Connection,
    query: &str,
    limit: usize,
) -> anyhow::Result<serde_json::Value> {
    warn_if_semantic_endpoints_incomplete(conn);
    let query_embedding = embed(query)?;
    let results = search_endpoints(conn, &query_embedding, limit)?;
    Ok(serde_json::to_value(results)?)
}

/// Cheap diagnostic for the "populated but missing embeddings" failure
/// mode (Fix 8b): if a store's `semantic_endpoints` row count is below its
/// `endpoints` row count, some operations can never be found by `search`
/// even though they exist — warn so an operator investigating an
/// unexpectedly-empty/sparse result set has a lead, without changing the
/// success/`[]` return contract for legitimately-empty search results.
fn warn_if_semantic_endpoints_incomplete(conn: &Connection) {
    let counts: rusqlite::Result<(i64, i64)> = conn.query_row(
        "SELECT (SELECT COUNT(*) FROM endpoints), (SELECT COUNT(*) FROM semantic_endpoints)",
        [],
        |row| Ok((row.get(0)?, row.get(1)?)),
    );
    if let Ok((endpoints_count, semantic_count)) = counts
        && semantic_count < endpoints_count
    {
        tracing::warn!(
            endpoints_count,
            semantic_count,
            "semantic_endpoints is missing rows relative to endpoints; search results may be \
             incomplete — run the populate-embeddings binary to backfill"
        );
    }
}