{"id":30444467,"url":"https://github.com/synthetic-lab/octofriend","last_synced_at":"2026-06-30T03:03:43.429Z","repository":{"id":284425426,"uuid":"954908083","full_name":"synthetic-lab/octofriend","owner":"synthetic-lab","description":"An open-source coding helper. Very friendly!","archived":false,"fork":false,"pushed_at":"2026-06-24T00:36:07.000Z","size":5165,"stargazers_count":984,"open_issues_count":33,"forks_count":78,"subscribers_count":7,"default_branch":"main","last_synced_at":"2026-06-24T01:22:24.722Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/synthetic-lab.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-03-25T19:57:47.000Z","updated_at":"2026-06-24T00:36:10.000Z","dependencies_parsed_at":"2025-12-30T18:11:37.860Z","dependency_job_id":null,"html_url":"https://github.com/synthetic-lab/octofriend","commit_stats":null,"previous_names":["reissbaker/octofriend","synthetic-lab/octofriend"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/synthetic-lab/octofriend","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/synthetic-lab%2Foctofriend","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/synthetic-lab%2Foctofriend/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/synthetic-lab%2Foctofriend/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/synthetic-lab%2Foctofriend/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/synthetic-lab","download_url":"https://codeload.github.com/synthetic-lab/octofriend/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/synthetic-lab%2Foctofriend/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34950358,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-30T02:00:05.919Z","response_time":92,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-08-23T10:02:20.423Z","updated_at":"2026-06-30T03:03:43.424Z","avatar_url":"https://github.com/synthetic-lab.png","language":"TypeScript","funding_links":[],"categories":["📊 The List","Related Projects","TypeScript","Alternatives to Claude Code","others"],"sub_categories":[],"readme":"Octo is a small, helpful, zero-telemetry, cephalopod-flavored coding assistant.\nOcto is your friend.\n\n## Get Started\n\n```bash\nnpm install --global octofriend\n```\n\nAnd then:\n\n```bash\noctofriend\n# or, for short:\nocto\n```\n\n![octofriend](https://raw.githubusercontent.com/synthetic-lab/octofriend/main/octofriend.png)\n\n## About\n\nOcto is a small, helpful, cephalopod-flavored coding assistant that works with\nany OpenAI-compatible or Anthropic-compatible LLM API, and allows you to switch\nmodels at will mid-conversation when a particular model gets stuck. Octo can\noptionally use (and we recommend using) ML models we custom-trained and\nopen-sourced ([1](https://huggingface.co/syntheticlab/diff-apply),\n[2](https://huggingface.co/syntheticlab/fix-json)) to automatically handle tool\ncall and code edit failures from the main coding models you're working with:\nthe autofix models work with any coding LLM. Octo works great with Kimi K2.5,\nMiniMax M2.5, GPT-5.3, and Claude 4.6 (although pretty much any agentic\ncoding model will work). Octo wants to help you because Octo is your friend.\n\nOcto has zero telemetry. Using Octo with a privacy-focused LLM provider (may we\nselfishly recommend [Synthetic](https://synthetic.new)?) means your code stays\nyours. But you can also use it with any OpenAI-compatible API provider, with\nAnthropic, or with local LLMs you run on your own machine.\n\n## Enabling web search\n\nBy default, Octo will look for Synthetic API keys to use Synthetic's private,\nzero-data-retention search API to power Octo's web search tool. If you have any\nSynthetic models configured anywhere in Octo, Octo's search tool will Just\nWork: even non-Synthetic-hosted models, like Claude, will be able to use Octo's\nweb search tool.\n\nIf you don't want to use Synthetic's search API, but you still want to use the\nweb search tool, you can configure the `search` config in\n`~/.config/octofriend/octofriend.json5`:\n\n```typescript\n{\n  // ...the rest of your config,\n  search: {\n    url: \"some_search_api_url\",\n    apiEnvVar: \"SOME_ENV_VAR_FOR_AUTH\"\n  },\n}\n```\n\nThe search tool will make POST requests against the configured URL with the\nfollowing format, which is compatible with both Synthetic and\n[Exa](https://exa.ai):\n\n```javascript\n{\n  query: \"some search query\",\n}\n```\n\nIf you don't configure the `search` config, and you don't configure any\nSynthetic API keys, Octo's harness will automatically hide the web search tool\nso Octo doesn't try to call it.\n\n## Demo\n\n[![Octo asciicast](https://raw.githubusercontent.com/synthetic-lab/octofriend/main/octo-asciicast.svg)](https://asciinema.org/a/728456)\n\n## Sandboxing Octo\n\nOcto has built-in Docker support, and can attach to any Docker container\nwithout needing special configuration or editing the image or container. To\nmake Octo run inside an _existing_ container you have running — for example, if\nyou already have a Docker Compose setup — run `octo docker connect\nyour-container-name`.\n\nTo have Octo launch a Docker image and shut it down when Octo quits, you can\nrun:\n\n```bash\n# Make sure to add the -- before the docker run args!\nocto docker run -- ordinary-docker-run-args\n```\n\nFor example, to launch Octo inside an Alpine Linux container:\n\n```bash\nocto docker run -- -d -i -t alpine /bin/sh\n```\n\nAll of Octo shell commands and filesystem edits and reads will happen inside\nthe container. However, Octo will continue to use any MCP servers you have\ndefined in your config via your host machine (since the MCP servers are\npresumably running on your machine, not inside the container), and will make\nHTTP requests from your machine as well if it uses the built-in `fetch` tool,\nso that you can use arbitrary containers that may not have `wget` or `curl`\ninstalled.\n\n## Rules\n\nOcto will look for instruction files named like so:\n\n- `OCTO.md`\n- `CLAUDE.md`\n- `AGENTS.md`\n\nOcto uses the _first_ one of those it finds: so if you want to have different\ninstructions for Octo than for Claude, just have an `OCTO.md` and a\n`CLAUDE.md`, and Octo will ignore your `CLAUDE.md`.\n\nOcto will search the current directory for rules, and every parent directory,\nup until (inclusive of) your home directory. All rule files will be merged: so\nif you want project-specific rules as well as general rules to apply\neverywhere, you can add an `OCTO.md` to your project, as well as a global\n`OCTO.md` in your home directory.\n\nIf you don't want to clutter your home directory, you can also add a global\nrules file in `~/.config/octofriend/OCTO.md`.\n\n## Skills\n\nOcto supports the [Agent Skills](https://agentskills.io/) spec for giving\nreusable context-dependent instructions. If you want to give special\ninstructions for Octo to do code reviews, for example, you might write a code\nreview skill file, and Octo will intelligently load the skill when it needs to\ndo code reviews. You can find the full skill spec on the [Agent Skills\nwebsite](https://agentskills.io), but they're essentially just tagged Markdown\nwith optional scripts. Here's a very simple code review skill you might use:\n\n```markdown\n---\nname: \"pr-review\"\ndescription: \"Review Github pull requests\"\n---\n\nTo load a Github pull request, run the fetch tool twice:\n\n## First fetch\n\nFirst, load the URL for the PR to understand the author's intent.\n\nYour fetch tool does not execute JavaScript. Note that parts of the Github UI\nmay fail without JS; for example, loading comments might say:\n\n    UH OH!\n    There was an error while loading\"\n\nThis is okay and expected. Don't worry about that.\n\n## Second fetch: load the diff\n\nTo load the diff for the PR, fetch the PR URL with a `.diff`\nattached to the end. For example, to review\n`https://github.com/synthetic-lab/octofriend/pull/66`, you should fetch:\n\n`https://github.com/synthetic-lab/octofriend/pull/66.diff`\n\nThe diff is the most important part. The author may be incorrect, or have the\nright idea but the wrong implementation. Focus on whether there are any bugs or\nunexpected behavior.\n```\n\nWe automatically detect skills in the following places:\n\n- `~/.config/agents/skills`, for global skill definitions\n- `.agents/skills`, for skills relative to the current directory Octo is\n  working in. For example, if your company has special guidelines for agents,\n  you can distribute them with your company's repo in an `.agents/skills`\n  directory.\n\nIf there are more directories you want Octo to discover skills from, you can\nadd them to your `~/.config/octofriend/octofriend.json5` config file like so:\n\n```javascript\nskills: {\n  paths: [\n    // a list of directory paths containing skills\n  ],\n},\n```\n\n## Connecting Octo to MCP servers\n\nOcto can do a lot out of the box — pretty much anything is possible with enough\nBash — but if you want access to rich data from an MCP server, it'll help Octo\nout a lot to just provide the MCP server directly instead of trying to contort\nits tentacles into crafting the right Bash-isms. After you run `octofriend` for\nthe first time, you'll end up with a config file in\n`~/.config/octofriend/octofriend.json5`. To hook Octo up to your favorite MCP\nserver, add the following to the config file:\n\n```json5\nmcpServers: {\n  serverName: {\n    command: \"command-string\",\n    args: [\n      \"arguments\",\n      \"to\",\n      \"pass\",\n    ],\n  },\n},\n```\n\nFor example, to plug Octo into your Linear workspace:\n\n```json5\nmcpServers: {\n  linear: {\n    command: \"npx\",\n    args: [ \"-y\", \"mcp-remote\", \"https://mcp.linear.app/sse\" ],\n  },\n},\n```\n\n## Using Octo with local LLMs\n\nIf you're a relatively advanced user, you might want to use Octo with local\nLLMs. Assuming you already have a local LLM API server set up like ollama or\nllama.cpp, using Octo with it is super easy. When adding a model, make sure to\nselect `Add a custom model...`. Then it'll prompt you for your API base URL,\nwhich is probably something like: `http://localhost:3000`, or whatever port\nyou're running your local LLM server on. After that it'll prompt you for an\nenvironment variable to use as a credential; just use any non-empty environment\nvariable and it should work (since most local LLM server ignore credentials\nanyway).\n\nYou can also edit the Octofriend config directly in\n`~/.config/octofriend/octofriend.json5`. Just add the following to your list of\nmodels:\n\n```json5\n{\n  nickname: \"The string to show in the UI for your model name\",\n  baseUrl: \"http://localhost:SOME_PORT\",\n  apiEnvVar: \"any non-empty env var\",\n  model: \"The model string used by the API server, e.g. openai/gpt-oss-20b\",\n}\n```\n\n## Debugging\n\nBy default, Octo tries to present a pretty clean UI. If you want to see\nunderlying error messages from APIs or tool calls, run Octo with the\n`OCTO_VERBOSE` environment variable set to any truthy string; for example:\n\n```bash\nOCTO_VERBOSE=1 octofriend\n```\n\n## Desktop notifications\n\nThere's a hidden \"Notifications\" menu that only appears if you've configured\ndesktop notifications. To configure desktop notifications, add a block like\nthis to your `octofriend.json5`:\n\n```json5\nnotifications: {\n  notifyCommand: \"notify-send Octo 'Finished responding!'\",\n},\n```\n\nOr for macOS:\n\n```json5\nnotifications: {\n  notifyCommand: 'osascript -e \\'display notification \"Octo finished!\"\\'',\n},\n```\n\nThis enables the Notifications submenu in the main `ctrl-p` menu. You can set\nit to the following three settings:\n\n- Notify the next time Octo needs input\n- Notify any time Octo needs input this session\n- Always notify any time Octo needs input\n\nThe last option will be persisted to your config file, if you set it.\n\nBy default, for the session-level and persistent notifications, Octo will wait\n10 seconds before notifying you, and if it receives input during that time\nit'll skip the notification (so as to not spam you with notifications when\nyou're actively attending to it and chatting). To change the wait time, set:\n\n```json5\nnotifications: {\n  notifyCommand: \"some command\",\n  notifyTimeoutMs: 20000, // Or however many milliseconds you want to wait\n},\n```\n\n## Opting into canary versions\n\nIf you want to use unreleased versions of Octo, clone this repo and read the\ninstructions in `canary.sh` to install `canary-octo` in your shell.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsynthetic-lab%2Foctofriend","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsynthetic-lab%2Foctofriend","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsynthetic-lab%2Foctofriend/lists"}