Part of #390.
Summary
Add a native kbagent docs query "<question>" command that answers questions from the Keboola documentation, porting the docs_query MCP tool.
MCP source (keboola-mcp-server @ agent-v1.60.0)
- Tool:
src/keboola_mcp_server/tools/doc.py (docs_query) — thin, read-only; delegates to the AI-service client.
- Client:
clients/ai_service.py docs_question(query) → POST docs/question, body {"query": "<str>"}, returns {"text": str, "sourceUrls": [str]} (wire field is camelCase sourceUrls).
- Base URL:
https://ai.{stack-suffix}; auth header X-StorageAPI-Token.
- It is a server-side RAG/Q&A endpoint — no local retrieval, no embedded corpus.
What kbagent already has
ai_client.py AiServiceClient already targets the same ai.{stack} base URL (_derive_service_url(stack_url, "ai")) with header X-StorageApi-Token, and inherits retry/backoff/timeout from BaseHttpClient.
- It already implements
get_component_detail (GET /docs/components/{id}) and suggest_components (POST /suggest/component) — so the camelCase→snake_case alias pattern is established.
- Missing: one client method
docs_question(), a service method, a thin command. No new client, no new auth, no URL work.
Proposed command
kbagent docs query "How do I configure incremental loading?" [--project ALIAS]
- New
docs Typer group (room for a future docs suggest-component, since the /suggest/component client method already exists with no command).
--project optional (resolve stack+token like component detail).
Implementation sketch (3-layer)
- L3
ai_client.py: docs_question(query) -> dict → POST /docs/question, body {"query": query}.
- L2 add
ask_docs(alias, query) to ComponentService (it already owns ai_client_factory) or a small DocsService.
- L1
commands/docs.py: thin command, dual output (JSON {text, source_urls}; human = answer panel + "Sources" list). Add DocsAnswer model to models.py with sourceUrls alias.
Effort: S
Zero new infrastructure; one client method + one service method + thin command + model.
Acceptance criteria
Risks / open questions
docs/question is an internal AI-service endpoint with no published contract found in either repo — confirm shape stability with the AI Service team (response model breaks silently if text/sourceUrls rename).
- Requires a project Storage token (no global/anonymous mode), even though docs are global content.
- Redundant with
kbagent tool call docs_query, but native is faster (no subprocess) and gets --json/Rich.
- Consider shipping
docs suggest-component in the same PR for symmetry (client method already present).
Part of #390.
Summary
Add a native
kbagent docs query "<question>"command that answers questions from the Keboola documentation, porting thedocs_queryMCP tool.MCP source (
keboola-mcp-server@agent-v1.60.0)src/keboola_mcp_server/tools/doc.py(docs_query) — thin, read-only; delegates to the AI-service client.clients/ai_service.pydocs_question(query)→POST docs/question, body{"query": "<str>"}, returns{"text": str, "sourceUrls": [str]}(wire field is camelCasesourceUrls).https://ai.{stack-suffix}; auth headerX-StorageAPI-Token.What kbagent already has
ai_client.pyAiServiceClientalready targets the sameai.{stack}base URL (_derive_service_url(stack_url, "ai")) with headerX-StorageApi-Token, and inherits retry/backoff/timeout fromBaseHttpClient.get_component_detail(GET /docs/components/{id}) andsuggest_components(POST /suggest/component) — so the camelCase→snake_case alias pattern is established.docs_question(), a service method, a thin command. No new client, no new auth, no URL work.Proposed command
docsTyper group (room for a futuredocs suggest-component, since the/suggest/componentclient method already exists with no command).--projectoptional (resolve stack+token likecomponent detail).Implementation sketch (3-layer)
ai_client.py:docs_question(query) -> dict→POST /docs/question, body{"query": query}.ask_docs(alias, query)toComponentService(it already ownsai_client_factory) or a smallDocsService.commands/docs.py: thin command, dual output (JSON{text, source_urls}; human = answer panel + "Sources" list). AddDocsAnswermodel tomodels.pywithsourceUrlsalias.Effort: S
Zero new infrastructure; one client method + one service method + thin command + model.
Acceptance criteria
kbagent docs query "…"returns answer text + source URLs.--jsonemits{text, source_urls, project_alias}.Risks / open questions
docs/questionis an internal AI-service endpoint with no published contract found in either repo — confirm shape stability with the AI Service team (response model breaks silently iftext/sourceUrlsrename).kbagent tool call docs_query, but native is faster (no subprocess) and gets--json/Rich.docs suggest-componentin the same PR for symmetry (client method already present).