{"name":"io.github.Align-Software-Company/opensolar-mcp","slug":"align-software-company-opensolar-mcp","title":"OpenSolar MCP","description":"Unofficial, self-hosted MCP server for the documented OpenSolar API.","url":"https://mcp.market/server/align-software-company-opensolar-mcp","rating":null,"grade":"B","score":82,"certified":false,"status":"active","category":"other","tags":[],"presence":{"score":32,"stars":0,"forks":0,"downloads_week":676,"last_push_at":"2026-09-30T11:35:40.000Z","license":"MIT"},"uptime":null,"claimed":false,"transport":"mixed","callable_via_gateway":false,"default_price_micros":0,"repository":"https://github.com/Align-Software-Company/opensolar-mcp","website":"https://github.com/Align-Software-Company/opensolar-mcp","version":"0.1.3","remotes":[],"packages":[{"registryType":"npm","identifier":"@alignco/opensolar-mcp","version":"0.1.3","runtimeHint":"npx","transport":{"type":"stdio"},"environmentVariables":[{"description":"OpenSolar bearer token","isRequired":true,"format":"string","isSecret":true,"name":"OPENSOLAR_API_TOKEN"},{"description":"OpenSolar organisation ID","isRequired":true,"format":"number","placeholder":"12345","name":"OPENSOLAR_ORG_ID"},{"description":"Tool profile: agent (curated default) or full (every registered tool)","format":"string","default":"agent","choices":["agent","full"],"name":"OPENSOLAR_PROFILE"},{"description":"Hide every tool that can change OpenSolar data","format":"boolean","default":"false","name":"OPENSOLAR_READ_ONLY"},{"description":"OpenSolar access plan; api_access hides tools that need Raw Data API Access","format":"string","choices":["api_access","raw_data"],"name":"OPENSOLAR_PLAN"},{"description":"Comma-separated toolsets that replace the profile's tool selection","format":"string","placeholder":"projects,contacts,systems","name":"OPENSOLAR_TOOLSETS"},{"description":"Directory that create_private_file may read from; uploads stay disabled when unset","format":"filepath","name":"OPENSOLAR_UPLOAD_ROOT"}]},{"registryType":"oci","identifier":"ghcr.io/align-software-company/opensolar-mcp:0.1.3","transport":{"type":"streamable-http","url":"http://localhost:3000/mcp"}}],"tools":[{"name":"accept_connection_request","description":"Accepts a pending connection. org_to_id comes from list_connection_requests. This call is not retried. …","write_action":false,"price_micros":0,"input_schema":null},{"name":"compare_project_systems","description":"Compares the systems on one project. Columns are included only when that system payload has them: kW, module count, annual kWh, kWh per kW, price, price per watt, battery kWh, and hardware names. No system is ranked. One system-details call runs when a listed system is missing modules, inverters, or batteries. An empty array counts as present. Groups already on the list are not replaced. A failed ","write_action":false,"price_micros":0,"input_schema":null},{"name":"create_connection_request","description":"Requests a connection to a partner org. org_name must match exactly. This call is not retried. …","write_action":true,"price_micros":0,"input_schema":null},{"name":"create_contact","description":"Adds a person to the live org. Send only first_name, family_name, email, and phone. This call is not retried.","write_action":true,"price_micros":0,"input_schema":null},{"name":"create_permission_role","description":"Creates a team permission role. role_type is always 1, the value the page uses for a partner role. These permissions only reduce what a partner can do. This call is not retried.","write_action":true,"price_micros":0,"input_schema":null},{"name":"create_private_file","description":"Creates a private file in the live org from a path confined to OPENSOLAR_UPLOAD_ROOT on this server. Uploads are disabled until that root is configured. The resolved real path must remain inside the root, including through symlinks. The server reads that file as multipart title and file_contents. Files over 25 MB are refused. File bytes are not accepted from the model. The download URL is omitted.","write_action":true,"price_micros":0,"input_schema":null},{"name":"create_project","description":"Creates a project in the live org. A new project can be blocked when the wallet is empty. API Access uses project-level paid entitlement while it is enabled. This call is not retried.","write_action":true,"price_micros":0,"input_schema":null},{"name":"create_webhook","description":"Creates a webhook in the live org. Requires endpoint, enabled, and debug. Leave trigger_fields and payload_fields unset to use OpenSolar defaults. project.* plus event.* plus contact.* is broader than most callers want. This call is not retried.","write_action":true,"price_micros":0,"input_schema":null},{"name":"create_workflow","description":"Creates a workflow in the live org. OpenSolar assigns the stages. Actions are omitted from the result. This call is not retried.","write_action":true,"price_micros":0,"input_schema":null},{"name":"delete_connection","description":"Deletes a connection and its sharing settings. This call is not retried. …","write_action":true,"price_micros":0,"input_schema":null},{"name":"delete_contact","description":"Removes the person from the live org. This call is not retried.","write_action":true,"price_micros":0,"input_schema":null},{"name":"delete_costing","description":"Removes the costing from the live org. This call is not retried.","write_action":true,"price_micros":0,"input_schema":null},{"name":"delete_payment_option","description":"Removes the payment option from the live org. This call is not retried.","write_action":true,"price_micros":0,"input_schema":null},{"name":"delete_pricing_scheme","description":"Removes the pricing scheme from the live org. This call is not retried.","write_action":true,"price_micros":0,"input_schema":null},{"name":"delete_private_file","description":"Removes the private file from the live org. This call is not retried.","write_action":true,"price_micros":0,"input_schema":null},{"name":"delete_project","description":"Removes the project from the live org. This call is not retried.","write_action":true,"price_micros":0,"input_schema":null},{"name":"delete_workflow","description":"Removes the workflow from the live org. This call is not retried.","write_action":true,"price_micros":0,"input_schema":null},{"name":"generate_project_document","description":"Creates a project document in the live org and returns the private file id. Omit format for the document type's default. pdf and csv set file_format on generate_document; docx calls generate_document_docx. The call sends action=save so OpenSolar stores a private file. File bytes are not returned. Use get_private_file for contents. This call is not retried.","write_action":true,"price_micros":0,"input_schema":null},{"name":"get_contact","description":"Returns one contact by id, including `is_synthetic_email`. Passport, licence, and date of birth are redacted. Contacts have no created_date or modified_date.","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_costing","description":"Returns one costing by id: title, description, and boolean priority. Per-unit rates are omitted.","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_event","description":"Returns one event by id. Adds `event_type_name` and omits `url` and `org`. Use an id from get_project events. Unknown types become `Unknown event type`.","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_org","description":"Returns the connected OpenSolar org: id, name, address, contact info, and measurement units. `verbose: true` returns the full redacted payload.","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_payment_option","description":"Returns one payment option by id: title, payment type, priority, auto-apply, and archived. `configuration_json` is omitted.","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_pricing_scheme","description":"Returns one pricing scheme by id: title, formula, priority, auto-apply, and archived. `configuration_json` is omitted.","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_private_file","description":"Returns one private file by id: title, file tag titles, project id, and size when OpenSolar sent it. The download URL stays on the server. `include_contents: true` downloads the file and refuses a body over 10 MB. Text is included for the model, capped at 100,000 characters. Images are image content. PDFs include extracted text and a PDF resource; other binary files use an embedded resource. Binar","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_project","description":"Returns one project by id: address, stage, stage_milestone, workflow ids, contacts, assigned role, system_count, design_available, and events. Use it for fields a search row does not include. When search_projects reports `resolution: unique`, that target does not need this call before a write. `verbose: true` returns the full redacted object; `design` is `[REDACTED]`. API Access may omit design.","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_project_design","description":"Reads the compressed design on one project. section defaults to summary: system count and system_price_including_tax. components and energy return unmapped true because the decompress section does not name those keys. geometry reports whether autoFacetsGeoJson is present and does not return coordinates. financials returns numeric pricing keys on each system and does not return pricing objects. Req","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_project_snapshot","description":"Reads one project plus its workflow, systems, and file metadata. A section that fails is a gap, not an empty list. Design, file URLs, and configuration JSON are omitted. payment_option is included only when the project payload points at payment_option_sold. Usage keeps the source period. Daily-per-month values are not summed into an annual total. Systems are one page from the systems list. File ti","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_proposal_data","description":"Returns proposal figures for one project: system name, annual kWh, monthly kWh, payback year, net present value, IRR, and return on investment. Requires Raw Data API Access. A 402 means this org does not have that plan. One inaccessible project returns 403. A compressed output string is decoded on the server and is not returned.","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_role","description":"Returns one role by id: display, email, phone, job title, and is_admin. Chat API keys are omitted. Optional fieldset is list only.","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_system","description":"Returns one system by id, with the list fields plus module, inverter, and battery codes and quantities when OpenSolar sent them.","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_system_details","description":"Returns modules, inverters, batteries, module groups, and incentives for systems on a project the org owns. Shared team projects cannot use this endpoint. include_parts and exclude_parts only filter the upstream `data` field, which is not returned. OpenSolar can time out on large projects; do not retry in a loop. custom_data is omitted.","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_system_image","description":"Gets a system image. Width and height are required. The server follows redirects after checking each redirect target. The first call can create a private file on the project, and a later design change regenerates it. The default result is the private file id when the response exposes one, plus content type. include_contents returns the image as MCP image content and refuses a body over 10 MB. Imag","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_workflow","description":"Returns one workflow by id, including stage id, title, milestone, order, and is_archived. Actions are omitted. Use a stage id as active_stage_id.","write_action":false,"price_micros":0,"input_schema":null},{"name":"list_connected_orgs","description":"Lists established org connections. …","write_action":false,"price_micros":0,"input_schema":null},{"name":"list_connection_requests","description":"Lists pending connection requests. …","write_action":false,"price_micros":0,"input_schema":null},{"name":"list_contacts","description":"Lists one page of contacts as `{ contacts }`. Each contact includes `is_synthetic_email` for `@os.code` addresses. Passport, licence, and date of birth are redacted. Contacts have no created_date or modified_date.","write_action":false,"price_micros":0,"input_schema":null},{"name":"list_costings","description":"Lists one page of costings as `{ costings, page, limit }`. The only optional filter is boolean priority. Per-unit rates are omitted.","write_action":false,"price_micros":0,"input_schema":null},{"name":"list_event_types","description":"Returns the OpenSolar event type ids and titles, including gaps. This is a copied docs table, not an API call.","write_action":false,"price_micros":0,"input_schema":null},{"name":"list_file_tags","description":"Returns private-file tag titles. The title is the identifier. This is a copied docs table, not an API call.","write_action":false,"price_micros":0,"input_schema":null},{"name":"list_payment_options","description":"Lists one page of payment options as `{ payment_options, page, limit }`. Optional filters are payment_type, auto_apply_enabled, and priority. `configuration_json` is omitted.","write_action":false,"price_micros":0,"input_schema":null},{"name":"list_pricing_schemes","description":"Lists one page of pricing schemes as `{ pricing_schemes, page, limit }`. Optional filters are priority, auto_apply_enabled, and pricing_formula. `configuration_json` is omitted.","write_action":false,"price_micros":0,"input_schema":null},{"name":"list_private_files","description":"Lists one page of private files as `{ private_files, page, limit }`. Each row is id, title, file tag titles, and project id. The download URL is omitted.","write_action":false,"price_micros":0,"input_schema":null},{"name":"list_project_systems","description":"Lists one page of systems for a project as `{ systems, page, limit }`. Each row has id, name, size, module count, battery kWh, annual output, and price. Not the full pricing breakdown.","write_action":false,"price_micros":0,"input_schema":null},{"name":"list_projects","description":"Lists one page of projects in the connected org. Default result is `{ projects, page, limit }` with id, title, address, dates, stage, stage_milestone, and workflow ids when OpenSolar sent them. `verbose: true` returns `{ projects, page, limit }` with the full redacted list objects. Use search_projects when you know a name, address, email, or phone. Use get_project only when you need detail beyond ","write_action":false,"price_micros":0,"input_schema":null},{"name":"list_roles","description":"Lists roles in the connected org as `{ roles }`: id, display, email, phone, job title, and is_admin. Chat API keys are omitted.","write_action":false,"price_micros":0,"input_schema":null},{"name":"list_roof_types","description":"Returns the OpenSolar roof type ids and titles. This is a copied docs table, not an API call.","write_action":false,"price_micros":0,"input_schema":null},{"name":"list_webhook_logs","description":"Lists one page of webhook logs as `{ webhook_logs, page, limit }`. Each row is id, webhook_id, event_queue_name, created_date, modified_date, and event_timestamp. An empty page can return HTTP 500. …","write_action":false,"price_micros":0,"input_schema":null},{"name":"list_webhook_queue","description":"Lists one page of the webhook queue as `{ webhook_queue, page, limit }`. Each row is id, webhook_id, model_name, event, number_of_attempts, next_attempt_at, and processing_started_at.","write_action":false,"price_micros":0,"input_schema":null},{"name":"list_webhooks","description":"Lists the org webhooks as `{ webhooks }`. Each webhook is id, endpoint, enabled, debug, trigger_fields, and payload_fields. The webhooks page does not document paging. …","write_action":false,"price_micros":0,"input_schema":null},{"name":"list_workflows","description":"Lists one page of workflows as `{ workflows, page, limit }`. Each stage includes id, title, milestone, order, and is_archived. Use a stage id as active_stage_id. Actions are omitted.","write_action":false,"price_micros":0,"input_schema":null},{"name":"preflight_project_share","description":"","write_action":false,"price_micros":0,"input_schema":null},{"name":"search_contacts","description":"","write_action":false,"price_micros":0,"input_schema":null},{"name":"search_projects","description":"","write_action":false,"price_micros":0,"input_schema":null},{"name":"share_entities","description":"Shares or unshares one kind of entity with connected orgs. resource is the same value as entity_type. This call is not retried.","write_action":false,"price_micros":0,"input_schema":null},{"name":"share_project","description":"Shares one project with one connected org. The server builds the permission role URL from permission_role_id. is_shared defaults to true when omitted. This call is not retried.","write_action":false,"price_micros":0,"input_schema":null},{"name":"update_connection","description":"Sets is_active on a connection. false disables sharing both ways. true enables it again. This call is not retried. …","write_action":true,"price_micros":0,"input_schema":null},{"name":"update_contact","description":"Updates a person in the live org. Send at least one of first_name, family_name, email, and phone. This call is not retried.","write_action":true,"price_micros":0,"input_schema":null},{"name":"update_private_file","description":"Updates a private file title in the live org. The published sample sends only title. The download URL is omitted. This call is not retried.","write_action":true,"price_micros":0,"input_schema":null},{"name":"update_project","description":"Updates address, notes, and related fields on one project in the live org. Send at least one field besides id. Stage, design, workflow, and usage are not accepted. This call is not retried.","write_action":true,"price_micros":0,"input_schema":null},{"name":"update_project_stage","description":"Sets the workflow stage on a project in the live org. Send active_stage_id with workflow_id, or stage_name. A stage title is resolved on that workflow and never matches an archived stage. No match or two matches with the same title do not PATCH. The deprecated stage field is not accepted. This call is not retried.","write_action":true,"price_micros":0,"input_schema":null},{"name":"update_project_usage","description":"Sets energy consumption on a project in the live org. Only the usage object is sent. values must match the source: one integer for annual, 12, 6, or 4 integers for the period sources, or Low, Medium, or High for estimate. This call is not retried.","write_action":true,"price_micros":0,"input_schema":null},{"name":"update_webhook","description":"Updates a webhook in the live org. A blank trigger_fields or payload_fields on an existing webhook is treated as null. This call is not retried. …","write_action":true,"price_micros":0,"input_schema":null}],"scan":{"score":82,"grade":"B","scanned_at":"2026-10-01T13:49:34.934Z","report":{"scannerVersion":"0.1.10","scannedAt":"2026-10-01T13:49:34.849Z","components":{"code":{"score":25,"max":25,"notes":["2 source files scanned"]},"reliability":{"score":-1,"max":20,"notes":["no gateway calls yet and no remote to probe"]},"poisoning":{"score":-1,"max":15,"notes":["tools not inspected (local package is not executed); not counted"]},"auth":{"score":6,"max":15,"notes":["static API keys via environment variables"]},"maintenance":{"score":15,"max":15,"notes":["last push 1 days ago"]},"identity":{"score":7,"max":10,"notes":["registry namespace matches repository owner"]}},"findings":[],"inputs":{"packages":[{"registryType":"npm","identifier":"@alignco/opensolar-mcp","version":"0.1.3","found":true,"license":"MIT","hasInstallScripts":false,"dependencyCount":6,"publishedAt":"2026-09-29T05:27:30.486Z","repositoryUrl":"git+https://github.com/Align-Software-Company/opensolar-mcp.git","weeklyDownloads":676}],"repo":{"found":true,"owner":"Align-Software-Company","repo":"opensolar-mcp","archived":false,"pushedAt":"2026-09-30T11:35:40Z","stars":0,"forks":0,"openIssues":5,"ownerType":"Organization","ownerAvatarUrl":"https://avatars.githubusercontent.com/u/247416812?v=4","ownerCreatedAt":"2025-12-02T15:58:34Z","license":"MIT"},"icon":{"url":"https://raw.githubusercontent.com/Align-Software-Company/opensolar-mcp/main/docs/images/icon.png","source":"registry","width":512,"height":512},"presence":{"stars":0,"forks":0,"downloadsWeek":676,"license":"MIT","lastPushAt":"2026-09-30T11:35:40.000Z","score":32}}}},"grade_history":[],"reviews":[]}