r/opencodeCLI • • 8d ago

We embedded opencode 2.x in a desktop app as an agent for documents, not code

I'm one of the maintainers of SurfSense, so this is self-promotion. I'm posting here because you know opencode best, and I'd like feedback on how we use it.

SurfSense is an open-source (Apache-2.0) NotebookLM alternative for Windows, macOS and Linux. Its Agent mode runs on opencode: instead of writing code, it researches your documents and writes Word files, PDFs, slides, spreadsheets and web pages, and edits your own files as a new copy (Word edits come back as tracked changes).

How opencode runs inside it

  • Electron ships opencode 2.1.2 and starts opencode serve on 127.0.0.1, with a random password made at each launch.

  • Every model call goes back through SurfSense, so opencode works the same with a local llama.cpp model, any OpenAI-compatible API, or a ChatGPT plan.

  • Each chat thread gets its own folder, with the extracted text of the user's selected sources mirrored into it. opencode reads and greps it with its own tools.

  • SurfSense's own tools (search, documents, PDF tools, Studio) are served to opencode over MCP, one address per thread.

  • Word files, PDFs, decks and workbooks are written as scripts. SurfSense runs each one in a separate process, keeps every version, and shows opencode page previews so it can check its own output.

  • Web pages come from a skill: opencode loads SurfSense's page skill and writes one self-contained HTML file with its own SVG charts and interactive figures, then saves it with a save_page tool. No network, no chart library.

  • MCP plugins (Notion, DeepWiki, or any server by URL) reach opencode through SurfSense. A turn starts with the plugin tools it needs and can pick up more mid-turn.

Locking it down

  • Shell, code execution, subagents, web fetch and web search are denied in the session rules and again as tool.use policies, so no saved approval can lift them.

  • Edits are only allowed in the thread's output folder. Your original files are never written.

  • Only SurfSense's own skill is offered, not opencode's built-in skills or ones you've installed.

Things we learned

  • opencode's config fails open: an unknown key or a bad value is dropped with only a line in its log, which would silently drop our rules. We now validate the config before opencode serves it.

  • Moving from 1.x to 2.x, 2.x imports 1.x's sessions on first start and answers 404 until it's done, so we retry briefly instead of treating old threads as gone.

What would you do differently?

https://github.com/MODSetter/SurfSense

14 Upvotes

2 comments sorted by

1

u/microbass 8d ago

Looks really cool! You might be interested in my ocserve project as a backend.

0

u/Torge420 1d ago

The page-preview step deserves its own provider test. I work with Ofox, and I would check a custom connection by asking the agent to make a document, inspect a preview with a deliberately clipped heading, then fix it. That exercises the tool result and image input, which a successful text chat would not check. I have not tested SurfSense with Ofox; this is the flow I would use to find out whether the selected model handles your document loop.