Skip to content

AaltoSciComp/scicomp-docs-assistant

Repository files navigation

SciComp Docs Agent

Search and Q&A over Aalto scicomp-docs (Triton HPC and related guides).

Two ways to use this project:

Use case What you get Needs LLM API key?
Web chat UI Browser chat UI with tool-calling loop Yes (Aalto gateway + VPN)
MCP server Doc search tools for your own agent (Cursor, Claude, custom code) No

Both paths share the same Python tools in app/doc_tools.py.

Prerequisites

  • Python 3.12+ or Docker
  • Docs snapshot in docs-source/ (git submodule — required for both paths)
  • ripgrep optional for local dev (brew install ripgrep); included in the Docker image
  • LLM API key only for the web chat UI

Clone

git clone --recurse-submodules https://github.com/AaltoSciComp/scicomp-docs-assistant.git
cd scicomp-docs-assistant

If you already cloned without submodules:

git submodule update --init --recursive

After a healthy clone, /api/health should report docs_present: true and index_pages in the hundreds (typically 300+). If index_pages is 0, the docs submodule is missing — see Troubleshooting.


Quick start: Web chat UI (recommended)

Browser-based agent that calls the same tools and cites https://scicomp.aalto.fi/.

Requires: Aalto VPN + API key from llm-gateway.k8s.aalto.fi.

Docker (recommended)

cp .env.example .env
# Edit .env and set LLM_API_KEY=your-key-here

docker compose up --build

Open http://localhost:8081 (host port 8081; container listens on 8080).

Local Python

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env   # set LLM_API_KEY

uvicorn app.main:app --reload --port 8080

Open http://localhost:8080.

Using another LLM provider

The gateway client is OpenAI-compatible. Set in .env:

LLM_API_KEY=your-provider-key
LLM_BASE_URL=https://your-provider.example.com/v1
LLM_MODEL=your-model-id

The web UI and MCP can run together on the same server — MCP does not use the LLM.


Quick start: MCP only

Expose doc search to any MCP client. No LLM key, no VPN.

HTTP (Docker, recommended)

cp .env.mcp.example .env   # optional; compose works without .env for MCP-only
docker compose up --build

MCP endpoint: http://localhost:8081/mcp/ (trailing slash required)

Verify:

curl -s http://localhost:8081/api/health | python3 -m json.tool
# expect: "docs_present": true, "index_pages": 300+ (approx), "llm_configured": false

Option B — HTTP (local Python)

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

uvicorn app.main:app --port 8080

MCP endpoint: http://localhost:8080/mcp/

Option C — stdio (local MCP clients)

From the repo root, with dependencies installed:

source .venv/bin/activate   # after pip install -r requirements.txt
python -m app.mcp_stdio

Cursor / VS Code client config (use your venv Python path):

{
  "mcpServers": {
    "scicomp-docs": {
      "command": "/path/to/scicomp-docs-assistant/.venv/bin/python",
      "args": ["-m", "app.mcp_stdio"],
      "cwd": "/path/to/scicomp-docs-assistant",
      "env": {
        "DOCS_ROOT": "/path/to/scicomp-docs-assistant/docs-source",
        "SKILLS_DIR": "/path/to/scicomp-docs-assistant/skills"
      }
    }
  }
}

MCP tools

Tool Description
find_pages Rank pages by title, headings, and path
get_doc_outline Table of contents with line numbers
search_docs Ripgrep over .rst / .md sources
list_doc_tree Browse the docs folder tree
read_doc Read a file with optional line range

Prompt scicomp-docs-search — recommended search workflow (same as the web agent skill).

Resource scicomp-docs://skill/search — raw skill markdown.

Connect from any MCP client (HTTP)

{
  "mcpServers": {
    "scicomp-docs": {
      "url": "http://localhost:8081/mcp/"
    }
  }
}

Clients that only support stdio (e.g. Claude Desktop) can proxy via mcp-remote:

{
  "mcpServers": {
    "scicomp-docs": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "http://localhost:8081/mcp/"]
    }
  }
}

Connect from Python

Install the MCP client SDK on the machine running your script (pip install "mcp>=1.19,<2"):

import asyncio
from mcp.client.session import ClientSession
from mcp.client.streamable_http import streamablehttp_client

async def main():
    async with streamablehttp_client("http://localhost:8081/mcp/") as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()
            result = await session.call_tool("find_pages", {"query": "GPU sbatch"})
            print(result.content[0].text)

asyncio.run(main())

Security: /mcp/ has no authentication. Bind to localhost or put a reverse proxy in front if exposing beyond your machine.


How it works (web agent)

  1. You ask a question in the browser UI.
  2. The LLM receives a search skill (skills/scicomp-docs-search.md).
  3. The model calls tools: find_pagesget_doc_outline / search_docsread_doc.
  4. It answers with citations as published URLs on https://scicomp.aalto.fi/.

Updating the documentation snapshot

git submodule update --remote docs-source
docker compose up --build   # rebuild image so docs-source is refreshed

Configuration

Variable Default Description
LLM_API_KEY (empty) Required for web chat only
LLM_BASE_URL https://llm-gateway.k8s.aalto.fi/api/v1 OpenAI-compatible base URL
LLM_MODEL RedHatAI/gemma-4-31B-it-FP8-Dynamic Model id
LLM_TEMPERATURE 0.15 Sampling temperature
LLM_MAX_TOKENS 4096 Max completion tokens
AGENT_MAX_TOOL_ROUNDS 18 Max tool-calling rounds per chat turn
DOCS_ROOT ./docs-source Path to scicomp-docs tree
DOCS_SITE_BASE_URL https://scicomp.aalto.fi Published site for citations
SKILLS_DIR ./skills Agent skill markdown files
HOST 0.0.0.0 Bind address (local uvicorn)
PORT 8080 Listen port (local uvicorn)

Env templates:

  • .env.example — full template (web agent + MCP)
  • .env.mcp.example — minimal MCP-only (LLM_API_KEY empty)

Troubleshooting

Symptom Likely cause Fix
index_pages: 0 or docs_present: false Submodule not initialized git submodule update --init --recursive, then rebuild/restart
MCP client can't connect Wrong port or missing trailing slash Docker: http://localhost:8081/mcp/ — local: http://localhost:8080/mcp/
MCP works but tools return nothing Empty docs-source/ Same as above; check health endpoint
Chat returns 503 “LLM_API_KEY is not configured” Key not set Add LLM_API_KEY to .env (not needed for MCP)
Chat errors / timeouts from LLM VPN off or wrong gateway Connect to Aalto VPN; verify key at llm-gateway.k8s.aalto.fi
docker compose fails on .env Old Compose version Upgrade Docker Desktop, or cp .env.mcp.example .env
Slow local search ripgrep not installed brew install ripgrep or use Docker
stdio MCP: “docs not found” warning Wrong cwd or DOCS_ROOT Run from repo root; set DOCS_ROOT in client config
Docker build: can't pull python image Docker Hub unreachable or rate-limited Use a mirror, e.g. public.ecr.aws/docker/library/python:3.12-slim-bookworm

Health check:

curl -s http://localhost:8081/api/health | python3 -m json.tool

Healthy MCP + docs: docs_present: true, index_pages > 0. Web chat additionally needs llm_configured: true.

Project layout

app/
  main.py          # FastAPI + SSE chat + MCP mount
  mcp_server.py    # MCP tools, prompt, resource
  mcp_stdio.py     # stdio entry point (`python -m app.mcp_stdio`)
  agent.py         # Tool-calling loop
  doc_tools.py     # search / list / read (shared by agent + MCP)
  doc_index.py     # Page/heading index for find_pages
  config.py        # Settings from .env
  llm_client.py    # Gateway HTTP client
  static/          # Chat UI
skills/
  scicomp-docs-search.md
docs-source/       # scicomp-docs git submodule

License

Documentation content belongs to AaltoSciComp/scicomp-docs. This agent wrapper is provided as-is for local use.

About

Web chat agent and MCP server for searching and answering questions over Aalto SciComp / Triton HPC documentation.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors