Codeoutline
FreeMaintainedMCP and LSP server for code exploration: symbols, line-numbered source, call paths and editor navigation
About
MCP and LSP server for code exploration: symbols, line-numbered source, call paths and editor navigation
README
English | 简体中文
Lightweight code indexing and exploration for coding agents, as an MCP server, and for editors, as a language server. Powered by Lua.
CodeOutline answers symbol queries with line-numbered source, call paths, and callers/callees, refreshes incrementally, and caches the index on disk. Editors get symbols, definitions, references, call hierarchy, and completion from the same index through LSP. The MCP protocol with both transports (stdio and Streamable HTTP) and the language server are implemented in Lua, so neither depends on Node; in the npm package, Node only locates and starts the runtime for your platform.
Installation and setup
Requires Node.js 20 or newer. npm downloads the runtime for your platform automatically; no compiler or Lua installation is needed. Install it globally rather than configuring clients with npx -y: npx keeps a full npm process running beside every server it starts.
npm install -g codeoutline
codeoutline --version
Recommended: one shared HTTP service
A stdio server is a child process of its client, so every agent session (each Claude Code session, each Cursor window) starts its own copy and builds its own in-memory index. One HTTP service serves all sessions from a single process and a single index.
A global npm installation starts that service in the background and registers it to start at login: a Run registry value on Windows, a LaunchAgent on macOS, and a systemd user unit on Linux; without a systemd user manager (WSL, containers), start codeoutline daemon at login yourself. The service installs updates and restarts itself into them, so after installation the only setup is registering its URL once.
Claude Code (added globally, available in every project):
claude mcp add --transport http codeoutline --scope user http://127.0.0.1:19876/mcp
Cursor (~/.cursor/mcp.json):
{ "mcpServers": { "codeoutline": { "url": "http://127.0.0.1:19876/mcp" } } }
codeoutline install does the same for a native installation, or after installing with --ignore-scripts; --port selects a port other than 19876. Set CODEOUTLINE_AUTOSTART=0 when installing to skip the login entry. codeoutline uninstall stops the service and removes the entry; run it before npm uninstall -g codeoutline, which does not run package scripts. The service logs to ~/.codeoutline/logs.
The service listens on 127.0.0.1:19876 and serves projects anywhere on the machine, so switching between projects on different drives needs no configuration. Only local processes can reach it, and they already have your file access. A shared service has no project of its own: it uses the client's roots when the client provides them, and otherwise the agent passes projectPath, which the tools ask for when it is missing.
To run an HTTP service yourself instead, for example restricted to some directories, start codeoutline serve --http and repeat --allow-root for each directory tree to allow; a tree that is unavailable at startup, such as an unmounted drive, is reported and becomes usable once it appears. Such a service installs updates but keeps running the old version until restarted; on Windows, supervise the native launcher rather than the npm one; see DISTRIBUTION.md.
Alternative: stdio, one process per session
Use stdio when you do not want a resident service. Each session then starts and stops its own server.
claude mcp add codeoutline --scope user -- codeoutline serve --stdio
On Windows, Claude Code cannot start the codeoutline.cmd shim directly; use -- cmd /c codeoutline serve --stdio. For Cursor, set "command": "codeoutline", "args": ["serve", "--stdio"]. A client that starts codeoutline with no arguments, as 0.1.7 recommended, gets the same stdio server.
When no project is specified, the service uses, in order: the projectPath argument of the call, the --project option, the client's roots (the first directory returned by roots/list), and the directory the service was started in. Clients usually start a stdio service in the project directory, so a global configuration needs no project path. Access defaults to --project or the start directory; repeat --allow-root to allow more.
Seven tools are provided:
| Tool | Purpose |
|---|---|
codeoutline_explore |
Query source, call paths, and callers/callees by symbol or file name (query; optional projectPath, budget) |
codeoutline_callers |
Find recursive callers and affected files for an exact symbol/qualified name (query; optional projectPath, depth default 3, max_nodes default 200, budget) |
codeoutline_affected |
Analyze changed files with shared reverse traversal, shortest paths and test candidates (files; optional projectPath, depth, max_nodes, budget) |
codeoutline_type_hierarchy |
Find declared ancestors and descendants of a C#/Java/Kotlin/TS/C++ type (query; optional projectPath, direction, depth default 8, max_nodes default 200, budget) |
codeoutline_type_references |
Find explicit type uses with identity resolution in C/C++, C#, Java, Kotlin, TS/ArkTS, Go and Rust (query; optional projectPath, max_nodes default 200, budget) |
codeoutline_status |
Refresh and report index, cache, scanner, and parser statistics |
codeoutline_rebuild |
Rebuild fully, bypassing the cache |
Without Node, download the native archive for your platform from GitHub Releases, extract it, and run codeoutline (codeoutline.cmd on Windows).
Editor integration (LSP)
codeoutline lsp --stdio is a language server over the same indexer. Each editor window starts its own server process with its own index; it does not connect to the shared MCP service, and the MCP URL is not an LSP endpoint.
| Feature | Scope |
|---|---|
| Document and workspace symbols | Workspace symbols match substrings, case-insensitively |
| Definition, hover, signature help | Definition also goes from import lines (require, #include, module imports) to the files they load |
| References | Functions, methods, constructors, macros and supported explicit type positions |
| Call hierarchy | Functions, methods, constructors and macros; incoming and outgoing calls |
| Method implementations | C#, Java, Kotlin and TypeScript interface/abstract methods and C++ virtual overrides; textDocument/implementation |
| Completion | Locals, the file's definitions and imports, declarations from included C/C++ headers, and members after ., ->, ::, ?., or Lua : |
Resolution is name-based, the same as codeoutline_explore; it is not a type checker. Rename, diagnostics, and formatting are not provided, so CodeOutline works best beside a language's own server or where none is available. Unsaved edits are included in every request. A .codeoutline.json file in the workspace root can map Lua call arguments to registration sites for Go to Definition. Behavior, limits, and options are described in LSP.md.
Thin clients are in this repository: one VSIX for VS Code and Cursor, and a Zed extension. They are not published to an extension marketplace yet; install them as described in their READMEs. Other editors can start the same command through their generic LSP support; only VS Code, Cursor, and Zed have been tested.
Clients start the server directly, without a shell:
- Linux and macOS: the npm installation puts an executable
codeoutlineon PATH, so the client defaults (codeoutlinewithlsp --stdio) work. An editor started from the desktop may not inherit PATH entries added by your shell profile (nvm, for example); then configure the absolute path printed bycommand -v codeoutline. - Windows: npm installs
codeoutline.cmd, a batch file. The VS Code/Cursor client finds the npm installation itself, and Zed startscodeoutline.cmdfrom PATH through cmd.exe, so neither needs settings. For clients that cannot start a batch file, configurenodeas the command, with the arguments<global npm folder>/codeoutline/launcher/codeoutline.cjs,lsp,--stdio;npm root -gprints the global folder, usuallyC:\Users\<you>\AppData\Roaming\npm\node_modules. For the native archive, run itsbin/xnet.exewith<archive>/scripts/codeoutline/command.lua,LOG_STDERR=1,LOG_FILE=0,lsp,--stdio.
The server uses the newest installed version when it starts and does not install updates itself; an update installed by the background service takes effect the next time the editor starts the server. Started directly from the native archive, the server always runs that archive's version.
System requirements
| Platform | Requirements |
|---|---|
| Windows | x64, Windows 10 / Server 2016 or newer (Windows 8 for the native archive); Windows 11 on ARM64 runs it under x64 emulation. No Visual C++ redistributable needed |
| Linux | x64, glibc 2.28 or newer: RHEL / Rocky / Alma 8 and 9, CentOS Stream 9, Debian 10+, Ubuntu 20.04+. Alpine/musl is not supported |
| macOS | macOS 11 or newer; one universal binary for Apple Silicon and Intel |
On Linux, decoding GBK sources needs the GBK module of the system iconv. Minimal EL8/EL9 installs and container images lack it: dnf install glibc-gconv-extra. UTF-8 projects work without it, and codeoutline doctor reports when it is missing.
Supported languages
C, C++, C#, Go, Java, JavaScript / TypeScript (including JSX/TSX), ArkTS (.ets), Kotlin (.kt / .kts), Lua, Python, and Rust.
ArkTS reuses the JS/TS parser: component struct declarations are indexed as classes,
with decorated fields, methods, local module imports and ArkUI calls. Declarative UI
blocks remain calls rather than method declarations. This is heuristic indexing, not
ArkTS type checking; SDK @kit.*/@ohos.* resolution, resource references and generated
UI lifecycle/state behavior are not modeled. Zed requires a separate ArkTS language extension.
Kotlin includes declarations, constructor properties, extension functions, expression bodies, package imports (including aliases), and ordinary, generic and trailing-lambda calls. Resolution is heuristic: compiler-generated members, implicit lambda receivers, string-template expressions, Java interop and coroutine/framework dispatch are not modeled.
C/C++ bare calls check project macro visibility on demand: define/undef, indexed include order and finite conditions distinguish visible macros from ordinary functions. Unknown expansions remain unresolved; this does not run a preprocessor.
Unknown filename suffixes are handled on demand. LSP uses a supported editor language
ID first, then bounded, conservative syntax detection. Explicit project-relative file
paths in explore queries receive the same temporary parsing; lang: can supply a
language hint. Detection ignores comments, strings, binary data and ambiguous syntax.
Each explore query admits at most four such files of 1 MiB each and 2 MiB in total.
No suffix association is learned. Except for the C/C++ include-driven admission below,
these files are not added to the persistent index. Supply a full relative path for files
outside the root directory; file discovery by basename uses the regular index.
C/C++ literal #include directives can admit project-local unknown-suffix source
fragments such as .inl or .inc. The normal file listing supplies candidates and
honors ignore rules; relative paths and project include-path configuration take
precedence. Without configured search paths, only a unique suffix match is admitted.
Fragments inherit a C/C++ parser hint, with C++ syntax detection, and are parsed once
per language hint into compact cached records. Unreferenced unknown files, ignored
files, external SDKs, binary data and clearly foreign-language sources are not admitted.
Changes rediscover reachable fragments and remove orphaned include cycles; cache
reloads preserve parser hints. Limits are 4,096 fragments, 64 MiB combined source and
32 discovery rounds, plus the normal per-file size limit; refresh statistics expose
fragment_limited when a discovery limit is reached. Detailed bindings and macro
environments remain query-time data. Inclusion alone does not restore a surrounding
class, namespace or the compiler configuration of every translation unit.
Explore can suggest exact-name definitions for unresolved calls, including possible macro declarations. The separate Unconfirmed definition candidates section gives locations, matching reasons and bounded source snippets. These suggestions never add call edges, seeds, callers or impact paths; inspect them before inferring a relationship. Known import, local, receiver, qualification and include-policy barriers still apply. Lookup inspects at most four encountered sites and 256 same-name entries per ordinary site, with eight results per site and snippets from four source files totaling 2 MiB. Macro suggestions use a separate bounded pass with the existing macro limits. Output limits are reported; suggestions and their evidence are query-owned and are not stored in the index.
C++ lookup covers named type aliases, namespace aliases, using ns::Type, using ns::function,
and bounded using namespace chains across included headers. Calls, navigation and completion
share this lookup; local imports respect their declaration position and block scope, and
ambiguous imported names remain unresolved. Import evidence is generated on demand rather
than stored in the index. This is heuristic lookup: preprocessing/include order, compiler
include-search configuration, dependent templates, ADL and full overload resolution are not modeled.
JS/TS package imports resolve local npm/Yarn workspaces (workspaces arrays or packages lists)
and pnpm packages lists. Package discovery reuses indexed directories; manifests and resolution
maps exist only during a query. The nearest workspace owns an import, pnpm configuration takes
precedence, and relative imports and existing tsconfig paths retain their priority. Supported globs
are *, **, ? and ! exclusions; pnpm accepts block string lists or JSON flow lists.
Lookup covers scoped names, subpaths, exact/wildcard exports, ordered types/import/require/
node/default conditions, and legacy types/typings/module/main entries. An unavailable
declared export stays unresolved rather than guessing a source directory. Duplicate package names
also stay unresolved. Configuration changes apply on the next query without reindexing sources.
Discovery is bounded to 4,096 directories, 512 packages, 1,024 configuration probes and 8 MiB of
configuration per query (1 MiB per file); exceeded limits report incomplete results. This is source
navigation, not full Node/TypeScript module resolution: dependency installation, lockfiles, package
imports, custom conditions, arbitrary YAML, and CommonJS export analysis are not provided.
Go method queries share bounded, query-time method sets across agent exploration, callers, LSP definition/implementation lookup and completion. Ordinary interfaces match only when every required method has an identical resolved parameter/result signature, including variadic form. Value and pointer receivers, non-generic embeddings, shallower declarations, field shadowing and ambiguous promotions are handled separately. Implementation edges are possible structural matches, not proof of a runtime receiver. Empty interfaces do not expand to every type. Generic bodies, type-set constraints and unresolved signatures remain unknown. Detailed evidence is not stored in the index; see Go method queries for limits.
Go imports use the nearest in-project go.mod and go.work: declared module paths,
workspace use lists, and relative local replace targets locate indexed packages.
Workspace replacements override module replacements; version-specific replacements
require an agreed direct requirement across workspace modules. Module boundaries,
duplicate names and conflicting replacements prevent speculative matches. Package calls,
navigation and completion share explicit aliases and declared package names (including
imports ending in /v2). Imported packages exclude test files and non-Go files;
unqualified function lookup stays within the current package. With no module metadata,
directory-suffix lookup remains available only when it finds a unique package.
Configuration is query-owned and reloaded on the next request. Limits are 1,024 config
probes, 1 MiB per config, 8 MiB total, 256 workspace modules, 512 files, 8,192 scanned
nodes and 64 matching declarations per package lookup (4,096 legacy directory candidates);
exceeded limits report incomplete results. Lookup stays inside
the indexed project and does not invoke Go or download dependencies. The full module
version graph, host GOWORK/GOPATH, vendor/module caches, build tags, dot imports,
lexical shadowing and full receiver/type inference are not modeled. Configuration accepts
standard line/block directives and JSON-compatible quoted paths; absolute local paths
and other Go string escape forms are outside this supported subset.
Rust Cargo lookup reads local path dependencies and inherited workspace.dependencies
on demand, including renamed packages, hyphenated crate names and custom [lib] names/paths.
Workspace dependency paths are relative to their defining workspace manifest; sibling packages
are not inferred as dependencies. crate/self/super, declared file/inline modules, grouped
use aliases and bounded named public re-exports share resolution across calls, navigation
and module completion. Detailed import, path and visibility evidence reuses the bounded query
source cache and is excluded from serialized indexes. External lookups require public items.
Manifest edits apply on the next request. Limits include 1,024 manifest probes, 1 MiB per
manifest, 8 MiB total, 512 dependencies per package, 8,192 nodes per module and 64 alias-source
files per caller query; exceeded limits report incomplete results. Supported TOML includes
basic/literal strings, arrays, inline dependency tables, dotted dependency properties and
dependency subtables. Lookup stays within the indexed root and never invokes Cargo. Registry/
Git downloads, dev/build/target-specific dependencies, lockfile/feature/target selection,
patch/replace overrides, glob re-exports,
#[path]/generated modules, custom binary targets, block-local imports and full Rust type,
privacy or macro analysis are not modeled. Without Cargo metadata, legacy Rust lookup remains.
Function values in supported JS/TS/ArkTS, Python and Java/Kotlin forms retain ref dependencies, including explicit imports and typed method references. A reference is not proof of callback execution; anonymous scopes and complex expressions have conservative limits.
C#, Java and Kotlin implementation relationships use declared inheritance and matching named
parameter types. Explore and callers label these edges implementation: they describe possible
implementations, not calls made by the method or a proven runtime receiver. Go to Implementation
uses the same lookup; Go to Definition continues to return the declaration. Detailed method
evidence is generated per query and excluded from the index. Candidate, result and hierarchy
limits report incomplete results. Generic substitution, inherited-only interface implementations,
and default-interface conflict resolution are not modeled.
Lua also follows local callback arrays populated by named local functions and table.insert,
then directly invoked through the value variable of a builtin pairs/ipairs loop. These
query-owned automatic:callback-loop edges reuse static registry bindings and preserve
collection identity. See Indirect calls
for mutation, scope and size limits.
JS/TS also infer limited Node EventEmitter deliveries from literal registrations and emissions
on the same local object. These query-owned automatic:event edges feed explore/callers without
configuration; see Indirect calls
for import, scope, mutation and candidate limits.
TypeScript interface and explicitly abstract methods use the same bounded query path. Only
explicit implements/extends relationships between ordinary top-level named types are linked;
named/default/namespace imports, re-exports, workspace packages and tsconfig paths reuse module
resolution. Parameter and return annotations must match exactly after resolving primitive or
named types (including simple arrays); named type identity includes its declaring module.
Both signatures must have explicit annotations. Generic heritage/methods, aliases, unions,
optional/rest/default parameters, accessors, arrow fields, declaration merging, nested types,
inferred returns and structural implementations are excluded. Class overload signatures are
not treated as abstract contracts. These links do not perform TypeScript assignability checks.
C++ uses the same query path for non-template, single, non-virtual inheritance. It matches
ordinary named/builtin parameter and return types, pointer/reference and cv decoration, and
member const/volatile/reference qualifiers. Overrides can omit virtual/override; private
virtual methods participate, while final blocks further overrides. Namespace imports, aliases
and indirect includes use the existing bounded C++ lookup. Matching out-of-line definitions are
preferred over class declarations; an unmatched body cannot stand in for an edited declaration.
Pure virtual overrides remain contracts. Multiple/virtual inheritance, templates, covariant
returns, function-pointer/array parameters and decorated type aliases in signatures are excluded.
These links describe possible implementations, without proving virtual dispatch at a call site.
Each query retains at most 128 alias-file arrays and 1 MiB of alias evidence from the shared
source loader. Reaching either limit reports incomplete relationships and suppresses uncertain
C++ links; alias data is never persisted.
C/C++ include lookup can use ordered project search paths in .codeoutline.json:
{
"includePaths": ["shared/include"],
"includePathRules": [
{ "directory": "apps/client", "paths": ["apps/client/include"] },
{ "directory": "apps/server", "paths": ["apps/server/include"] }
]
}
Quoted includes first search the including file's directory. Other searches use the longest
matching directory rule, then project includePaths, then LSP initializationOptions.includePaths,
in array order, stopping at the first existing header. Rule directories match whole path
components; apps/client does not match apps/client-tools. Paths are relative to the workspace root or absolute;
rule directories must stay inside the workspace (. matches the root). Each including file
selects its own rule. Configuration is reloaded per query and shared by explore, callers,
definition, implementation navigation and completion. Existing same-directory source files take
priority when pairing a header with its implementation; C++ class-outside members must belong to
the selected class, rather than another same-named class.
With configured paths, a paired source must directly include the selected header; unsupported
build/forced-include relationships remain declarations instead of guessed definitions.
An explicit includePaths (including []), a matching directory rule, or nonempty LSP search
paths disables whole-project suffix guesses for that file. Without configuration, legacy suffix
lookup remains. External or excluded headers can be opened from include lines but do not contribute
indexed symbols or fall through to indexed duplicates. There are at most 128 rules and 128
effective directories per file; paths are literal, without globs. These are per-file lookup rules,
not compiler build configurations, forced includes or full preprocessor/translation-unit analysis.
Only query-owned configuration and bounded path caches are added; no include maps are persisted.
Command line
Explore, callers, type-hierarchy and type-references accept explicit query filters
such as lang:lua path:service/ connect. They select starting symbols; dependency
expansion still crosses files and languages, including Lua-to-C calls.
Project search ranking lets .codeoutline.json
deprioritize directory prefixes when explore chooses starting symbols. Files
remain indexed, and dependency expansion keeps the same visibility.
codeoutline serve --stdio [--project PATH] [--allow-root PATH ...]
codeoutline serve --http [--host HOST] [--port PORT] [--project PATH] [--allow-root PATH ...]
codeoutline lsp --stdio [--project PATH]
codeoutline explore --project PATH --query QUERY [--budget BYTES]
codeoutline status [--project PATH]
codeoutline rebuild [--project PATH]
codeoutline doctor [--project PATH]
status, rebuild, and doctor print JSON; a failed diagnostic exits nonzero. One-shot commands default to the current directory as the project. lsp --stdio is started by an editor and speaks LSP on stdin and stdout; it is not an interactive command. Its workspace comes from the editor, and --project is used only when the editor sends none.
The runtime logs only warnings and errors, to stderr, and writes no log files, so starting it in a project leaves nothing behind. For troubleshooting, set CODEOUTLINE_LOG_LEVEL (DEBUG, INFO, WARN, ERROR, ...) and CODEOUTLINE_LOG_DIR to write log files to that directory.
MCP service details
The protocol baseline is MCP 2025-06-18. Query budgets range from 256 to 262144 bytes (default 16000); truncated output stays valid UTF-8 and ends with a truncation notice. Paths always refer to the machine running the service.
In stdio mode, stdout carries only MCP messages and logs go to stderr. HTTP listens on the local machine by default; clients connect to http://127.0.0.1:19876/mcp. Remote listening requires a CODEOUTLINE_TOKEN of at least 16 bytes and hosts allowed explicitly with --allow-host; clients send Authorization: Bearer .... Unlike local HTTP, a remote service without --allow-root is limited to --project or its start directory. Repeat --allow-origin to allow full browser origins; unlisted origins are rejected. Protect the token with a TLS reverse proxy for remote deployments.
The main thread handles the protocol while a resident index thread serves queries one at a time. Requests with a progress token receive progress every second (over SSE for HTTP); there is no standalone GET/SSE endpoint (it returns 405). Limits: 64 sessions, 64 queued or running jobs, a 120-second job deadline, and sessions expire after 15 idle minutes. Cancellation takes effect at explicit checkpoints, so a single file's native parse cannot be interrupted (files are capped at 1.5 MB). Cancelled updates roll back to the last complete in-memory index; cancelling a read-only query does not discard it.
Indexing behavior and limits
The service starts parse workers on demand for full scans with at least 32 files that need reading, while the index thread commits their results. It uses 8 parse threads on Windows and 6 elsewhere; set CODEOUTLINE_INDEX_THREADS to override the count, or 0 to disable them. Workers are reused and shut down after 60 seconds idle, once all outstanding batches have returned, then recreated when needed.
The cache lives at .codeoutline/cache/<SHA-256 of path>.idx in the user's home directory. It is integrity-checked and rebuilt automatically if corrupt; every write goes to a separate temporary file that atomically replaces the old one, which survives a failed write. Up to 8 projects stay resident by default, and idle ones are evicted after 15 minutes. Directory aliases and links resolve to real absolute paths; on Windows, ASCII case is ignored.
Source encodings are confirmed on demand: the first index pass does not check each file, only the files a query touches. UTF-8 (with or without BOM) is tried first, then strict GBK conversion; a GBK file is reparsed and its symbols updated before the query runs, without modifying the file. Encoding results are cached and invalidated when a file changes, and a matched file that cannot be decoded is reported as an error. When both encodings are valid, UTF-8 wins. GBK files that no query has touched yet may still be misparsed, so Chinese identifiers can be missed; querying the file name triggers its repair.
Files are listed with ripgrep (rg) when available, honoring every .gitignore. Without rg, a directory walk supports only the common rules of the root .gitignore (no negation, no nested ignore files) and skips hidden directories, node_modules, __pycache__, and symbolic links. Project root paths must not contain ", %, !, $, backticks, backslashes, or line breaks.
Building from source
The runtime comes from the xnet2lua submodule:
git submodule update --init --recursive
The build scripts compile the LuaJIT runtime (with xproc, MPSCQ, and HTTPS) and copy it to bin/ at the repository root. On Windows, run from an MSVC developer terminal; the result links the C runtime statically. On macOS, the result is a universal binary for macOS 11 or newer.
.\tools\build-runtime.ps1
sh tools/build-runtime.sh
When running from source, pass LOG_STDERR=1 explicitly; the installed codeoutline adds it for you:
.\bin\xnet.exe scripts/codeoutline/command.lua LOG_STDERR=1 serve --stdio --project C:/src/project
Tests:
.\bin\xnet.exe tests/lua/codeoutline_spec.lua
.\bin\xnet.exe tests/lua/stability_spec.lua
.\bin\xnet.exe tests/lua/parse_pool_spec.lua
.\bin\xnet.exe tests/lua/lsp_spec.lua
npm ci
npm test
npm run test:package
npm test checks both transports with the official MCP SDK; npm run test:package builds real packages and verifies an installation outside the checkout. Set XSCAN_PURE_LUA=1 to exercise the pure-Lua scanner. Packaging and publishing are described in DISTRIBUTION.md.
Embedding
package.path = 'scripts/?.lua;' .. package.path
local service = require('codeoutline.service')
local text, info = service.explore('C:/src/project', 'Session.save', { budget = 16000 })
get, explore, and status refresh automatically; forget clears only the in-memory index, and rebuild reindexes without the disk cache. service.configure adjusts the resident project count and idle timeout. When embedding on Android, the host must call xutils_android_init(JavaVM*) once before starting worker threads; otherwise GBK conversion reports an error.
Origin and license
The code was extracted from Codua and uses the codeoutline.* namespace. CodeOutline is licensed under BSD-2-Clause; third-party notices are in THIRD_PARTY.md.
Install Codeoutline in Claude Desktop, Claude Code & Cursor
unyly install codeoutlineInstalls into Claude Desktop, Claude Code, Cursor & VS Code — handles npx, uvx and build-from-source repos for you.
First time? Get the CLI: curl -fsSL https://unyly.org/install | sh
Or configure manually
Run in your terminal:
claude mcp add codeoutline -- npx -y codeoutlineStep-by-step: how to install Codeoutline
FAQ
Is Codeoutline MCP free?
Yes, Codeoutline MCP is free — one-click install via Unyly at no cost.
Does Codeoutline need an API key?
No, Codeoutline runs without API keys or environment variables.
Is Codeoutline hosted or self-hosted?
Self-hosted: the server runs locally on your machine via the install command above.
How do I install Codeoutline in Claude Desktop, Claude Code or Cursor?
Open Codeoutline on unyly.org, pick your client tab (Claude Desktop, Claude Code, Cursor) and press Install — the config is generated automatically, no JSON editing.
Changes
Versions and requested access over time.
- New version published
Related MCPs
GitHub
PRs, issues, code search, CI status
by GitHubFilesystem
Secure file operations with configurable access controls.
Memory
Knowledge graph-based persistent memory system.
Unyly Deploy
Deploy sites and MCP servers to Unyly straight from your AI agent
by UnylyAmap Maps Mcp Server
MCP server for using the AMap Maps API
by duxiaohuiPayMCP
Lightweight payments layer for MCP servers: turn tools into paid endpoints with a two-line decorator. [PyPI](https://pypi.org/project/paymcp/) · [npm](https://w
by blustAIServer For Power BI
Enables exploring Microsoft Fabric / Power BI workspaces and semantic models, and executing ad-hoc DAX queries.
by Mitsubishi-FusoTemplate MCP Server
A CLI tool to create a new Model Context Protocol server project with TypeScript support, dual transport options, and an extensible structure
by mcpdotdirectSupabase
Database, auth and storage
by SupabaseEverything
Reference / test server with prompts, resources, and tools.
Compare Codeoutline with
Not sure what to pick?
Find your stack in 60 seconds
Author?
Embed badge for your README
Browse similar
All development MCPs
