{"id":13643974,"url":"https://github.com/janlay/openai-cli","last_synced_at":"2026-01-31T21:22:42.696Z","repository":{"id":153972372,"uuid":"629019620","full_name":"janlay/openai-cli","owner":"janlay","description":"A universal cli for OpenAI, written in BASH.","archived":false,"fork":false,"pushed_at":"2025-01-30T09:43:31.000Z","size":41,"stargazers_count":221,"open_issues_count":2,"forks_count":20,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-21T06:42:24.414Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Shell","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/janlay.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"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}},"created_at":"2023-04-17T13:06:58.000Z","updated_at":"2025-04-10T03:30:54.000Z","dependencies_parsed_at":"2023-10-10T18:22:58.923Z","dependency_job_id":"e0ecb03b-b7db-4ebf-b8f7-f71001f0ab8e","html_url":"https://github.com/janlay/openai-cli","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/janlay/openai-cli","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/janlay%2Fopenai-cli","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/janlay%2Fopenai-cli/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/janlay%2Fopenai-cli/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/janlay%2Fopenai-cli/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/janlay","download_url":"https://codeload.github.com/janlay/openai-cli/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/janlay%2Fopenai-cli/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28955285,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-31T18:30:42.805Z","status":"ssl_error","status_checked_at":"2026-01-31T18:30:19.593Z","response_time":128,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":"2024-08-02T01:01:55.628Z","updated_at":"2026-01-31T21:22:42.690Z","avatar_url":"https://github.com/janlay.png","language":"Shell","funding_links":[],"categories":["CLIs"],"sub_categories":[],"readme":"# openai-cli\nA universal cli for OpenAI, written in BASH.\n\n# Features\n- [x] Scalable architecture allows for continuous support of new APIs.\n- [x] Custom API name, version, and all relevant properties.\n- [x] Dry-run mode (without actually initiating API calls) to facilitate debugging of APIs and save costs.\n- [x] New in v3: Supports any AI services that provide OpenAI-compatible APIs.\n\nImportant changes in version 3:\n- `-v api_version` in previous versions is now removed. If you have a custom `OPENAI_API_ENDPOINT`, you need to append API version in it. The internal API version is remove as some services like DeepSeek don't have version prefix in `/v1/chat/completions`.\n- `OPENAI_CHAT_MODEL` no longer supported, use `OPENAI_API_MODEL` instead.\n- By default, the request no longer includes optional parameters `temperature` / `max_tokens`. You need to explictly add `+temperature` / `+max_tokens` to customize if necessary.\n\nAvailable APIs:\n- [x] `chat/completions` (default API)\n- [x] `models`\n- [x] `images/generations`\n- [x] `embeddings`\n- [x] `moderations`\n\nThe default API `chat/completions` provides:\n- [x] Complete pipelining to interoperate with other applications\n- [x] Allow prompts to be read from command line arguments, file, and stdin\n- [x] Support streaming\n- [x] Support multiple topics\n- [x] Support continuous conversations.\n- [ ] Token usage\n\n# Installation\n- [jq](https://stedolan.github.io/jq/) is required.\n  - Linux: `sudo apt install jq`\n  - macOS: `brew install jq`\n- Download script and mark it executable:\n  ```bash\n  curl -fsSLOJ https://go.janlay.com/openai\n  chmod +x openai\n  ```\n  You may want to add this file to a directory in `$PATH`. \n\n  Also install the manual page, e.g.:\n  ```bash\n  pandoc -s -f markdown -t man README.md \u003e /usr/local/man/man1/openai.1\n  ```\n  \u003cdetails\u003e\n  \u003csummary\u003eFurther reading: curl's killer feature\u003c/summary\u003e\n  \u003ca href=\"https://daniel.haxx.se/blog/2020/09/10/store-the-curl-output-over-there/\"\u003e\u003ccode\u003e-OJ\u003c/code\u003e is a killer feature\u003c/a\u003e\n  \u003c/details\u003e\n\nNow you can try it out!\n\n# Tips\n## Getting started\nTo begin, type `openai -h` to access the help manual.\n\n⚠️ If you run `openai` directly, it may appear to be stuck because it expects prompt content from stdin which is not yet available. To exit, simply press Ctrl+C to interrupt the process.\n\n\u003cdetails\u003e\n  \u003csummary\u003eWhy are you so serious?\u003c/summary\u003e\n  \nWhat happens when the `openai` command is executed without any parameters? It means that:\n- The default API used will be `chat/completions`, and the schema version will be `v1`.\n- The prompt will be read from stdin.\n- The program will wait for input while stdin remains empty.\n\u003c/details\u003e\n\n## Quick Examples\nThe best way to understand how to use `openai` is to see various usage cases.\n- Debug API data for testing purposes  \n  `openai -n foo bar`\n- Say hello to OpenAI  \n  `openai Hello`\n- Use another model  \n  `openai +model=gpt-3.5-turbo-0301 Hello`\n- Disable streaming, allow for more variation in answer  \n  `openai +stream=false +temperature=1.1 Hello`\n- Call another available API  \n  `openai -a models`\n- Create a topic named `en2fr` with initial prompt  \n  `openai @en2fr Translate to French`\n- Use existing topic  \n  `openai @en2fr Hello, world!`\n- Read prompt from clipboard then send result to another topic  \n  `pbpaste | openai | openai @en2fr`\n\n## Providing prompt\nThere are multiple ways to obtain a prompt using `openai`:\n- Enclose the prompt in single quotes `'` or double quotes `\"`  \n  `openai \"Please help me translate '你好' into English\"`\n- Use any argument that does not begin with a minus sign `-`  \n  `openai Hello, world!`\n- Place any arguments after `--`  \n  `openai -n -- What is the purpose of the -- argument in Linux commands`\n- Input from stdin  \n  `echo 'Hello, world!' | openai`\n- Specify a file path with `-f /path/to/file`  \n  `openai -f question.txt`\n- Use `-f-` for input from stdin  \n  `cat question.txt | openai -f-`\n\nChoose any one you like :-)\n\n## OpenAI key\n`$OPENAI_API_KEY` must be available to use this tool. Prepare your OpenAI key in `~/.profile` file by adding this line:\n```bash\nexport OPENAI_API_KEY=sk-****\n```\nOr you may want to run with a temporary key for one-time use:\n```bash\nOPENAI_API_KEY=sk-**** openai hello\n```\n\nEnvironment variables can also be set in `$HOME/.openai/config`.\n\n## Working with compatible AI services\nYou can set the environment variable `OPENAI_COMPATIBLE_PROVIDER` to another service name in uppercase, such as `DEEPSEEK`. Then set the three environment variables `DEEPSEEK_API_ENDPOINT`, `DEEPSEEK_API_KEY`, and `DEEPSEEK_API_MODEL` respectively:\n```bash\nexport OPENAI_COMPATIBLE_PROVIDER=DEEPSEEK\nexport DEEPSEEK_API_ENDPOINT=https://api.deepseek.com\nexport DEEPSEEK_API_KEY=sk-***\nexport DEEPSEEK_API_MODEL=deepseek-chat\n```\n\nYou may have noticed that if you set `OPENAI_COMPATIBLE_PROVIDER` to `FOO`, you also need to set `FOO_API_ENDPOINT`, `FOO_API_KEY`, and `FOO_API_MODEL` accordingly.\n\nAfter gathering information on multiple AI providers, you can switch the AI service by setting a temporary environment variable, `OPENAI_COMPATIBLE_PROVIDER`, as shown below:\n```bash\n# Switch to DeepSeek\nOPENAI_COMPATIBLE_PROVIDER=DEEPSEEK openai\n# Switch to Qwen\nOPENAI_COMPATIBLE_PROVIDER=QWEN openai\n# Switch to the default provider (OpenAI)\nOPENAI_COMPATIBLE_PROVIDER= openai\n```\n\n## Testing your API invocations\n`openai` offers a [dry-run mode](https://en.wikipedia.org/wiki/Dry_run) that allows you to test command composition without incurring any costs. Give it a try!\n\n```bash\nopenai -n hello, world!\n\n# This would be same:\nopenai -n 'hello, world!'\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eCommand and output\u003c/summary\u003e\n\n```\n$ openai -n hello, world!\nDry-run mode, no API calls made.\n\nRequest URL:\n--------------\nhttps://api.openai.com/v1/chat/completions\n\nAuthorization:\n--------------\nBearer sk-cfw****NYre\n\nPayload:\n--------------\n{\n  \"model\": \"gpt-3.5-turbo\",\n  \"temperature\": 0.5,\n  \"max_tokens\": 200,\n  \"stream\": true,\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": \"hello, world!\"\n    }\n  ]\n}\n```\n\u003c/details\u003e\nWith full pipelining support, you can achieve the same functionality using alternative methods:\n\n```bash\necho 'hello, world!' | openai -n\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eFor BASH gurus\u003c/summary\u003e\n\nThis would be same:\n```bash\necho 'hello, world!' \u003ehello.txt\nopenai -n \u003chello.txt\n```\n\nEven this one:\n```bash\nopenai -n \u003c\u003c\u003c'hello, world!'\n```\n\nand this:\n```bash\nopenai -n \u003c\u003c(echo 'hello, world!')\n```\n\u003c/details\u003e\n\nIt seems you have understood the basic usage. Try to get real answer from OpenAI:\n\n```bash\nopenai hello, world!\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eCommand and output\u003c/summary\u003e\n\n```\n $ openai hello, world!\nHello there! How can I assist you today?\n```\n\n\u003c/details\u003e\n\n## Topics\nTopic starts with a `@` sign. so `openai @translate Hello, world!` means calling the specified topic `translate`.\n\nTo create new topic, like translate, with the initial prompt (system role, internally):\n```bash\nopenai @translate 'Translate, no other words: Chinese -\u003e English, Non-Chinese -\u003e Chinese'\n```\n\nThen you can use the topic by\n```bash\nopenai @translate 'Hello, world!'\n```\nYou should get answer like `你好，世界！`.\n\nAgain, to see what happens, use the dry-run mode by adding `-n`. You will see the payload would be sent:\n```json\n{\n  \"model\": \"gpt-3.5-turbo\",\n  \"temperature\": 0.5,\n  \"max_tokens\": 200,\n  \"stream\": true,\n  \"messages\": [\n    {\n      \"role\": \"system\",\n      \"content\": \"Translate, no other words: Chinese -\u003e English, Non-Chinese -\u003e Chinese\"\n    },\n    {\n      \"role\": \"user\",\n      \"content\": \"Hello, world!\"\n    }\n  ]\n}\n```\n\n## Chatting\nAll use cases above are standalone queries, not converstaions. To chat with OpenAI, use `-c`. This can also continue existing topic conversation by prepending `@topic`.\n\nPlease note that chat requests will quickly consume tokens, leading to increased costs.\n\n## Advanced\nTo be continued.\n\n## Manual\nTo be continued.\n\n# LICENSE\nThis project uses the MIT license. Please see [LICENSE](https://github.com/janlay/openai-cli/blob/master/LICENSE) for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjanlay%2Fopenai-cli","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjanlay%2Fopenai-cli","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjanlay%2Fopenai-cli/lists"}