Skip to content

4chems Platform — IUCLID, CHESAR & QSAR Toolbox hosting

by 4chems.com · remote · no sign-in to list tools · v0.12.1 · published by com.4chems

Remote MCP server for 4chems hosted IUCLID, CHESAR and QSAR Toolbox: onboarding, inquiries, admin.

Deletes · 4Final · 1Changes · 17

32 tools: 4 can delete or cancel things, 1 do something that can't be undone, 17 change things and 10 only read.

Scanned Oct 21, 2026

2 checks matched something in the tool definitions. No finding is not a safety guarantee. How the checks work.

claude mcp add --transport http platform-api https://mcp.4chems.com/mcp

Findings

Matches of fixed checks, with the text they matched.

2 warn
  • The server marks "enrich_domain" as not read-only (readOnlyHint: false), and its words say it reads.

    Matched text

    annotations: {"readOnlyHint":false,"destructiveHint":false,"idempotentHint":true,"openWorldHint":true}; The description's first verb is "fetch": a word for reading.

    What this check looks for
  • The description contains "every other tool", wording about other tools or servers.

    Matched text

    description: "...s `authorization` ('Bearer <token>') to every other tool."

    What this check looks for

Tools

Open a tool for its reasons and full description. Descriptions are the publisher's own words, shown as they are.

32 tools

Deletes or cancels 4Claude Code: deny
  • dismiss_access_requestDismiss a pending access request (level `admin` or `owner` of the request's tenant).No findings

    Why it is in this group

    • The name "dismiss_access_request" says "dismiss": a word for a change.
    • The server marks it destructive (destructiveHint: true).
    Description, as the server wrote it
    Dismiss a pending access request (level `admin` or `owner` of the request's tenant). The requester is mailed — naming the tenant, never the dismissing admin — and may ask again. 409 `access_request.not_pending` unless the request is pending.

    Annotations the server declares

    • destructiveHint: true
    • idempotentHint: false
    • openWorldHint: false
    • readOnlyHint: false
    • title: Dismiss Access Request Endpoint
  • revoke_assignmentRevoke a role x scope assignment from a tenant member.No findings

    Why it is in this group

    • The name "revoke_assignment" says "revoke": a word for removing or ending something.
    • The server marks it destructive (destructiveHint: true).
    Description, as the server wrote it
    Revoke a role x scope assignment from a tenant member.

    Annotations the server declares

    • destructiveHint: true
    • idempotentHint: true
    • openWorldHint: false
    • readOnlyHint: false
    • title: Revoke Assignment
  • revoke_invitationRevoke a pending invitation so its token can no longer be accepted.No findings

    Why it is in this group

    • The name "revoke_invitation" says "revoke": a word for removing or ending something.
    • The server marks it destructive (destructiveHint: true).
    Description, as the server wrote it
    Revoke a pending invitation so its token can no longer be accepted. Call this when a tenant admin wants to withdraw an invite sent by mistake or no longer needed; accepted invitations cannot be revoked.

    Annotations the server declares

    • destructiveHint: true
    • idempotentHint: true
    • openWorldHint: false
    • readOnlyHint: false
    • title: Revoke Invitation
  • withdraw_access_requestWithdraw the caller's own pending access request; no notification is sent.No findings

    Why it is in this group

    • The name "withdraw_access_request" says "withdraw": a word that usually means money moves, which cannot be taken back.
    • The server marks it destructive (destructiveHint: true).
    Description, as the server wrote it
    Withdraw the caller's own pending access request; no notification is sent. Any other caller gets 404 `access_request.not_found`, the same as for an unknown id. 409 `access_request.not_pending` unless pending.

    Annotations the server declares

    • destructiveHint: true
    • idempotentHint: false
    • openWorldHint: false
    • readOnlyHint: false
    • title: Withdraw Access Request Endpoint
Can't be undone 1Claude Code: ask
  • create_invitationInvite an email address to the caller's tenant at the specified access level and return the invitation, including the raw single-use accept token.No findings

    Why it is in this group

    • The name "create_invitation" says "create": a word for a change.
    • The description's first verb is "invite": a word for sending, and what is sent cannot be taken back.
    Description, as the server wrote it
    Invite an email address to the caller's tenant at the specified access level and return the invitation, including the raw single-use accept token. Call this when a tenant admin wants to add a new member; the invitee accepts via `accept_invitation`.

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: false
    • openWorldHint: false
    • readOnlyHint: false
    • title: Create Invitation
Changes things 17Claude Code: ask
  • accept_invitationAccept a pending invitation and grant the invitee's first role assignment.No findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    Description, as the server wrote it
    Accept a pending invitation and grant the invitee's first role assignment. Call this when an invitee has a valid invite link and wants to join the tenant; single-use, consuming the token marks it accepted.

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: false
    • openWorldHint: false
    • readOnlyHint: false
    • title: Accept Invitation
  • add_tenant_serviceRequest a new service subscription for the caller's tenant and return its status.No findings

    Why it is in this group

    • The name "add_tenant_service" says "add": a word for a change.
    Description, as the server wrote it
    Request a new service subscription for the caller's tenant and return its status. Call this when a tenant admin wants to add a service (ADR 0016 code fix: requires `admin`, was `customer` realm role only).

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: false
    • openWorldHint: false
    • readOnlyHint: false
    • title: Add Tenant Service
  • approve_access_requestApprove a pending access request: issue a `member` invitation to the requester and resolve the request (level `admin` or `owner` of the request's tenant).No findings

    Why it is in this group

    • The name "approve_access_request" says "approve": a word for a change.
    Description, as the server wrote it
    Approve a pending access request: issue a `member` invitation to the requester and resolve the request (level `admin` or `owner` of the request's tenant). The response carries the single-use invitation token to hand to the requester, who accepts via `accept_invitation`. 409 `access_request.not_pending` unless the request is pending.

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: false
    • openWorldHint: false
    • readOnlyHint: false
    • title: Approve Access Request Endpoint
  • complete_billingComplete the tenant's billing details: legal-entity name and type, VAT id, invoice address, invoice email and optional PO reference.No findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    Description, as the server wrote it
    Complete the tenant's billing details: legal-entity name and type, VAT id, invoice address, invoice email and optional PO reference. Call this when the owner or a billing contact has the details. EU VAT ids are validated against VIES by the worker; a failed operation with `billing.vat_check_unavailable` can be retried by submitting again. Returns `202` with an operation to poll.

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: true
    • readOnlyHint: false
    • title: Complete Billing
  • create_access_requestRequest access to the tenant that owns the caller's verified email domain.No findings

    Why it is in this group

    • The name "create_access_request" says "create": a word for a change.
    Description, as the server wrote it
    Request access to the tenant that owns the caller's verified email domain.

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
    • readOnlyHint: false
    • title: Create Access Request Endpoint
  • create_self_service_tenantCreate a 7-day trial tenant for the caller's business email domain (UC-052).No findings

    Why it is in this group

    • The name "create_self_service_tenant" says "create": a word for a change.
    Description, as the server wrote it
    Create a 7-day trial tenant for the caller's business email domain (UC-052). Needs a verified email on a business domain and `attestation: true`; answers `auth.email_not_verified`, `tenant.attestation_required`, `tenant.free_mail_domain` (free-mail address), `tenant.domain_exists` (a live trial tenant on the domain) or `trial.exists_for_domain` (the domain already had its one trial; call `start_inquiry`). The trial lasts exactly 7 days; `ttl` / `expires_at` in the body are ignored.

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: false
    • openWorldHint: false
    • readOnlyHint: false
    • title: Create Self Service Tenant
  • enrich_domainFetch the caller's domain imprint and suggest legal-entity details (UC-057).1 finding

    Why it is in this group

    • The description's first verb is "fetch": a word for reading.
    • The server marks it as not read-only (readOnlyHint: false).

    Findings

    • Warn

      The server marks "enrich_domain" as not read-only (readOnlyHint: false), and its words say it reads.

      Matched text

      annotations: {"readOnlyHint":false,"destructiveHint":false,"idempotentHint":true,"openWorldHint":true}; The description's first verb is "fetch": a word for reading.

      What this check looks for
    Description, as the server wrote it
    Fetch the caller's domain imprint and suggest legal-entity details (UC-057).

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: true
    • readOnlyHint: false
    • title: Enrich Domain Endpoint
  • grant_assignmentGrant a role x scope assignment to a tenant member.No findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    Description, as the server wrote it
    Grant a role x scope assignment to a tenant member.

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: false
    • openWorldHint: false
    • readOnlyHint: false
    • title: Grant Assignment
  • start_account_registrationStart registering a 4chems account with a business email address (`email`, `name`, optional `company`).No findings

    Why it is in this group

    • The name "start_account_registration" says "start": a word for a change.
    Description, as the server wrote it
    Start registering a 4chems account with a business email address (`email`, `name`, optional `company`). Anonymous. Emails a 6-digit code to the address; no account exists yet. Ask the user for the code, then call verify_account_registration with the returned challenge_id and code. Free-mail addresses (gmail.com, ...) are refused: use the company address, or call start_inquiry. The answer is the same whether or not the address already has an account.

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: false
    • openWorldHint: false
    • readOnlyHint: false
    • title: Start Account Registration
  • start_device_loginSign in to an existing account by device login (UC-091, RFC 8628).No findings

    Why it is in this group

    • The name "start_device_login" says "start": a word for a change.
    Description, as the server wrote it
    Sign in to an existing account by device login (UC-091, RFC 8628). Anonymous, empty body; the account must exist (start_account_registration, then set the password through the emailed link). Show `verification_uri` (or `verification_uri_complete`) and `user_code` to the human, who signs in there, then call `verify_device_login` with `challenge_id`, waiting `interval` seconds between calls. The response never contains the Keycloak device_code or the agent client secret.

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: false
    • openWorldHint: false
    • readOnlyHint: false
    • title: Start Device Login
  • start_inquiryStore an anonymous inquiry draft and email a 6-digit verification code.No findings

    Why it is in this group

    • The name "start_inquiry" says "start": a word for a change.
    Description, as the server wrote it
    Store an anonymous inquiry draft and email a 6-digit verification code. Ask the user for the code, then call verify_inquiry with the returned challenge_id and code — the inquiry reaches 4chems only after that verification succeeds.

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: false
    • openWorldHint: false
    • readOnlyHint: false
    • title: Start Inquiry
  • start_registrationDEPRECATED: use start_device_login.No findings

    Why it is in this group

    • The name "start_registration" says "start": a word for a change.
    Description, as the server wrote it
    DEPRECATED: use start_device_login. Deprecated — use start_device_login (same behaviour).

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: false
    • openWorldHint: false
    • readOnlyHint: false
    • title: Start Registration (deprecated — use start_device_login)
  • verify_account_registrationVerify the emailed 6-digit code (`challenge_id`, `code`) and create the 4chems account.No findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    Description, as the server wrote it
    Verify the emailed 6-digit code (`challenge_id`, `code`) and create the 4chems account. Never guess or retry codes, and never ask the user for a password.

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: false
    • openWorldHint: false
    • readOnlyHint: false
    • title: Verify Account Registration
  • verify_device_loginPoll a device login to token issuance (UC-091, RFC 8628).1 finding

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.

    Findings

    • Warn

      The description contains "every other tool", wording about other tools or servers.

      Matched text

      description: "...s `authorization` ('Bearer <token>') to every other tool."

      What this check looks for
    Description, as the server wrote it
    Poll a device login to token issuance (UC-091, RFC 8628). Anonymous. While the human has not signed in yet it answers `{"status": "pending", "retry_after": <seconds>}`: wait `retry_after` seconds and call again with the same `challenge_id`. On approval it returns Keycloak's token set (`access_token`, `refresh_token`, `expires_in`, ...) exactly once; pass the `access_token` as `authorization` ('Bearer <token>') to every other tool.

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: false
    • openWorldHint: false
    • readOnlyHint: false
    • title: Verify Device Login
  • verify_inquiryVerify the 6-digit code and deliver the inquiry to the helpdesk inbox.No findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    Description, as the server wrote it
    Verify the 6-digit code and deliver the inquiry to the helpdesk inbox.

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: false
    • openWorldHint: false
    • readOnlyHint: false
    • title: Verify Inquiry
  • verify_registrationDEPRECATED: use verify_device_login.No findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    Description, as the server wrote it
    DEPRECATED: use verify_device_login. Deprecated — use verify_device_login (same behaviour).

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: false
    • openWorldHint: false
    • readOnlyHint: false
    • title: Verify Registration (deprecated — use verify_device_login)
Only reads 10Claude Code: allow
  • get_billingReturn the tenant's stored billing details: VAT id, invoice address, invoice email and PO reference.No findings

    Why it is in this group

    • The name "get_billing" says "get": a word for reading.
    Description, as the server wrote it
    Return the tenant's stored billing details: VAT id, invoice address, invoice email and PO reference. Call this to check whether billing is complete; only the owner and billing contacts may read it (`403 rbac.insufficient_level`).

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
    • readOnlyHint: true
    • title: Get Billing
  • get_catalog_templatesReturn the enabled ApplicationTemplate catalog, ordered by name.No findings

    Why it is in this group

    • The name "get_catalog_templates" says "get": a word for reading.
    Description, as the server wrote it
    Return the enabled ApplicationTemplate catalog, ordered by name. Call this to discuss trial and template options with a prospect or customer before starting a trial. If this doesn't answer your question, call `start_inquiry` to ask 4chems directly or request a call.

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
    • readOnlyHint: true
    • title: Get Catalog Templates
  • get_my_accessReturn the caller's access level per related tenant.No findings

    Why it is in this group

    • The name "get_my_access" says "get": a word for reading.
    Description, as the server wrote it
    Return the caller's access level per related tenant. Call this to check what the current caller is authorized to do before attempting an action that requires a specific level, or to discover a pending invitation or access request.

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
    • readOnlyHint: true
    • title: Get My Access
  • get_my_operationReturn the status, result and error of an operation the caller started, such as the `Location` of a `202` from `complete_billing`.No findings

    Why it is in this group

    • The name "get_my_operation" says "get": a word for reading.
    Description, as the server wrote it
    Return the status, result and error of an operation the caller started, such as the `Location` of a `202` from `complete_billing`. Call this to poll it to completion.

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
    • readOnlyHint: true
    • title: Get My Operation
  • get_onboarding_routeReturn the next onboarding step.No findings

    Why it is in this group

    • The name "get_onboarding_route" says "get": a word for reading.
    Description, as the server wrote it
    Return the next onboarding step. If this doesn't answer your question, call `start_inquiry` to ask 4chems directly or request a call.

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
    • readOnlyHint: true
    • title: Get Onboarding Route
  • list_consentsReturn the caller's own recorded consents plus the tenant-scope consents of every tenant where the caller is at least a viewer.No findings

    Why it is in this group

    • The name "list_consents" says "list": a word for reading.
    Description, as the server wrote it
    Return the caller's own recorded consents plus the tenant-scope consents of every tenant where the caller is at least a viewer. Call this to check which legal documents have already been accepted before asking again. Pass `tenant_id` to list one tenant's consents only (a caller of several tenants must).

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
    • readOnlyHint: true
    • title: List Consents
  • list_invitationsList all invitations for the caller's tenant, most recent first.No findings

    Why it is in this group

    • The name "list_invitations" says "list": a word for reading.
    Description, as the server wrote it
    List all invitations for the caller's tenant, most recent first. Call this to show a tenant admin which invitations are pending, accepted, or revoked; the raw token is never included.

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
    • readOnlyHint: true
    • title: List Invitations
  • list_membersList tenant members with their effective role x scope assignments.No findings

    Why it is in this group

    • The name "list_members" says "list": a word for reading.
    Description, as the server wrote it
    List tenant members with their effective role x scope assignments.

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
    • readOnlyHint: true
    • title: List Members
  • list_tenant_servicesReturn the caller's tenant's active service subscriptions.No findings

    Why it is in this group

    • The name "list_tenant_services" says "list": a word for reading.
    Description, as the server wrote it
    Return the caller's tenant's active service subscriptions. Call this before offering to add a service, to check what is already subscribed.

    Annotations the server declares

    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
    • readOnlyHint: true
    • title: List Tenant Services

This is not a safety rating, and no finding is not a safety guarantee. The groups and findings come from fixed checks of the tool definitions the server returned on the date shown, not from its code or what it does when called. How the checks work.

Install

Pinned to version 0.12.1. Values in angle brackets are yours to fill in.

claude mcp add --transport http platform-api https://mcp.4chems.com/mcp

Run in a terminal.

Claude Code permissions

Allow the reads, ask before a change, deny the deletes. Paste into .claude/settings.json.

.claude/settings.json
{
  "permissions": {
    "allow": [
      "mcp__platform-api__get_catalog_templates",
      "mcp__platform-api__list_consents",
      "mcp__platform-api__get_my_access",
      "mcp__platform-api__get_onboarding_route",
      "mcp__platform-api__get_my_operation",
      "mcp__platform-api__get_legal_entity_types",
      "mcp__platform-api__get_billing",
      "mcp__platform-api__list_invitations",
      "mcp__platform-api__list_members",
      "mcp__platform-api__list_tenant_services"
    ],
    "ask": [
      "mcp__platform-api__record_consent",
      "mcp__platform-api__start_inquiry",
      "mcp__platform-api__verify_inquiry",
      "mcp__platform-api__accept_invitation",
      "mcp__platform-api__create_access_request",
      "mcp__platform-api__approve_access_request",
      "mcp__platform-api__enrich_domain",
      "mcp__platform-api__start_device_login",
      "mcp__platform-api__verify_device_login",
      "mcp__platform-api__start_account_registration",
      "mcp__platform-api__verify_account_registration",
      "mcp__platform-api__start_registration",
      "mcp__platform-api__verify_registration",
      "mcp__platform-api__create_self_service_tenant",
      "mcp__platform-api__complete_billing",
      "mcp__platform-api__create_invitation",
      "mcp__platform-api__grant_assignment",
      "mcp__platform-api__add_tenant_service"
    ],
    "deny": [
      "mcp__platform-api__dismiss_access_request",
      "mcp__platform-api__withdraw_access_request",
      "mcp__platform-api__revoke_invitation",
      "mcp__platform-api__revoke_assignment"
    ]
  }
}

Tools that only read are allowed, tools that change things ask first, tools that delete or cancel are denied. It assumes the server is installed as platform-api. Review it before you use it.