{"name":"com.4chems/platform-api","slug":"4chems-platform-api","title":"4chems Platform — IUCLID, CHESAR & QSAR Toolbox hosting","description":"Remote MCP server for 4chems hosted IUCLID, CHESAR and QSAR Toolbox: onboarding, inquiries, admin.","url":"https://mcp.market/server/4chems-platform-api","rating":null,"grade":"B","score":84,"certified":false,"status":"active","category":"other","tags":[],"presence":{"score":23,"stars":0,"forks":0,"downloads_week":null,"last_push_at":"2026-10-09T19:28:09.000Z","license":null},"uptime":{"percent":89,"checks":28,"ok":25,"last_checked_at":"2026-11-04T08:30:29.429Z","last_ok_at":"2026-11-03T05:50:28.164Z","latency_ms":876},"claimed":false,"transport":"remote","callable_via_gateway":true,"default_price_micros":0,"repository":"https://github.com/4chems/mcp","website":"https://www.4chems.com/mcp/","version":"0.12.1","remotes":[{"type":"streamable-http","url":"https://mcp.4chems.com/mcp"}],"packages":[],"tools":[{"name":"accept_invitation","description":"Accept a pending invitation and grant the invitee's first role assignment.\nCall this when an invitee has a valid invite link and wants to join the\ntenant; single-use, consuming the token marks it accepted.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"authorization":{"type":"string"},"token":{"type":"string"}},"required":["authorization","token"],"additionalProperties":false}},{"name":"add_tenant_service","description":"Request a new service subscription for the caller's tenant and return its\nstatus. Call this when a tenant admin wants to add a service (ADR 0016\ncode fix: requires `admin`, was `customer` realm role only).","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"authorization":{"type":"string"},"tenant_id":{"default":"","type":"string"},"body":{"default":"","properties":{"service":{"type":"string"}},"required":["service"],"type":"object"}},"required":["authorization"],"additionalProperties":false}},{"name":"approve_access_request","description":"Approve a pending access request: issue a `member` invitation to the\nrequester and resolve the request (level `admin` or `owner` of the\nrequest's tenant). The response carries the single-use invitation token\nto hand to the requester, who accepts via `accept_invitation`. 409\n`access_request.not_pending` unless the request is pending.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"authorization":{"type":"string"},"access_request_id":{"type":"string"}},"required":["authorization","access_request_id"],"additionalProperties":false}},{"name":"complete_billing","description":"Complete the tenant's billing details: legal-entity name and type, VAT id,\ninvoice address, invoice email and optional PO reference. Call this when the\nowner or a billing contact has the details. EU VAT ids are validated against\nVIES by the worker; a failed operation with `billing.vat_check_unavailable`\ncan be retried by submitting again. Returns `202` with an operation to poll.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"authorization":{"type":"string"},"tenant_id":{"default":"","type":"string"},"body":{"default":"","description":"`complete_billing` body. `vat_id` is checked against the tenant's country in the service.","properties":{"address_line1":{"maxLength":200,"minLength":1,"type":"string"},"address_line2":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}]},"city":{"maxLength":100,"minLength":1,"type":"string"},"invoice_email":{"format":"email","type":"string"},"legal_entity_type":{"anyOf":[{"pattern":"^[A-Z]{2,3}_[A-Z0-9][A-Z0-9_]*$","type":"string"},{"type":"null"}]},"name":{"anyOf":[{"maxLength":200,"minLength":1,"type":"string"},{"type":"null"}]},"other_label":{"anyOf":[{"maxLength":80,"minLength":2,"type":"string"},{"type":"null"}]},"po_reference":{"anyOf":[{"maxLength":64,"minLength":1,"type":"string"},{"type":"null"}]},"postal_code":{"maxLength":20,"minLength":1,"type":"string"},"vat_id":{"anyOf":[{"maxLength":40,"type":"string"},{"type":"null"}]}},"required":["address_line1","postal_code","city","invoice_email"],"type":"object"}},"required":["authorization"],"additionalProperties":false}},{"name":"create_access_request","description":"Request access to the tenant that owns the caller's verified email domain.","write_action":true,"price_micros":0,"input_schema":{"type":"object","properties":{"authorization":{"type":"string"}},"required":["authorization"],"additionalProperties":false}},{"name":"create_invitation","description":"Invite an email address to the caller's tenant at the specified access\nlevel and return the invitation, including the raw single-use accept\ntoken. Call this when a tenant admin wants to add a new member; the\ninvitee accepts via `accept_invitation`.","write_action":true,"price_micros":0,"input_schema":{"type":"object","properties":{"authorization":{"type":"string"},"tenant_id":{"default":"","type":"string"},"body":{"default":"","properties":{"billing_contact":{"default":false,"type":"boolean"},"email":{"format":"email","type":"string"},"level":{"description":"The grantable tenant access levels (ADR 0016 decision 3: role collapse).\n\nScoped department/instance roles (``team_admin``, ``env_admin``,\n``app_admin``, ``application_owner``, ``application_supervisor``,\n``application_user``) and the platform roles (``platform_admin``,\n``node_admin``) are no longer grantable; the migration\n(``uc087accesslevelscore_0001``) maps every existing row onto one of\nthese four values.","enum":["viewer","member","admin","owner"],"type":"string"}},"required":["email"],"type":"object"}},"required":["authorization"],"additionalProperties":false}},{"name":"create_self_service_tenant","description":"Create a 7-day trial tenant for the caller's business email domain (UC-052).\nNeeds a verified email on a business domain and `attestation: true`; answers\n`auth.email_not_verified`, `tenant.attestation_required`,\n`tenant.free_mail_domain` (free-mail address), `tenant.domain_exists`\n(a live trial tenant on the domain) or `trial.exists_for_domain` (the\ndomain already had its one trial; call `start_inquiry`). The trial lasts\nexactly 7 days; `ttl` / `expires_at` in the body are ignored.","write_action":true,"price_micros":0,"input_schema":{"type":"object","properties":{"authorization":{"type":"string"},"body":{"default":"","description":"Request body for POST /v1/onboarding/tenants (UC-052).\n\nThe domain is derived from the caller's verified token email claim\n(NFR-006 pt 4) — it is not a request parameter.\nattestation must be true; the endpoint raises 422 if false (NFR-006 §8a).","properties":{"attestation":{"type":"boolean"},"bot_signals":{"anyOf":[{"description":"Advisory bot-detection signals from the onboarding wizard (UC-052).\n\nRecorded and fed to scoring; never used as a hard gate.","properties":{"honeypot":{"anyOf":[{"type":"string"},{"type":"null"}]},"submit_timing_ms":{"anyOf":[{"type":"integer"},{"type":"null"}]}},"type":"object"},{"type":"null"}]},"legal_entity":{"description":"Composite legal-entity input validated against the country catalog.\n\nRules:\n- *country* must be a supported market (validated at field level via SupportedCountry,\n  caught in the model validator against the loaded catalog).\n- *legal_entity_type* must appear in that country's catalog file.\n- When *legal_entity_type* is ``<CC>_OTHER``, *other_label* is required (2-80 chars).\n- For any other type, *other_label* must be absent.","properties":{"country":{"pattern":"^[A-Z]{2}$","type":"string"},"legal_entity_type":{"pattern":"^[A-Z]{2,3}_[A-Z0-9][A-Z0-9_]*$","type":"string"},"name":{"maxLength":200,"minLength":1,"type":"string"},"other_label":{"anyOf":[{"maxLength":80,"minLength":2,"type":"string"},{"type":"null"}]}},"required":["country","legal_entity_type","name"],"type":"object"}},"required":["legal_entity","attestation"],"type":"object"}},"required":["authorization"],"additionalProperties":false}},{"name":"dismiss_access_request","description":"Dismiss a pending access request (level `admin` or `owner` of the\nrequest's tenant). The requester is mailed — naming the tenant, never the\ndismissing admin — and may ask again. 409 `access_request.not_pending`\nunless the request is pending.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"authorization":{"type":"string"},"access_request_id":{"type":"string"}},"required":["authorization","access_request_id"],"additionalProperties":false}},{"name":"enrich_domain","description":"Fetch the caller's domain imprint and suggest legal-entity details (UC-057).","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"authorization":{"type":"string"}},"required":["authorization"],"additionalProperties":false}},{"name":"get_billing","description":"Return the tenant's stored billing details: VAT id, invoice address, invoice\nemail and PO reference. Call this to check whether billing is complete; only\nthe owner and billing contacts may read it (`403 rbac.insufficient_level`).","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"authorization":{"type":"string"},"tenant_id":{"default":"","type":"string"}},"required":["authorization"],"additionalProperties":false}},{"name":"get_catalog_templates","description":"Return the enabled ApplicationTemplate catalog, ordered by name. Call this to\ndiscuss trial and template options with a prospect or customer before starting a\ntrial. If this doesn't answer your question, call `start_inquiry` to ask\n4chems directly or request a call.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"authorization":{"default":"","type":"string"}},"additionalProperties":false}},{"name":"get_legal_entity_types","description":"Return the legal-entity types available for *country*, ordered alphabetically.\nIf this doesn't answer your question, call `start_inquiry` to ask 4chems directly\nor request a call.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"country":{"description":"ISO 3166-1 alpha-2 country code","type":"string"},"authorization":{"default":"","type":"string"}},"required":["country"],"additionalProperties":false}},{"name":"get_my_access","description":"Return the caller's access level per related tenant. Call this to check\nwhat the current caller is authorized to do before attempting an action\nthat requires a specific level, or to discover a pending invitation or\naccess request.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"authorization":{"type":"string"}},"required":["authorization"],"additionalProperties":false}},{"name":"get_my_operation","description":"Return the status, result and error of an operation the caller started, such as\nthe `Location` of a `202` from `complete_billing`. Call this to poll it to completion.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"authorization":{"type":"string"},"operation_id":{"type":"string"}},"required":["authorization","operation_id"],"additionalProperties":false}},{"name":"get_onboarding_route","description":"Return the next onboarding step. If this doesn't answer your question, call\n`start_inquiry` to ask 4chems directly or request a call.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"authorization":{"default":"","type":"string"}},"additionalProperties":false}},{"name":"grant_assignment","description":"Grant a role x scope assignment to a tenant member.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"authorization":{"type":"string"},"sub":{"type":"string"},"tenant_id":{"default":"","type":"string"},"body":{"default":"","properties":{"role":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["role","scope_type","scope_id"],"type":"object"}},"required":["authorization","sub"],"additionalProperties":false}},{"name":"list_consents","description":"Return the caller's own recorded consents plus the tenant-scope consents of\nevery tenant where the caller is at least a viewer. Call this to check which legal\ndocuments have already been accepted before asking again. Pass `tenant_id` to\nlist one tenant's consents only (a caller of several tenants must).","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"authorization":{"type":"string"},"tenant_id":{"default":"","type":"string"}},"required":["authorization"],"additionalProperties":false}},{"name":"list_invitations","description":"List all invitations for the caller's tenant, most recent first. Call this to\nshow a tenant admin which invitations are pending, accepted, or revoked; the\nraw token is never included.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"authorization":{"type":"string"},"tenant_id":{"default":"","type":"string"}},"required":["authorization"],"additionalProperties":false}},{"name":"list_members","description":"List tenant members with their effective role x scope assignments.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"authorization":{"type":"string"},"tenant_id":{"default":"","type":"string"}},"required":["authorization"],"additionalProperties":false}},{"name":"list_tenant_services","description":"Return the caller's tenant's active service subscriptions. Call this before\noffering to add a service, to check what is already subscribed.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"authorization":{"type":"string"},"tenant_id":{"default":"","type":"string"}},"required":["authorization"],"additionalProperties":false}},{"name":"record_consent","description":"Record acceptance of a legal document version and return the entry; call this\nonly after showing the user the document URL and version and receiving an\nexplicit affirmative answer.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"authorization":{"type":"string"},"document_code":{"type":"string"},"document_version":{"type":"string"},"tenant_id":{"default":"","type":"string"}},"required":["authorization","document_code","document_version"],"additionalProperties":false}},{"name":"revoke_assignment","description":"Revoke a role x scope assignment from a tenant member.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"authorization":{"type":"string"},"sub":{"type":"string"},"id":{"type":"string"},"tenant_id":{"default":"","type":"string"}},"required":["authorization","sub","id"],"additionalProperties":false}},{"name":"revoke_invitation","description":"Revoke a pending invitation so its token can no longer be accepted. Call this\nwhen a tenant admin wants to withdraw an invite sent by mistake or no longer\nneeded; accepted invitations cannot be revoked.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"authorization":{"type":"string"},"invitation_id":{"type":"string"},"tenant_id":{"default":"","type":"string"}},"required":["authorization","invitation_id"],"additionalProperties":false}},{"name":"start_account_registration","description":"Start registering a 4chems account with a business email address (`email`,\n`name`, optional `company`). Anonymous. Emails a 6-digit code to the address;\nno account exists yet. Ask the user for the code, then call\nverify_account_registration with the returned challenge_id and code. Free-mail\naddresses (gmail.com, ...) are refused: use the company address, or call\nstart_inquiry. The answer is the same whether or not the address already has\nan account.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"authorization":{"default":"","type":"string"},"body":{"default":"","description":"Request body for POST /v1/onboarding/registrations/account (UC-088).","properties":{"company":{"anyOf":[{"maxLength":120,"type":"string"},{"type":"null"}]},"email":{"type":"string"},"name":{"maxLength":120,"minLength":1,"type":"string"}},"required":["email","name"],"type":"object"}},"additionalProperties":false}},{"name":"start_device_login","description":"Sign in to an existing account by device login (UC-091, RFC 8628). Anonymous,\nempty body; the account must exist (start_account_registration, then set the\npassword through the emailed link). Show `verification_uri` (or\n`verification_uri_complete`) and `user_code` to the human, who signs in there,\nthen call `verify_device_login` with `challenge_id`, waiting `interval` seconds\nbetween calls. The response never contains the Keycloak device_code or the\nagent client secret.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"authorization":{"default":"","type":"string"}},"additionalProperties":false}},{"name":"start_inquiry","description":"Store an anonymous inquiry draft and email a 6-digit verification code.\nAsk the user for the code, then call verify_inquiry with the returned\nchallenge_id and code — the inquiry reaches 4chems only after that\nverification succeeds.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"authorization":{"default":"","type":"string"},"body":{"default":"","properties":{"company":{"default":"","maxLength":120,"type":"string"},"email":{"format":"email","type":"string"},"message":{"maxLength":4000,"minLength":10,"type":"string"},"name":{"maxLength":120,"minLength":1,"type":"string"},"topic":{"enum":["migration","hosting","iuclid","chesar","qsar_toolbox","other"],"type":"string"},"website":{"default":"","type":"string"}},"required":["name","email","topic","message"],"type":"object"}},"additionalProperties":false}},{"name":"start_registration","description":"DEPRECATED: use start_device_login. Deprecated — use start_device_login (same behaviour).","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"authorization":{"default":"","type":"string"}},"additionalProperties":false}},{"name":"verify_account_registration","description":"Verify the emailed 6-digit code (`challenge_id`, `code`) and create the\n4chems account. Never guess or retry codes, and never ask the user for a\npassword.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"authorization":{"default":"","type":"string"},"body":{"default":"","description":"Request body for POST /v1/onboarding/registrations/account/verify (UC-089).","properties":{"challenge_id":{"format":"uuid","type":"string"},"code":{"maxLength":32,"minLength":1,"type":"string"}},"required":["challenge_id","code"],"type":"object"}},"additionalProperties":false}},{"name":"verify_device_login","description":"Poll a device login to token issuance (UC-091, RFC 8628). Anonymous. While\nthe human has not signed in yet it answers `{\"status\": \"pending\",\n\"retry_after\": <seconds>}`: wait `retry_after` seconds and call again with the\nsame `challenge_id`. On approval it returns Keycloak's token set\n(`access_token`, `refresh_token`, `expires_in`, ...) exactly once; pass the\n`access_token` as `authorization` ('Bearer <token>') to every other tool.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"authorization":{"default":"","type":"string"},"body":{"default":"","description":"Request body for POST /v1/onboarding/registrations/device/verify (UC-075).","properties":{"challenge_id":{"format":"uuid","type":"string"}},"required":["challenge_id"],"type":"object"}},"additionalProperties":false}},{"name":"verify_inquiry","description":"Verify the 6-digit code and deliver the inquiry to the helpdesk inbox.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"authorization":{"default":"","type":"string"},"body":{"default":"","properties":{"challenge_id":{"format":"uuid","type":"string"},"code":{"maxLength":6,"minLength":6,"type":"string"}},"required":["challenge_id","code"],"type":"object"}},"additionalProperties":false}},{"name":"verify_registration","description":"DEPRECATED: use verify_device_login. Deprecated — use verify_device_login (same behaviour).","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"authorization":{"default":"","type":"string"},"body":{"default":"","description":"Request body for POST /v1/onboarding/registrations/device/verify (UC-075).","properties":{"challenge_id":{"format":"uuid","type":"string"}},"required":["challenge_id"],"type":"object"}},"additionalProperties":false}},{"name":"withdraw_access_request","description":"Withdraw the caller's own pending access request; no notification is\nsent. Any other caller gets 404 `access_request.not_found`, the same as\nfor an unknown id. 409 `access_request.not_pending` unless pending.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"authorization":{"type":"string"},"access_request_id":{"type":"string"}},"required":["authorization","access_request_id"],"additionalProperties":false}}],"scan":{"score":84,"grade":"B","scanned_at":"2026-10-13T14:43:23.768Z","report":{"scannerVersion":"0.1.10","scannedAt":"2026-10-13T14:43:23.747Z","components":{"code":{"score":-1,"max":25,"notes":["remote-only server, no package to scan"]},"reliability":{"score":20,"max":20,"notes":["remote reachable in 1643ms"]},"poisoning":{"score":15,"max":15,"notes":["32 tool descriptions checked"]},"auth":{"score":3,"max":15,"notes":["open endpoint exposes 3 write-action tools with no auth"]},"maintenance":{"score":15,"max":15,"notes":["last push 4 days ago"]},"identity":{"score":10,"max":10,"notes":["registry namespace matches repository owner","GitHub account older than a year","website matches verified namespace"]}},"findings":[{"id":"auth.open-write","severity":"high","component":"auth","title":"Write-action tools reachable without authentication"}],"inputs":{"probes":[{"url":"https://mcp.4chems.com/mcp","reachable":true,"authRequired":false,"latencyMs":1643,"serverInfo":{"name":"platform-api-customer","version":"0.12.1"}}],"packages":[],"repo":{"found":true,"owner":"4chems","repo":"mcp","archived":false,"pushedAt":"2026-10-09T19:28:09Z","stars":0,"forks":0,"openIssues":0,"ownerType":"Organization","ownerAvatarUrl":"https://avatars.githubusercontent.com/u/193915394?v=4","ownerCreatedAt":"2025-01-06T13:55:00Z"},"icon":{"url":"https://www.4chems.com/images/favicon_hu_2a07e4e9fa1b67bd.png","source":"site","width":144,"height":144},"presence":{"stars":0,"forks":0,"downloadsWeek":null,"license":null,"lastPushAt":"2026-10-09T19:28:09.000Z","score":23}}}},"grade_history":[],"reviews":[]}