Skip to content
Conduit

mcp server

vla

A CLI-based agentic coding harness with persistent memory and LSP-backed code intelligence.

outerstellar-hq/vlacommunitylistedunreviewed

Set up

Runs on your computer. Pick your agent and operating system.

This project does not publish an install method we can turn into a config. Follow the README instead.

README

synced Oct 21, 2026

432 deterministic tests. Full-screen TUI with split-pane diff + session switcher + animated demo. MCP support. LSP integration. OS-level sandbox.

What makes VLA different

  1. Full-screen TUI. A bubbletea terminal interface with markdown rendering, expandable tool-call blocks, split-pane diff preview, session switcher, scroll lock, live status bar (spinner + token count), slash-command autocomplete, and inline approval prompts — like Claude Code or OpenCode.
  2. MCP support. Connect external tools via Model Context Protocol — same protocol as Claude Code, Cursor, OpenCode. Any MCP server plugs in via .vla/mcp.json.
  3. IDE-grade tool space. 20+ built-in tools: file, search, git, web, memory, navigation, plus unlimited MCP tools.
  4. Persistent memory. The agent remembers across sessions. Memories are stored per-project with embedding-based semantic search, auto-injected into context before each LLM call.
  5. LSP-backed navigation. When a language server is available (17 supported: gopls, pyright, rust-analyzer, clangd, solargraph, and more), go-to-definition, find-references, hover, and diagnostics use real LSP. Falls back to a regex-based indexer.
  6. 150+ providers. Auto-configured via models.dev — vla use openai/gpt-4o and you're running.
  7. Encapsulated tools. Every tool is a self-contained Go struct in its own file.

Install

macOS / Linux (Homebrew):

brew tap outerstellar-hq/tap
brew install vla

Windows (Scoop):

scoop bucket add outerstellar-hq https://github.com/outerstellar-hq/vla
scoop install vla

Go install:

go install github.com/abrandt/vla@latest

Build from source:

git clone https://github.com/outerstellar-hq/vla.git
cd vla
go build -o vla .

Pre-built binaries: Download from releases (macOS, Linux, Windows — amd64 + arm64).

Quick start

# Option A: Configure with models.dev (auto-discovers 150+ providers)
export OPENAI_API_KEY=sk-...
vla use openai/gpt-4o       # writes config.json automatically

# Option B: Manual config
cp config.json.example config.json  # edit with your OpenAI-compatible API key

# Browse available models
vla models                    # list all providers
vla models openai             # list OpenAI models
vla models anthropic claude   # filter by name

# Run the agent
vla

CLI reference

CommandDescription
vlaStart the agent (full-screen TUI or readline)
vla use <provider/model>Configure provider via models.dev
vla models [provider] [filter]Browse models
vla sessions [--project <path>]List sessions
vla demo [--gif] [--out=DIR]Generate screenshots/GIF
vla bug --title '...' --body '...'Report a bug (creates GitHub issue)
vla versionPrint version
FlagDescription
--resume <id>Resume a session
--model <name>Override config model
--config <path>Path to config.json
--yesAuto-approve all tool calls
--planRead-only investigation mode
--sandboxOS-level sandbox (macOS/Linux)
--persona <name|path>System prompt persona (architect or .md file)

Built-in tools

ToolDescription
File
read_fileRead file contents (capped at 256 KiB)
write_fileCreate or overwrite a file
update_fileFind-and-replace within a file
delete_fileDelete a file
list_filesList project files
searchCodebase text search (ripgrep or Go fallback)
Git
git_statusShow working tree status
git_diffShow staged or unstaged changes
git_commitStage all + commit
Navigation
go_to_definitionFind where a symbol is defined (LSP or regex)
find_referencesFind all usages of a symbol (LSP or regex)
hoverType/signature/docs at a position (LSP only)
diagnosticsLint/type errors for a file (LSP only)
Memory
memory_saveStore a fact or knowledge for later
memory_searchSearch stored memories (keyword + semantic)
memory_listList all memories for the current project
memory_deleteDelete a memory by ID
Web
web_searchSearch the web (DuckDuckGo, no API key)
web_readFetch a URL, strip HTML to text

MCP (external tools)

VLA supports any MCP server via .vla/mcp.json:

{
  "servers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {"GITHUB_TOKEN": "ghp_xxx"}
    }
  }
}

On launch, VLA starts all MCP servers, performs the handshake, and registers their tools alongside the built-in tools. MCP tools are prefixed with the server name (e.g. github__create_issue) to avoid collisions. See .vla/mcp.json.example for more.

TUI (terminal interface)

When launched in a terminal, VLA uses a full-screen bubbletea interface:

Key bindings:

  • Ctrl+Enter (or Ctrl+J): submit input
  • Tab: expand/collapse tool call details
  • Ctrl+D: toggle split-pane diff preview
  • Ctrl+S: open session switcher
  • Ctrl+F: toggle auto-scroll follow mode
  • Ctrl+C: quit
  • Arrow keys / Page Up/Down: scroll conversation history
  • When stdin is piped (echo "fix bug" | vla), falls back to readline/plain mode
main.go                  → subcommand routing (models, use, default=agent)
tui_runner.go            → full-screen TUI launcher (bubbletea)
input.go                 → readline wrapper (fallback UI)
internal/agent/          → core loop + message types + context injection
internal/tui/            → bubbletea TUI (conversation, streaming, input)
internal/mcp/            → MCP client + tool adapter + server manager
internal/llm/            → OpenAI-compatible streaming client (SSE)
internal/lsp/            → LSP client (JSON-RPC) + process manager
internal/memory/         → persistent memory store + embeddings + hybrid search
internal/modelsdev/      → models.dev catalog client + CLI commands
internal/session/        → session lifecycle + NDJSON transcript
internal/indexer/        → regex symbol index + polling watcher
internal/tools/builtin/  → all 20 built-in tools (one file each)
internal/compaction/     → context-window compaction
internal/fsutil/         → path confinement
internal/app/            → wiring (config discovery, tool registration, resume)
internal/config/         → config.json loader

Memory system

Memories are stored as JSON files under ~/.vla/memory/<project>/. Each memory carries content, tags, and an embedding vector (via the OpenAI embeddings API). Search is hybrid: keyword (substring on content/tags) fused with vector cosine similarity, min-max normalized and weighted (0.7 vector / 0.3 keyword).

Before each LLM call, the agent searches memories relevant to the current user message and injects them as a system message — so the agent has context from all previous sessions without being told.

LSP integration

When a language server is installed (gopls for Go, pyright for Python), VLA uses it for:

  • go_to_definition — position-aware, not just name matching
  • find_references — precise, not heuristic
  • hover — type signatures, documentation
  • diagnostics — compile/lint errors with severity

If no server is available, navigation falls back to the regex-based indexer. The LSP client speaks the base protocol (Content-Length framing) over stdio, with a warm process pool (one server per language + workspace).

Security

VLA has four layers of defense against unintended file operations:

  1. Path confinement (fsutil.Confine) — every file tool validates paths against the project root. Symlinks are resolved to catch escapes.
  2. OS-level sandbox (--sandbox flag) — re-executes VLA inside sandbox-exec (macOS) or bwrap (Linux) with filesystem restricted to the project directory.
  3. Permission rules (.vla/permissions.json) — allow/deny/ask per tool.
  4. Diff approval — destructive tools (write_file, update_file, delete_file, git_commit) prompt for y/n/a before executing.

See docs/ARCHITECTURE.md for the full security model.

Testing

go test ./...        # 432 tests, all deterministic

All tests are deterministic — no API keys, no real network, no LSP servers required. LLM interactions use httptest.NewServer; LSP client tests use net.Pipe to simulate a server in-process.

Reporting bugs

vla bug --title "Something is broken" --body "Description of the issue"

Or interactively:

vla bug

This creates a GitHub issue directly in outerstellar-hq/vla with the bug label and your environment info attached. Requires the GitHub CLI or a GITHUB_TOKEN environment variable.

Documentation

  • Architecture — package layout, agent loop lifecycle, security model
  • Configuration — config.json, CLI flags, environment variables
  • TUI Reference — key bindings, modes, status bar
  • Permissions — .vla/permissions.json allow/deny/ask rules
  • Hooks — .vla/hooks.json event scripts
  • Plugins — .vla/plugins/ custom tools
  • MCP — Model Context Protocol server setup
  • Design Document — original design rationale (historical)
↑↓ navigate openesc close