Files
bendtherules 627b80008e feat(langfuse): add opt-in Langfuse observability integration
Add Langfuse as an OTel trace transport for MCP request lifecycle tracking.

Changes:
- New src/lib/langfuse-transport.ts: initializes LangfuseSpanProcessor when
  ASK262_LANGFUSE_ENABLED=true with valid credentials
- src/lib/tracing.ts: add metadata to TraceContext, propagate it to child spans,
  use startActiveSpan for proper OTel context, add setupTracing() entry point,
  add getSessionMetadata() for version/transport metadata
- src/lib/logger.ts: include TraceContext.metadata in JSON log mixin
- src/mcp-server-{http,stdio}.ts: call setupTracing() at startup, pass
  version/transport metadata through withSpan/withSpanContext
- src/lib/fireworks-embeddings.ts: wrap API calls in withSpan() with gen_ai
  attributes for Langfuse generation/cost tracking
- .env.example: add LANGFUSE_* configuration variables
- AGENTS.md: document Langfuse integration
- package.json: add @langfuse/tracing, @langfuse/otel, @opentelemetry/sdk-node
2026-04-27 18:31:19 +05:30

3.3 KiB

AGENTS.md - Ask262 Project Guide

Project Overview

Ask262 is a RAG-based MCP server for exploring the ECMAScript specification via engine262. Users ask questions like "How does array.map work?" and get answers grounded in the actual spec and implementation.

Stack: Vector search (LanceDB + Ollama/Fireworks embeddings) → Knowledge graph → LLM reasoning. Runs as MCP server (stdio or HTTP) for Claude Desktop, OpenCode, etc.

Commands

bun run ingest          # Ingest spec HTML into vector DB
bun run build           # Build knowledge graph
bun run lint            # Biome check
bun run type-check      # TypeScript strict check
bun test                # Run all Bun tests
bun run ask262-stdio    # Stdio transport
bun run ask262-http     # HTTP transport (port 8081)

Project Structure

Core: src/agent-tools/ - MCP tool implementations src/mcp-server-stdio.ts - Stdio server entry src/mcp-server-http.ts - HTTP server entry

Data: storage/ - LanceDB vector index spec-built/multipage/ - ECMAScript spec HTML engine262/ - JS engine implementation (git submodule, ignored) graphology/ - Knowledge graph JSON

Setup: src/setup/ingest.ts - Creates vector DB from spec src/setup/buildGraph.ts - Maps spec sections to code

Code Style

Imports: ES modules only. Node built-ins use node: prefix. Never CommonJS.

Formatting (Biome): 2 spaces, 80 char width, LF endings. Excludes: spec-built/, engine262/, graphology/.

TypeScript: Strict mode enabled. Explicit return types. Avoid any. Target: ES2022.

Naming: Folders kebab-case (agent-tools). Files camelCase (buildGraph.ts). Functions camelCase (createTool). Constants UPPER_SNAKE_CASE. Types PascalCase.

Error Handling: Try/catch with meaningful messages. Validate env vars. Log warnings for missing config.

Comments & Documentation:

  • JSDoc for public functions: purpose, params, return values, examples
  • Use /** */ for documentation blocks
  • Use // for inline implementation notes
  • Document complex logic or non-obvious decisions

Environment

Copy .env.example to .env:

  • ASK262_EMBEDDING_PROVIDER - ollama or fireworks
  • FIREWORKS_API_KEY - Required for Fireworks
  • OLLAMA_HOST - Ollama URL (default: http://localhost:11434)
  • ASK262_PORT - HTTP server port (default: 8081)
  • MCP_PUBLIC_URL - Public URL for inspector
  • ASK262_LANGFUSE_ENABLED - Enable Langfuse tracing (optional)
  • LANGFUSE_PUBLIC_KEY / LANGFUSE_SECRET_KEY - Langfuse credentials (required when enabled)

Key Dependencies

  • LanceDB - Vector storage
  • Ollama / Fireworks - Embeddings
  • LangChain - LLM framework
  • Hono - HTTP server
  • Biome - Lint/format

Important Notes

  • TypeScript only - no plain JS
  • Run bun run type-check before committing
  • Ingest/build are slow (local embedding generation)
  • Don't lint/format external dirs (engine262/, spec-built/, graphology/)

Observability

Ask262 uses OpenTelemetry for tracing. When ASK262_LANGFUSE_ENABLED=true is set with valid Langfuse credentials, all OTel spans are exported to Langfuse automatically. No code changes are needed — it's purely a transport configuration. Metadata (version, transport type) is attached to every trace and included in both Langfuse and JSON logs.