{"id":50166235,"url":"https://github.com/softwareone-platform/mpt-extension-example","last_synced_at":"2026-05-24T21:03:36.193Z","repository":{"id":342340571,"uuid":"1171403586","full_name":"softwareone-platform/mpt-extension-example","owner":"softwareone-platform","description":"Example of SoftwareONE Marketplace Extension ","archived":false,"fork":false,"pushed_at":"2026-04-02T15:21:58.000Z","size":674,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-03T03:41:46.050Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/softwareone-platform.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","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":"2026-03-03T07:33:04.000Z","updated_at":"2026-04-02T15:23:26.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/softwareone-platform/mpt-extension-example","commit_stats":null,"previous_names":["softwareone-platform/mpt-extension-example"],"tags_count":0,"template":true,"template_full_name":null,"purl":"pkg:github/softwareone-platform/mpt-extension-example","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/softwareone-platform%2Fmpt-extension-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/softwareone-platform%2Fmpt-extension-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/softwareone-platform%2Fmpt-extension-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/softwareone-platform%2Fmpt-extension-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/softwareone-platform","download_url":"https://codeload.github.com/softwareone-platform/mpt-extension-example/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/softwareone-platform%2Fmpt-extension-example/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33450404,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-24T19:21:36.376Z","status":"ssl_error","status_checked_at":"2026-05-24T19:21:10.562Z","response_time":57,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5: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":"2026-05-24T21:03:34.636Z","updated_at":"2026-05-24T21:03:36.182Z","avatar_url":"https://github.com/softwareone-platform.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SoftwareOne Marketplace Platform Extension Example\n\nThis is a reference implementation demonstrating how to build a SoftwareOne Marketplace Platform extension. The example is designed to be **human-friendly** with clear documentation and **agent-friendly** with well-structured code and comprehensive docstrings to enable effective code generation and analysis.\n\n## Quick Start\n\n### Prerequisites\n\nTo develop/run this extension you can choose between two different options:\n\n1. Docker (using [compose.yaml](compose.yaml))\n     - Build the app service:\n         ```bash\n         docker compose build\n         ```\n     - Enter the bash shell of the container for development purposes:\n         ```bash\n         docker compose run --rm bash\n         ```\n     - Run the extension application:\n         ```bash\n         docker compose run --rm app\n         ```\n\n2. Local machine\n     - Install Node.js: https://nodejs.org/en/download\n     - Install uv: https://docs.astral.sh/uv/getting-started/installation/\n\n\n### Setup Extension\n\n1. In your vendor account, create a new extension\n2. In the extension detail view, navigate to the **Service** section and copy the **Extension Secret**\n3. Update the `settings.yaml` file with your `extension_id` and set `env_domain` if you target dev/test/staging\n4. Create a `.secrets.yaml` file in the project root with the following content:\n    ```yaml\n    api_key: \u003cyour-extension-secret\u003e\n    ```\n\n### Build Frontend\n\nInstall frontend dependencies and build the bundles:\n```bash\ncd frontend\nnpm install\nnpm run build\n```\n\nScript details (from package.json):\n- `build:types`: Type-check and emit types using `tsc -p tsconfig.json`\n- `build:code`: Bundle JS/CSS using `node esbuild.config.js`\n- `build`: Runs `build:types` then `build:code`\n- `start`: Watch mode for local development (runs types + bundler in parallel)\n\nWatch mode:\n```bash\ncd frontend\nnpm run start\n```\n\n### Install Backend Dependencies\n\nUse `uv` to create the virtual environment and install Python dependencies:\n```bash\ncd backend\nuv sync\n```\n\n### Run Extension\n\nStart the extension using:\n```bash\nuv run runext\n```\n\n\n### Run mrok Development Console\n\nOnce the extension started you can run the mrok Development Console to spy the traffic.\nIn a new terminal window run:\n\n```bash\nmrok agent dev console\n```\n\n![mrok dev console](docs/assets/mrok_dev_console.png)\n\n\nYou can also run the web version or the development console:\n\n```bash\nmrok agent dev web\n```\n\n\n## Project Structure\n\nThe complete repository structure has been moved to [docs/project-structure.md](docs/project-structure.md) to keep this README concise.\n\nHigh-level layout:\n\n- `backend/`: FastAPI service and extension runtime logic\n- `frontend/`: UI source and build config (file layout may evolve)\n- `static/`: generated frontend bundles served by backend\n- `docs/`: additional technical documentation\n- root config files: `meta.yaml`, `settings.yaml`, `compose.yaml`, `Dockerfile`\n- `LLM.md`: canonical agent-instructions body — after editing, run `uv run python tools/sync-llm.py` to mirror it into `CLAUDE.md`, `AGENTS.md`, and `.github/copilot-instructions.md`.\n\n### Key Components\n\n**Backend (FastAPI)**\n- `main.py`: Bootstrap entry point that initializes and runs the extension via `runext` CLI\n- `extension.py`: Declares the FastAPI application instance and mounts static file serving for frontend assets\n- `routers`: Defines API routes and handlers for platform events, authenticated endpoints, and internal bypass endpoints\n- `config.py`: Manages settings loading from `settings.yaml` and environment variables\n- `schema.py`: Pydantic models for type-safe request/response validation\n- `auth.py`: FastAPI dependency to inject the authentication context into the endpoint handlers.\n- `client.py`: HTTPX based Marketplace API client with built-in support for authentication in the scope of an installation.\n\n\n**Frontend (Multi-Socket Architecture)**\n- Multiple entry points for different platform sockets (dashboard, accounts, settings, etc.)\n- Each socket is compiled into a separate JavaScript bundle during the build process\n- `esbuild.config.js` handles separate bundle generation for each socket\n- Built bundles are placed in `/static` for serving by the backend\n\n**Configuration**\n- `meta.yaml`: Jinja2 template declaring extension capabilities, hooks, events, and plugs. Supports dynamic values from `settings.yaml`\n- `settings.yaml`: Public configuration values (extension_id, product_id, API endpoints, domain settings). Defaults target production; change `env_domain` for dev/test/staging.\n- `.secrets.yaml`: Sensitive data like API keys and secrets (must be created locally, never committed)\n\n**Deployment**\n- `Dockerfile`: Container image for production deployment\n- `compose.yaml`: Local development environment setup\n\n## Developer Guides\n\n- [Project Settings](docs/settings.md) — Detailed docs about project settings.\n- [Injectable Dependencies](docs/injectable-dependencies.md) — FastAPI injectable dependencies\n- [Project Structure](docs/project-structure.md) — Detailed repository layout and file organization\n- [Adding Event Handlers](docs/adding-event-handlers.md) — Subscribe to and process platform events\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsoftwareone-platform%2Fmpt-extension-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsoftwareone-platform%2Fmpt-extension-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsoftwareone-platform%2Fmpt-extension-example/lists"}