{"id":13845515,"url":"https://github.com/brightio/penelope","last_synced_at":"2026-10-19T09:07:44.372Z","repository":{"id":43973353,"uuid":"374207022","full_name":"brightio/penelope","owner":"brightio","description":"Penelope Shell Handler","archived":false,"fork":false,"pushed_at":"2026-09-27T17:31:24.000Z","size":749,"stargazers_count":2143,"open_issues_count":5,"forks_count":243,"subscribers_count":21,"default_branch":"main","last_synced_at":"2026-10-17T12:17:37.208Z","etag":null,"topics":["ctf","ctf-tools","hackthebox","oscp","oscp-tools","pty","rce","reverse-shell","shell-handler","tryhackme","tty"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/brightio.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":".github/SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"claude":null,"gemini":null,"cursor":null,"copilot":null,"dco":null,"cla":null,"disclosure":null}},"created_at":"2021-06-05T20:32:27.000Z","updated_at":"2026-10-17T02:13:09.000Z","dependencies_parsed_at":"2026-02-01T22:06:05.312Z","dependency_job_id":"c0adceac-c825-4293-8df2-50fb7f6dfd2b","html_url":"https://github.com/brightio/penelope","commit_stats":{"total_commits":72,"total_committers":2,"mean_commits":36.0,"dds":"0.11111111111111116","last_synced_commit":"81fd31339c697fee5223a9a6e16bd5d26199019f"},"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/brightio/penelope","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brightio%2Fpenelope","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brightio%2Fpenelope/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brightio%2Fpenelope/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brightio%2Fpenelope/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/brightio","download_url":"https://codeload.github.com/brightio/penelope/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brightio%2Fpenelope/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":344872684,"owners_count":38334567,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-10-03T21:59:58.778Z","status":"online","status_checked_at":"2026-10-17T02:00:06.547Z","response_time":57,"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":["ctf","ctf-tools","hackthebox","oscp","oscp-tools","pty","rce","reverse-shell","shell-handler","tryhackme","tty"],"created_at":"2024-08-04T17:03:27.001Z","updated_at":"2026-10-19T09:07:44.366Z","avatar_url":"https://github.com/brightio.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/user-attachments/assets/0d369fba-480e-4e27-a117-8845dbd4b58e\" alt=\"Logo\" width=\"200\"/\u003e\n\u003c/div\u003e\n\n\u003cimg src=\"https://img.shields.io/badge/Version-0.21.13-6D4AFF\"/\u003e\u003cbr\u003e\n![Black Hat Arsenal](https://img.shields.io/badge/Presented%20at-Black%20Hat%20Arsenal-111827)\n![EU](https://img.shields.io/badge/EU%202024-2563EB)\n![USA](https://img.shields.io/badge/USA%202025-B91C1C)\n![MEA](https://img.shields.io/badge/MEA%202025-15803D)\u003cbr\u003e\n![Kali Linux](https://img.shields.io/badge/Packaged%20in-Kali%20Linux-557C94)\n\nPenelope is a modern shell handler for penetration testers and CTF players. It provides a more capable alternative to basic netcat listeners, adding automatic PTY upgrades, session management, logging, file transfers and helper modules.\n\n## Table of Contents\n- 📥 [Installation](#installation)\n- ⚙️ [Features](#features)\n  - 🖥️ [Session Features](#session-features)\n  - 🌍 [Global Features](#global-features)\n  - 🧩 [Modules](#modules)\n- 💻 [Usage](#usage)\n  - ▶️ [Typical Usage](#typical-usage)\n  - 📂 [HTTP File Server (`-s`)](#http-file-server--s)\n  - 🐚 [Reverse Shell Payloads](#reverse-shell-payloads)\n  - 🎬 [Example Workflow](#example-workflow)\n  - 🖲️ [Main Menu Commands](#main-menu-commands)\n  - ⚡ [Command Line Options](#command-line-options)\n- 🔒 [Security considerations](#security-considerations)\n- 📝 [TODO](#todo)\n- ❓ [FAQ](#faq)\n- 🙌 [Thanks to the early birds](#thanks-to-the-early-birds)\n\n## Installation\n\nPenelope runs on Unix-like host systems, including Linux, macOS, FreeBSD and requires **Python 3.6+**.\n\n### Kali Linux\nPenelope is available in Kali Linux:\n```bash\nsudo apt update\nsudo apt install penelope\n```\n\n### Standalone execution\nPenelope is implemented entirely with Python’s standard library, allowing it to run as a standalone script without any external dependencies:\n```bash\nwget -q https://raw.githubusercontent.com/brightio/penelope/refs/heads/main/penelope.py \u0026\u0026 python3 penelope.py\n```\n\n### pipx\nTo install the latest upstream version directly from GitHub:\n```bash\npipx install git+https://github.com/brightio/penelope\n```\nFor a versioned and more stable release path, Penelope is also available on PyPI:\n```bash\npipx install penelope-shell-handler\n```\n\n## Features\n### Session Features\n|Feature|Unix-like target|Windows target|\n|-----------|:-------:|:-----:|\n|Auto-upgrade shell|PTY|readline(*)|\n|Real-time terminal resize|✅|❌|\n|Logging shell activity|✅|✅|\n|Download remote files/folders|✅|✅|\n|Upload local/HTTP files/folders|✅|✅|\n|In-memory local/HTTP script execution with real-time output downloading|✅|❌|\n|Local port forwarding|✅|❌|\n|Spawn shells on multiple tabs and/or hosts|✅|❌|\n|Auto-maintain N active shells per host (re-spawn on death)|✅|❌|\n\n(*) Can be manually upgraded to PTY with the `upgrade` command\n\u003e ⚠️  Windows support is experimental and under active development.\n\n### Global Features\n- Streamlined interaction with targets through modules\n- Multiple sessions\n- Multiple listeners\n- Serve files and folders over HTTP (`-s`)\n- Can be imported by Python exploits to handle shells in the same terminal (see [extras/exploit_examples](https://github.com/brightio/penelope/tree/main/extras/exploit_examples))\n- Can be used with Metasploit exploits by disabling the default handler with `set DisablePayloadHandler True`\n- Expose live sessions to an MCP client like Claude Code with the `--mcp` switch (local HTTP, token-authenticated), driving the same shells alongside you\n\n### Modules\n\nModules are shortcuts for the tools you would otherwise download and upload by hand. Type `modules` to list them and `run \u003cmodule\u003e` to use one. Nothing is bundled with Penelope: each module fetches the tool from its official repository at the moment you run it, so you always get the current version and the download happens on your machine, not on the target.\n\n|Category|Module|What it does|\n|---|---|---|\n|Privilege Escalation|`upload_privesc_scripts`|Upload linpeas, lse, deepce, pspy on Unix, or winpeas, powerup, privesccheck, fullpowers, enablealltokenprivs on Windows|\n||`peass_ng`|Run the latest PEASS-ng in the background|\n||`lse`|Run the latest linux-smart-enumeration in the background|\n||`linuxexploitsuggester`|Run the latest linux-exploit-suggester in the background|\n||`traitor`|Upload Traitor|\n||`upload_local_exploits`|Upload DirtyFrag and DirtyPipe|\n||`upload_potato`|Upload GodPotato, SigmaPotato, PrintSpoofer|\n|Credential Dumping|`upload_credump_scripts`|Upload Mimikatz, LaZagne, Snaffler, SharpWeb|\n|Active Directory|`upload_ad_scripts`|Upload PowerView, SharpHound, GhostPack, adPEAS|\n|Pivoting|`ligolo`|Upload the Ligolo-ng agent|\n||`chisel`|Upload Chisel|\n||`ngrok`|Set up a TCP tunnel through ngrok|\n|Forensics|`uac`|Collect forensic artifacts with Unix-like Artifacts Collector in the background|\n||`linux_procmemdump`|Dump process memory in the background (needs root)|\n|Persistence|`panix`|Upload PANIX|\n|Misc|`meterpreter`|Spawn a Meterpreter session|\n||`cleanup`|Remove the files and directories you uploaded to the target|\n\n![modules](https://github.com/user-attachments/assets/ff139757-ea4b-487d-8e81-e84baf911093)\n\n#### Meterpreter module demonstration\n\n![meterpreter](https://github.com/user-attachments/assets/b9cda69c-e25c-41e1-abe2-ce18ba13c4ed)\n\n## Usage\n### Typical Usage\n```bash\npenelope                          # Listening for reverse shells on 0.0.0.0:4444\npenelope -p 5555                  # Listening for reverse shells on 0.0.0.0:5555\npenelope -p 4444,5555             # Listening for reverse shells on 0.0.0.0:4444 and 0.0.0.0:5555\npenelope -i eth0 -p 5555          # Listening for reverse shells on eth0:5555\npenelope -a                       # Listening for reverse shells on 0.0.0.0:4444 and show sample reverse shell payloads\n\npenelope -c target -p 3333        # Connect to a bind shell on target:3333\n\npenelope ssh user@target          # Get a reverse shell from target on local port 4444\npenelope -p 5555 ssh user@target  # Get a reverse shell from target on local port 5555\npenelope -i eth0 -p 5555 -- ssh -l user -p 2222 target  # Get a reverse shell from target on eth0, local port 5555 (use -- if ssh needs switches)\n\npenelope -s \u003cFile/Folder\u003e         # Share a file or folder via HTTP\n```\n![Penelope](https://github.com/user-attachments/assets/b8e5cd84-60a5-4d79-b041-68bee901ab19)\n\n### HTTP File Server (`-s`)\nPenelope can be used also as a quick HTTP file server.\n\n```bash\npenelope -s file.txt                 # Serve a single file on 0.0.0.0:8000\npenelope -s /path/to/dir             # Serve a whole folder\npenelope -s a.sh b.elf notes.txt     # Serve several items at once\npenelope -s . -p 80                  # Serve the current dir on port 80\npenelope -s secret.txt -prefix xk9   # Hide behind a URL prefix: /xk9/secret.txt\npenelope -s -u                       # Upload mode: accept PUT/POST into the CWD\npenelope -s -u -ud /tmp/loot         # Upload mode, store received files in /tmp/loot\n```\n\nOn start, Penelope prints a ready-to-use link per interface (and an upload hint\nwhen `-u` is set), so you can copy-paste straight into the target shell.\n\n### Reverse Shell Payloads\nPenelope prints ready-to-paste reverse shell commands pointing back at its own Listeners, so you don't have to look them up elsewhere and fill in the IP and port by hand. There are two ways to get them:\n\n```bash\npenelope -a                          # Print every payload for each Listener as it starts\n```\n\nFrom the Main Menu, `payloads` prints them at any time, and unlike `-a` it narrows the list first. It asks which Listener the payloads should point at, and whether the target runs Linux or Windows, so you only get the ones that can actually run there. Answer `*` for every Listener and `both` for every payload:\n\n|Target|Payloads|\n|---|---|\n|Linux|Bash TCP, Netcat with a named pipe, Python3, Perl, PHP, Ruby, Msfvenom ELF|\n|Windows|PowerShell, Msfvenom EXE|\n|Both|Metasploit `generic/shell_reverse_tcp` settings|\n\nThe payloads that run on the target are base64 encoded, so the quoting survives whatever mangles it on the way in, and the PowerShell one runs with `-nop -w hidden`. The Msfvenom lines are printed as they are, since those run on your machine to build the file rather than on the target.\n\n### Example Workflow\n\nAs shown in the video below, within only a few seconds we can:\n1. Get a fully functional auto-resizable PTY shell while logging every interaction with the target\n2. Execute the latest version of LinPEAS on the target without touching the disk and save the output to a local file in real time\n3. Open one more PTY shell in another tab\n4. Upload the latest versions of LinPEAS and linux-smart-enumeration\n5. Upload a local folder with custom scripts\n6. Upload an exploit-db exploit directly from URL\n7. Download and open a remote file locally\n8. Download the remote /etc directory\n9. Automatically replace a shell when an existing session dies, helping maintain access during unstable sessions\n\nhttps://github.com/brightio/penelope/assets/65655412/7295da32-28e2-4c92-971f-09423eeff178\n\n### Main Menu Commands\nNotes:\n- By default you need to press `F12` to detach the PTY shell and go to the Main Menu. If the upgrade was not possible and you ended up with a basic shell, you can detach it with `Ctrl+C`. This also prevents the accidental killing of the shell.\n- The Main Menu supports TAB completion and also short commands. For example instead of `interact 1` you can just type `i 1`.\n- `help \u003ccommand\u003e` shows the full usage and examples for any of these.\n\n|Group|Command|What it does|\n|---|---|---|\n|Session Operations|`run`|Run a module (`help run` lists them)|\n||`upload`|Upload local files, folders, or HTTP(S)/FTP URLs to the target|\n||`download`|Download files and folders from the target|\n||`open`|Download a remote file or folder and open it with your local default application|\n||`script`|Run a local or remote script in memory and download its output in real time|\n||`exec`|Execute a command on the target and print its output|\n||`spawn`|Spawn another shell from the selected target|\n||`maintain`|Keep N active shells per target, respawning them when they die|\n||`upgrade`|Upgrade the session's shell to PTY (automatic by default, disable with `-U`)|\n||`portfwd`|Forward a local port through the session to a host the target can reach|\n|Session Management|`sessions`|List active sessions or interact with one|\n||`use`|Select a session|\n||`interact`|Interact with a session|\n||`kill`|Kill a session|\n||`dir` \\| `.`|Open the session's local folder, or Penelope's base folder if no session is selected|\n|Shell Management|`listeners`|Add, stop, or view Listeners|\n||`payloads`|Show reverse shell commands for the active Listeners|\n||`connect`|Connect to a bind shell|\n||`Interfaces`|Show the local network interfaces|\n|Miscellaneous|`help`|Main Menu help, or help for one command|\n||`modules`|Show the available modules|\n||`history`|Show Main Menu history|\n||`cd`|Show or change the session's remote working directory (the one used for transfers)|\n||`lcd`|Show or change Penelope's local working directory|\n||`SET`|Show or set option values|\n||`reload`|Reload the rc file|\n||`reset`|Reset the local terminal|\n||`DEBUG`|Open the debug console|\n||`exit` \\| `quit` \\| `q` \\| `Ctrl+D`|Exit Penelope|\n\n![Main Menu](https://github.com/user-attachments/assets/a0ba2925-ea7a-4c09-9ed0-8063a7d21b65)\n\n### Command Line Options\n```\npositional arguments:\n  args                          Arguments for -s/--serve and SSH reverse shell modes\n\noptions:\n  -p, --ports                   Ports (comma separated) to listen/connect/serve, depending on -i/-c/-s options\n                                (Default: 4444/5555/8000)\n\nReverse or Bind shell?:\n  -i, --interface               Local interface/IP to listen. (Default: 0.0.0.0)\n  -c, --connect                 Bind shell Host\n  -j, --jump                    Reverse shell jump endpoints\n\nHints:\n  -a, --payloads                Show sample reverse shell payloads for active Listeners\n  -l, --interfaces              List available network interfaces\n  -h, --help                    show this help message and exit\n\nSession Logging:\n  -L, --no-log                  Disable session log files\n  -T, --no-timestamps           Disable timestamps in logs\n  -CT, --no-colored-timestamps  Disable colored timestamps in logs\n\nMisc:\n  -M, --menu                    Start in the Main Menu\n  -m, --maintain                Keep N sessions per target\n  -S, --single-session          Accommodate only the first created session\n  -ms, --max-sessions           Max active sessions per host (default 5, 0 = reject all new)\n  -C, --no-attach               Do not auto-attach on new sessions\n  -U, --no-upgrade              Disable shell auto-upgrade\n  -H, --keep-history            Keep target shell history (do not set HISTFILE=/dev/null)\n  -O, --oscp-safe               Enable OSCP-safe mode\n  --no-disk                     Keep all state in RAM (tmpfs); nothing persists to disk\n\nMCP:\n  --mcp                         Enable the MCP server over local HTTP\n  --mcp-host                    Host/IP to bind (default: 127.0.0.1)\n  --mcp-port                    Port to bind (default: saved port, else a random free port persisted to ~/.penelope/mcp.json)\n  --mcp-token                   Bearer token (default: saved token, else auto-generated and persisted)\n\nFile server:\n  -s, --serve                   Run HTTP file server mode\n  -prefix, --url-prefix         URL path prefix\n  -u, --upload                  Enable file upload (PUT/POST) to the server\n  -ud, --upload-dir             Directory to store uploads (default: CWD)\n\nDebug:\n  -N, --no-bins                 Simulate missing binaries on target (comma-separated)\n  -v, --version                 Print version and exit\n  -d, --debug                   Enable debug output\n  -dd, --dev-mode               Enable developer mode\n  -cu, --check-urls             Check hardcoded URLs health and exit\n```\n\n## Security considerations\n\nPenelope is designed to provide direct and flexible interaction with remote shells. Keep the following in mind when using it:\n\n- **Terminal escape sequences:** Penelope forwards terminal output from remote systems directly to your terminal emulator. Malicious remote processes may use terminal escape sequences to manipulate the screen, create misleading links, or interact with features such as the clipboard. This exposure is inherent to any tool that relays a remote shell to the local terminal (like SSH, telnet, netcat) and is not specific to Penelope. Use a terminal with appropriate security settings when connecting to untrusted systems.\n\n- **Session logs:** Session logs may contain credentials, tokens, commands and other sensitive information received from the target. Store them securely and use `--no-log` when logging is not required.\n\n- **Unencrypted connections:** Standard reverse and bind shell connections are not encrypted. Avoid using them over untrusted networks unless the traffic is protected by a secure tunnel or VPN.\n\n- **MCP server (`--mcp`):** When enabled, the MCP server grants full control over every active session (command execution, file transfer) to any client holding the bearer token, which is stored in `~/.penelope/mcp.json` (`0600`). It binds to `127.0.0.1` and is token-authenticated. Keep the token secret and avoid exposing the server on untrusted networks.\n\n\u003e ⚖️ **Disclaimer:** Penelope is intended for authorized security testing, research and educational purposes only. Do not use it against systems without explicit permission.\n\n## TODO\n\n### Features\n* encryption\n* remote port forwarding\n* socks \u0026 http proxy\n* team server\n* HTTPs and DNS agents\n\n### Known Issues\n* Session logging: commands that use alternate buffers, such as nano, may leave escape sequences in the log if they terminate abnormally. The data is still preserved, but viewing the logfile with tools like `cat` may look corrupted. Filtering these escape sequences is planned to make log output smoother.\n\n## FAQ\n\n### ► Is Penelope allowed in the OSCP exam?\n\nPenelope’s core shell-handling features do not perform automatic exploitation, which makes them suitable for OSCP-style usage. However, exam rules can change, so always verify the current official OffSec rules before using any tool during an exam.\n\nSome modules require extra caution:\n\n* The meterpreter module should only be used in a way that complies with the current exam rules.\n* The traitor module uploads Traitor, which performs automatic privilege escalation.\n\nIf you want to avoid accidental rule violations, use the `-O / --oscp-safe` switch.\n\n### ► How can I return from the remote shell to the Main Menu?\nIt depends on the type of shell upgrade in use:\n* PTY: press `F12`\n* Readline: send EOF (`Ctrl-D`)\n* Raw: send SIGINT (`Ctrl-C`)\n\nIn any case, the correct key is always displayed when you attach to a session. For example:\n\n![F12](https://github.com/user-attachments/assets/87da0eec-0d78-4f1b-8e82-f3ebe9cacf5e)\n\n### ► How can I customize Penelope (change default options, create custom modules, etc.)?\nSee [peneloperc](https://github.com/brightio/penelope/blob/main/extras/peneloperc)\n\n### ► Why aren’t my current working directory or user preserved when I use menu commands like download/upload?\nThis usually means you opened a new interactive shell, possibly under a different user. The Penelope agent only tracks the directory of the initial shell and keeps the permissions of the user from that first shell. The best workaround is to `cd /tmp` before opening a new shell, or, if you switched users, spawn a new reverse shell as the new user.\n\n### ► How can I contribute?\nYour contributions are invaluable! If you’d like to help, please report bugs, unexpected behaviors, or share new ideas. You can also submit pull requests but avoid making commits from IDEs that enforce PEP8 and unintentionally restructure the entire codebase.\n\n### ► Where does the name come from?\nPenelope was the wife of Odysseus and is known for her loyalty and patience while waiting for him to return. The tool is named after her because it was built to be a faithful and stable shell handler for workflows that go beyond a basic listener.\n\n## Thanks to the early birds\n* [Cristian Grigoriu - @crgr](https://github.com/crgr) for inspiring me to automate the PTY upgrade process. This is how this project was born.\n* [Paul Taylor - @bao7uo](https://github.com/bao7uo) for the idea to support bind shells.\n* [Longlone - @WAY29](https://github.com/WAY29) for indicating the need for compatibility with previous versions of Python (3.6).\n* [Carlos Polop - @carlospolop](https://github.com/carlospolop) for the idea to spawn shells on listeners on other systems.\n* [@darrenmartyn](https://github.com/darrenmartyn) for indicating an alternative method to upgrade the shell to PTY using the script command.\n* [@bamuwe](https://github.com/bamuwe) for the idea to get reverse shells via SSH.\n* [@strikoder](https://github.com/strikoder) for numerous enhancement ideas.\n* [@root-tanishq](https://github.com/root-tanishq), [@robertstrom](https://github.com/robertstrom), [@terryf82](https://github.com/terryf82), [@RamadhanAmizudin](https://github.com/RamadhanAmizudin), [@furkan-enes-polatoglu](https://github.com/furkan-enes-polatoglu), [@DerekFost](https://github.com/DerekFost), [@Mag1cByt3s](https://github.com/Mag1cByt3s), [@nightingalephillip](https://github.com/nightingalephillip), [@grisuno](https://github.com/grisuno), [@thinkslynk](https://github.com/thinkslynk), [@stavoxnetworks](https://github.com/stavoxnetworks), [@thomas-br](https://github.com/thomas-br), [@joshoram80](https://github.com/joshoram80), [@TheAalCh3m1st](https://github.com/TheAalCh3m1st), [@r3pek](https://github.com/r3pek), [@bamuwe](https://github.com/bamuwe), [@six-two](https://github.com/six-two), [@x9xhack](https://github.com/x9xhack), [@dummys](https://github.com/dummys), [@pocpayload](https://github.com/pocpayload), [@anti79](https://github.com/anti79), [@strikoder](https://github.com/strikoder), [@bestutsengineer](https://github.com/bestutsengineer) for bug reporting.\n* Special thanks to [@Y3llowDuck](https://github.com/Y3llowDuck) for spreading the word!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrightio%2Fpenelope","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbrightio%2Fpenelope","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrightio%2Fpenelope/lists"}