Oculus MCP
You can read local Oculus data through four read-only tools.
List tracked GitHub/Codeberg projects and their nested group hierarchy with pagination.
List saved activity metadata in Oculus order with pagination.
List persisted inspection IDs with pagination.
Get a cached AI explanation and up to three suggested patch locations by exact inspection ID.
All tools are read-only, idempotent, and do not fetch live forge data or modify local state.
Provides read-only access to Oculus (oculus.nvim) persisted JSON state, including tracked projects and subdirectories, saved review activity metadata, inspection overview IDs, and cached AI explanations with suggested patch locations.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Oculus MCPlist my tracked projects, then explain the first cached inspection"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Oculus MCP
A working MCP adapter for oculus.nvim and Oculus Web. It reads Oculus's existing JSON files without requiring Neovim to be running and can create private web workflows using a one-time account code.
Current capabilities
Tool | Result |
| GitHub/Codeberg repositories, nested tracking groups, and optional tracked subdirectory |
| Saved activity metadata in Oculus's saved order |
| IDs of persisted inspection overviews |
| Cached AI explanation and up to three suggested patch locations |
| Available Oculus Web sectors and slugs |
| Create an account-private web dashboard from a user-supplied workflow description and one-time code |
Tools return structured outputs with schemas; create_web_workflow is annotated as a write action. Local data lists support offset and limit (maximum 50). Files are reread on each request. Unknown state fields, tokens, raw event payloads, and telemetry are excluded from results.
Two read-only MCP resources provide Slack provisioning references: oculus://slack/workspace-creation and oculus://slack/group-creation. They give the Slack method names, required scopes, JSON field names, and example payloads for an Oculus organization, channel, and @mention user group. Actual organization-specific plans live behind Oculus Web's authenticated GET /api/organizations/:id/slack-plan endpoint. The local MCP server does not expose private organization records, hold Slack tokens, or create Slack objects.
Inspection context is cached AI output, possibly stale. Oculus persists explanations and suggested locations in inspect_overviews; that cache is not a snapshot of live buffers, complete diffs, or review threads. The adapter does not fetch forge APIs, execute commands from tool arguments, create worktrees, open editors, or modify local Oculus state.
Related MCP server: local-mcp-toolbox
Create a web workflow
Sign in to Oculus Web, open /workflows, and generate a one-time setup code. Tell the MCP client the code and describe your desired workflow, including its activity, goal, steps, and any links you want included. The client calls create_web_workflow and returns the dashboard URL. A workflow is private to the account that issued the code. The code expires after ten minutes and is consumed once; generating a new code invalidates the previous one. Resource URLs should come from the user or a verified source, not be invented.
Configure the server process with the web API origin before starting it:
export OCULUS_WEB_API_URL=http://127.0.0.1:3001
uv run oculus-mcpThe configured origin must use HTTPS, or loopback HTTP for local development. The URL is fixed in server configuration rather than supplied through tool arguments. The web API must be reachable from the MCP server host. Public plugin distribution still requires a proper per-user OAuth connection; this one-time setup flow is for the current developer setup.
Run the synthetic demo
Install uv and Python 3.11 or later, then run from this repository:
uv sync --frozen
uv run oculus-mcp --state-file examples/state.json --tracking-file examples/tracking.jsonThis starts the stdio server; silence is expected until an MCP client connects. examples/state.json contains synthetic review metadata. Its issue URL is illustrative and is not evidence that a real issue exists.
For MCP Inspector, start loopback HTTP in one terminal:
uv run oculus-mcp --transport streamable-http --state-file examples/state.json --tracking-file examples/tracking.jsonThen launch Inspector and select Streamable HTTP at http://127.0.0.1:8787/mcp:
npx @modelcontextprotocol/inspectorExample requests: “Which projects do I track?”, “Show my saved review items”, and “List my cached inspections, then explain the first one and identify what is unverified.”
Connect real Oculus files
By default the server reads $XDG_STATE_HOME/nvim/oculus.json, falling back to ~/.local/state/nvim/oculus.json. Match Oculus's configured state_file if it differs. The external tracking file is opt-in, matching Oculus's own tracking_file behavior:
export OCULUS_STATE_FILE="$HOME/.local/state/nvim/oculus.json"
export OCULUS_TRACKING_FILE="$HOME/.config/oculus/tracking.json"
uv run oculus-mcpWithout an explicit tracking file the adapter reads persisted legacy project membership from the state file. It cannot see unsaved setup options or changes that have not been persisted. An explicitly configured missing or malformed tracking file returns an error; it never silently falls back to stale state membership. Tracking version 1 and nested groups are supported; custom metadata is ignored. This reader projects known fields, rather than replacing Oculus's full tracking validation or write logic.
Local Codex connection
Register the adapter directly from a checkout:
codex mcp add oculus -- uv --directory /absolute/path/to/oculus-mcp run --frozen oculus-mcp --state-file /absolute/path/to/oculus.json --tracking-file /absolute/path/to/tracking.jsonFor a demo connection use absolute paths to this repository's example files. Omit --tracking-file when Oculus uses legacy state membership.
Plugin package
plugin.json and mcp.json provide the portable Agent Plugins layout with OpenAI presentation metadata and a local stdio server. Install the console entrypoint into a persistent tool environment so the plugin host can locate it:
uv tool install /absolute/path/to/oculus-mcpEnsure oculus-mcp is on the plugin host's PATH, and configure the file paths in its environment or in mcp.json arguments. This is a development package, not a published OpenAI directory plugin. Availability of local package installation varies by client.
The HTTP mode binds only to 127.0.0.1. Local review data has no OAuth isolation and should not be forwarded to a public endpoint with real Oculus data. The one-time workflow code authorizes creation for a specific web account, but does not authenticate the other MCP read tools. A public ChatGPT plugin needs an authenticated, stable HTTPS service. Secure MCP Tunnel is a possible private developer-mode route, but does not alone satisfy public submission requirements.
Architecture and next steps
models.py defines stable output contracts. backend.py reads configured files and projects known fields. server.py exposes the tools through the official MCP SDK. The backend boundary can later support a companion bridge or hosted store without changing the tool names.
A next iteration can add an explicitly configured Neovim bridge for live inspection exports and a separately permissioned editor-open action. Rich context should include the exact commit, source URL, capture time, changed files, and review threads. Never accept arbitrary Lua or shell expressions as tool input. Current suggested file paths are labels returned to the client, not files the server opens.
A hosted version can add account isolation, authorization, GitHub/Codeberg ingestion, and event delivery for monitoring by dots. A ChatGPT panel can display saved items and inspection evidence after the core tools work. Ontology relationships can be introduced behind the backend boundary once useful cross-forge workflows are established. None of these future capabilities is claimed to work in this skeleton.
Verification
uv sync --frozen
uv run pytest
uv buildTests cover tracking precedence, nested groups, pagination, malformed and oversized files, field projection, unsafe URLs and paths, cache limitations, and real MCP initialization/tool calls over stdio and HTTP. CI runs the suite on Python 3.11, 3.12, and 3.13. The package has not yet been installed or reviewed in ChatGPT's plugin directory.
Source contracts and references
The adapter was grounded in Oculus's docs/tracking.md, lua/oculus/storage.lua, lua/oculus/saved.lua, lua/oculus/window/saved.lua, and lua/oculus/inspect/overview.lua on October 1, 2026. These are JSON compatibility boundaries, not a promise that Oculus internals will never change.
OpenAI: Build an MCP server explains tools and production transport requirements. Package your plugin describes the portable manifest. Plugin Extensions and MCP Events cover later UI and event integrations.
License
MIT. This is an independent Oculus integration and is not made or endorsed by OpenAI.
Available Tools
4 toolsget_inspection_contextARead-onlyIdempotent
Read a cached AI explanation and up to three suggested patch locations by exact ID.
| Name | Required | Description | Default |
|---|---|---|---|
| inspection_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| source | No | |
| locations | No | |
| explanation | No | |
| limitations | No | |
| patch_model | No | |
| inspection_id | Yes | |
| explanation_model | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive and closed-world, so safety is covered. The description still adds real behavioral context beyond them: the payload is 'cached' (potentially stale) and the patch suggestions are capped at three.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One tightly written sentence, front-loaded with the action and the returned content, with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be detailed, and the annotations carry the safety profile. The description supplies what is missing: what the payload is, how it is keyed, and that results are bounded.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% and the single parameter has no description, but the phrase 'by exact ID' clarifies that inspection_id is an exact identifier rather than a name or search term. That partially compensates for the undocumented schema field, but format/constraints remain unstated.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb ('Read'), a concrete resource ('cached AI explanation and up to three suggested patch locations'), and a keying mode ('by exact ID'). It is clearly distinct from the list_* siblings, though it never names them explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'By exact ID' implies the agent must already possess an inspection_id (presumably from list_inspections), but the description never states that prerequisite or when this tool should be preferred over the list tools. Usage is only inferable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_inspectionsBRead-onlyIdempotent
Discover persisted inspection IDs before requesting their cached context.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| offset | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| total | Yes | |
| inspections | Yes | |
| next_offset | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and a closed-world profile, so the safety story is covered. The description adds that results are a discovery seed for a later context call, but says nothing about pagination behavior, result ordering, or total-count semantics that matter for a list tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single well-formed sentence with the discovery purpose front-loaded and the downstream dependency trailing. No waste, though it is arguably too terse for the information it leaves out.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return-value shape need not be described. However, for a paginated list tool with 0% schema coverage, the absence of any statement about limit/offset, ordering, or expected volume leaves a real gap an agent would hit when results exceed the default limit of 20.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the description never mentions limit or offset, even though pagination is the main behavioral concern for this tool. With two undocumented parameters and no compensating text, the agent must infer paging from names alone.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Discover') and resource ('persisted inspection IDs'), which tells the agent this is an enumeration tool that yields IDs rather than full records. It implicitly distinguishes itself from get_inspection_context by positioning itself as the ID-discovery step, though it never names the sibling explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'before requesting their cached context' gives explicit sequencing guidance that routes the agent to call this before get_inspection_context. It gives a clear context of use but offers no exclusions or detail on when this is unnecessary (e.g., if IDs are already known).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_saved_itemsCRead-onlyIdempotent
Read saved activity metadata in Oculus order; does not fetch live forge data.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| offset | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| items | Yes | |
| total | Yes | |
| next_offset | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, and openWorldHint=false, so the safety profile is covered. The description adds two genuine behavioral facts the annotations do not: the result ordering ("Oculus order") and that live forge data is not fetched, so results may be stale/metadata-only. It does not cover pagination behavior or result volume.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler; the scope negation is appended efficiently. It is arguably too terse for the gaps it leaves, but there is no wasted text.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be described, and annotations carry the safety profile. However, pagination semantics are absent from both schema and description, and the undefined jargon (Oculus order, forge data) leaves an agent without a clear mental model of the result set.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so both limit and offset are undocumented in the schema, and the description never mentions pagination, defaults of 20/0, or the maximum of 50. For a two-parameter list tool the description is the only place this could be explained, and it isn't.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The verb+resource is identifiable ("Read saved activity metadata"), but "saved activity" and "Oculus order" are unexplained domain jargon, and the description does nothing to distinguish this from siblings like list_tracked_projects or list_inspections. The negation ("does not fetch live forge data") narrows scope somewhat but doesn't clarify what is returned.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no statement of prerequisites, and no reference to any alternative tool. The only hint is the negative constraint about live forge data, which an agent could infer as an exclusion but is never framed as such.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_tracked_projectsBRead-onlyIdempotent
Read tracked GitHub/Codeberg projects and their Oculus group hierarchy.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| offset | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| total | Yes | |
| source | Yes | |
| projects | Yes | |
| next_offset | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, and openWorldHint=false, so the safety profile is covered. The description adds that results include the Oculus group hierarchy, which is useful shape information, but says nothing about pagination behavior despite exposing limit/offset.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler. It is appropriately sized, though its brevity comes partly from omitting pagination and usage context.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be described. The gap is that the two pagination parameters go entirely undocumented, leaving the tool minimally adequate rather than complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so neither limit (max 50, default 20) nor offset is explained anywhere. The description does not mention pagination at all, leaving the agent to guess that these control result windowing.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb (Read) and resource (tracked GitHub/Codeberg projects) plus the Oculus group hierarchy it returns. It's clearly distinct from list_inspections and list_saved_items, though it never explicitly contrasts itself with those siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to call this versus list_saved_items or list_inspections, nor any prerequisites or exclusions. The agent must infer usage purely from the resource noun.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
4 tool updates
v0.1.0- First observed
get_inspection_context - First observed
list_inspections - First observed
list_saved_items - First observed
list_tracked_projects
TDQS
Scored across 4 tools
The list_* tools target distinct resources (projects, inspections, saved items), and get_inspection_context has a specific retrieval role. However, list_inspections and list_saved_items both concern persisted metadata, which could cause minor initial ambiguity.
All tool names use consistent snake_case with clear list_ or get_ prefixes and noun phrases. The pattern is predictable and readable throughout.
Four tools is lean but reasonable for a focused read-only inspection and cache server. Each tool covers a distinct read operation, though the surface could potentially benefit from additional targeted operations.
The tools cover listing tracked projects, inspections, saved items, and retrieving cached inspection context, but there are no create, update, delete, or refresh operations for these entities. This may be intentional for a read-only surface, but notable lifecycle gaps remain.
Maintenance
Related MCP Connectors
Read-only MCP server: let AI agents read your ORANO saved-video library, tasks, and memory.
Search your AI chat history (ChatGPT, Claude, Codex) from any MCP client. Remote, private, read-only
Read-only MCP access to authorized Vocci sessions, notes, files, and memory search.
Read-only MCP server for interior design studios: projects, overviews, weekly activity. No writes.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceA read-only MCP server that provides AI agents with live, structured workspace awareness, including project listing, git status, and budgeted context packing, minimizing token usage.22 npm2MIT
- AlicenseAqualityAmaintenanceA secure, local-first MCP server for read-only inspection and troubleshooting of development environments, exposing narrow, typed, auditable capabilities for repository inspection, log summarization, Docker review, and security scanning without granting unrestricted machine access.8MIT
- FlicenseDqualityAmaintenanceProvides read-only, structured access to Yasin ecosystem information (project registry, documentation, GitHub state, diagnostics) through the MCP protocol, enabling AI agents to query without direct repository access.223-
- FlicenseAqualityCmaintenanceA read-only MCP server that lets AI assistants inspect local workspace files, search context, view git diffs, and fetch a fixed GitHub profile, all within a sandboxed stdio transport.5-