4chems Platform — IUCLID, CHESAR & QSAR Toolbox hosting
Remote MCP server for 4chems hosted IUCLID, CHESAR and QSAR Toolbox: onboarding, inquiries, admin.
我该使用它吗
质量与安全性
发现(2)
- LOW在 grant_assignment 中
- LOW在 revoke_assignment 中
基于对工具定义和协议合规性的自动分析。
上下文开销
这是每次将服务器的工具加载到模型上下文窗口时所消耗的大致 token 数。数值越高,可用于其他任务的注意力就越少。
安装
一键安装
将以下内容添加到你的 `claude_desktop_config.json` 文件中:
{
"mcpServers": {
"platform-api": {
"url": "https://mcp.4chems.com/mcp"
}
}
}远程端点
https://mcp.4chems.com/mcpstreamable-http它能做什么
工具清单
工具(32)
🟢get_catalog_templates(authorization)
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.
输入模式
{
"type": "object",
"properties": {
"authorization": {
"default": "",
"type": "string"
}
},
"additionalProperties": false
}输出模式
{
"type": "object",
"properties": {
"result": {
"items": {
"description": "Customer-facing (/v1) catalog item (UC-072).\n\nDeliberately narrower than ``TemplateOut``: ``version``, ``image_url`` and\n``repository_url`` are dropped — no data source populates them and they were\npermanently null in the public response. The `/infra` catalog admin schema\n(``TemplateOut``) and the database columns are unchanged.",
"properties": {
"code": {
"title": "Code",
"type": "string"
},
"created_at": {
"format": "date-time",
"title": "Created At",
"type": "string"
},
"description": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Description"
},
"enabled": {
"title": "Enabled",
"type": "boolean"
},
"id": {
"format": "uuid",
"title": "Id",
"type": "string"
},
"includes": {
"title": "Includes"
},
"kind": {
"title": "Kind",
"type": "string"
},
"legacy": {
"title": "Legacy",
"type": "boolean"
},
"legacy_note": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Legacy Note"
},
"name": {
"title": "Name",
"type": "string"
},
"options": {
"title": "Options"
},
"updated_at": {
"format": "date-time",
"title": "Updated At",
"type": "string"
}
},
"required": [
"id",
"code",
"name",
"description",
"kind",
"legacy",
"legacy_note",
"includes",
"options",
"enabled",
"created_at",
"updated_at"
],
"title": "TemplateV1Out",
"type": "object"
},
"title": "Response Get Catalog Templates",
"type": "array"
}
},
"required": [
"result"
],
"x-fastmcp-wrap-result": true
}🟢list_consents(authorization, tenant_id)
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).
输入模式
{
"type": "object",
"properties": {
"authorization": {
"type": "string"
},
"tenant_id": {
"default": "",
"type": "string"
}
},
"required": [
"authorization"
],
"additionalProperties": false
}输出模式
{
"type": "object",
"properties": {
"result": {
"items": {
"properties": {
"document_code": {
"title": "Document Code",
"type": "string"
},
"document_version": {
"title": "Document Version",
"type": "string"
},
"granted_at": {
"format": "date-time",
"title": "Granted At",
"type": "string"
},
"id": {
"format": "uuid",
"title": "Id",
"type": "string"
},
"source": {
"title": "Source",
"type": "string"
},
"subject_sub": {
"title": "Subject Sub",
"type": "string"
},
"tenant_id": {
"anyOf": [
{
"format": "uuid",
"type": "string"
},
{
"type": "null"
}
],
"title": "Tenant Id"
}
},
"required": [
"id",
"subject_sub",
"document_code",
"document_version",
"granted_at",
"source"
],
"title": "ConsentOut",
"type": "object"
},
"title": "Response List Consents",
"type": "array"
}
},
"required": [
"result"
],
"x-fastmcp-wrap-result": true
}⚪record_consent(authorization, document_code, document_version, tenant_id)
Record acceptance of a legal document version and return the entry; call this only after showing the user the document URL and version and receiving an explicit affirmative answer.
输入模式
{
"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
}输出模式
{
"type": "object",
"properties": {
"document_code": {
"title": "Document Code",
"type": "string"
},
"document_version": {
"title": "Document Version",
"type": "string"
},
"granted_at": {
"format": "date-time",
"title": "Granted At",
"type": "string"
},
"id": {
"format": "uuid",
"title": "Id",
"type": "string"
},
"source": {
"title": "Source",
"type": "string"
},
"subject_sub": {
"title": "Subject Sub",
"type": "string"
},
"tenant_id": {
"anyOf": [
{
"format": "uuid",
"type": "string"
},
{
"type": "null"
}
],
"title": "Tenant Id"
}
},
"required": [
"id",
"subject_sub",
"document_code",
"document_version",
"granted_at",
"source"
],
"title": "ConsentOut"
}⚪start_inquiry(authorization, body)
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.
输入模式
{
"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
}输出模式
{
"type": "object",
"properties": {
"challenge_id": {
"format": "uuid",
"title": "Challenge Id",
"type": "string"
},
"expires_in_seconds": {
"title": "Expires In Seconds",
"type": "integer"
},
"next_step": {
"title": "Next Step",
"type": "string"
}
},
"required": [
"challenge_id",
"expires_in_seconds",
"next_step"
],
"title": "InquiryChallengeOut"
}⚪verify_inquiry(authorization, body)
Verify the 6-digit code and deliver the inquiry to the helpdesk inbox.
输入模式
{
"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
}输出模式
{
"type": "object",
"properties": {
"inquiry_id": {
"format": "uuid",
"title": "Inquiry Id",
"type": "string"
},
"reference": {
"title": "Reference",
"type": "string"
},
"status": {
"title": "Status",
"type": "string"
}
},
"required": [
"inquiry_id",
"reference",
"status"
],
"title": "InquiryReceivedOut"
}⚪accept_invitation(authorization, token)
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.
输入模式
{
"type": "object",
"properties": {
"authorization": {
"type": "string"
},
"token": {
"type": "string"
}
},
"required": [
"authorization",
"token"
],
"additionalProperties": false
}输出模式
{
"type": "object",
"properties": {
"accepted_at": {
"anyOf": [
{
"format": "date-time",
"type": "string"
},
{
"type": "null"
}
],
"title": "Accepted At"
},
"billing_contact": {
"default": false,
"title": "Billing Contact",
"type": "boolean"
},
"created_at": {
"format": "date-time",
"title": "Created At",
"type": "string"
},
"email": {
"title": "Email",
"type": "string"
},
"expires_at": {
"format": "date-time",
"title": "Expires At",
"type": "string"
},
"id": {
"format": "uuid",
"title": "Id",
"type": "string"
},
"invited_by": {
"title": "Invited By",
"type": "string"
},
"level": {
"title": "Level",
"type": "string"
},
"status": {
"title": "Status",
"type": "string"
},
"tenant_id": {
"title": "Tenant Id",
"type": "string"
}
},
"required": [
"id",
"tenant_id",
"email",
"level",
"status",
"expires_at",
"invited_by",
"created_at"
],
"title": "InvitationOut"
}🟢get_my_access(authorization)
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.
输入模式
{
"type": "object",
"properties": {
"authorization": {
"type": "string"
}
},
"required": [
"authorization"
],
"additionalProperties": false
}输出模式
{
"type": "object",
"properties": {
"result": {
"items": {
"properties": {
"level": {
"enum": [
"none",
"requester",
"viewer",
"member",
"admin",
"owner"
],
"title": "Level",
"type": "string"
},
"subscription": {
"properties": {
"expires_at": {
"anyOf": [
{
"format": "date-time",
"type": "string"
},
{
"type": "null"
}
],
"title": "Expires At"
},
"grace_ends_at": {
"anyOf": [
{
"format": "date-time",
"type": "string"
},
{
"type": "null"
}
],
"title": "Grace Ends At"
},
"state": {
"description": "Commercial state (UC-096, UC-086 D7); `TrialStatus` is provisioning only.",
"enum": [
"trialing",
"expired",
"erased",
"active"
],
"title": "SubscriptionState",
"type": "string"
}
},
"required": [
"state",
"expires_at",
"grace_ends_at"
],
"title": "SubscriptionOut",
"type": "object"
},
"tenant": {
"title": "Tenant",
"type": "string"
},
"via": {
"title": "Via",
"type": "string"
}
},
"required": [
"tenant",
"level",
"via",
"subscription"
],
"title": "TenantAccessOut",
"type": "object"
},
"title": "Response Get My Access",
"type": "array"
}
},
"required": [
"result"
],
"x-fastmcp-wrap-result": true
}🟡create_access_request(authorization)
Request access to the tenant that owns the caller's verified email domain.
输入模式
{
"type": "object",
"properties": {
"authorization": {
"type": "string"
}
},
"required": [
"authorization"
],
"additionalProperties": false
}输出模式
{
"type": "object",
"properties": {
"created_at": {
"format": "date-time",
"title": "Created At",
"type": "string"
},
"error": {
"anyOf": [
{
"properties": {
"code": {
"title": "Code",
"type": "string"
},
"message": {
"title": "Message",
"type": "string"
}
},
"required": [
"code",
"message"
],
"title": "ErrorDetail",
"type": "object"
},
{
"type": "null"
}
]
},
"finished_at": {
"anyOf": [
{
"format": "date-time",
"type": "string"
},
{
"type": "null"
}
],
"title": "Finished At"
},
"operation_id": {
"format": "uuid",
"title": "Operation Id",
"type": "string"
},
"result": {
"anyOf": [
{},
{
"type": "null"
}
],
"title": "Result"
},
"status": {
"title": "Status",
"type": "string"
},
"target_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Target Id"
},
"target_type": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Target Type"
},
"type": {
"title": "Type",
"type": "string"
}
},
"required": [
"operation_id",
"status",
"type",
"created_at"
],
"title": "OperationOut"
}⚪approve_access_request(authorization, access_request_id)
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.
输入模式
{
"type": "object",
"properties": {
"authorization": {
"type": "string"
},
"access_request_id": {
"type": "string"
}
},
"required": [
"authorization",
"access_request_id"
],
"additionalProperties": false
}输出模式
{
"type": "object",
"properties": {
"created_at": {
"format": "date-time",
"title": "Created At",
"type": "string"
},
"id": {
"format": "uuid",
"title": "Id",
"type": "string"
},
"invitation_id": {
"format": "uuid",
"title": "Invitation Id",
"type": "string"
},
"status": {
"title": "Status",
"type": "string"
},
"tenant_id": {
"format": "uuid",
"title": "Tenant Id",
"type": "string"
},
"token": {
"title": "Token",
"type": "string"
},
"updated_at": {
"format": "date-time",
"title": "Updated At",
"type": "string"
}
},
"required": [
"id",
"tenant_id",
"status",
"created_at",
"updated_at",
"invitation_id",
"token"
],
"description": "`approve_access_request` response: the issued invitation, with its\nsingle-use accept token for the admin to hand to the requester.",
"title": "AccessRequestApprovedOut"
}🔴dismiss_access_request(authorization, access_request_id)
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.
输入模式
{
"type": "object",
"properties": {
"authorization": {
"type": "string"
},
"access_request_id": {
"type": "string"
}
},
"required": [
"authorization",
"access_request_id"
],
"additionalProperties": false
}输出模式
{
"type": "object",
"properties": {
"created_at": {
"format": "date-time",
"title": "Created At",
"type": "string"
},
"id": {
"format": "uuid",
"title": "Id",
"type": "string"
},
"status": {
"title": "Status",
"type": "string"
},
"tenant_id": {
"format": "uuid",
"title": "Tenant Id",
"type": "string"
},
"updated_at": {
"format": "date-time",
"title": "Updated At",
"type": "string"
}
},
"required": [
"id",
"tenant_id",
"status",
"created_at",
"updated_at"
],
"description": "An access request after approve / dismiss / withdraw (UC-094).",
"title": "AccessRequestOut"
}🔴withdraw_access_request(authorization, access_request_id)
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.
输入模式
{
"type": "object",
"properties": {
"authorization": {
"type": "string"
},
"access_request_id": {
"type": "string"
}
},
"required": [
"authorization",
"access_request_id"
],
"additionalProperties": false
}输出模式
{
"type": "object",
"properties": {
"created_at": {
"format": "date-time",
"title": "Created At",
"type": "string"
},
"id": {
"format": "uuid",
"title": "Id",
"type": "string"
},
"status": {
"title": "Status",
"type": "string"
},
"tenant_id": {
"format": "uuid",
"title": "Tenant Id",
"type": "string"
},
"updated_at": {
"format": "date-time",
"title": "Updated At",
"type": "string"
}
},
"required": [
"id",
"tenant_id",
"status",
"created_at",
"updated_at"
],
"description": "An access request after approve / dismiss / withdraw (UC-094).",
"title": "AccessRequestOut"
}🟢enrich_domain(authorization)
Fetch the caller's domain imprint and suggest legal-entity details (UC-057).
输入模式
{
"type": "object",
"properties": {
"authorization": {
"type": "string"
}
},
"required": [
"authorization"
],
"additionalProperties": false
}输出模式
{
"type": "object",
"properties": {
"confidence": {
"default": 0,
"title": "Confidence",
"type": "number"
},
"country": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Country"
},
"entity_type": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Entity Type"
},
"legal_entity_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Legal Entity Name"
},
"source_url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Source Url"
}
},
"description": "Response for POST /v1/onboarding/enrichment (UC-057).\n\nSuggest-only: all fields are nullable; confidence=0 means no suggestion.\nThe UI must fall back to manual entry when confidence is low.",
"title": "EnrichmentOut"
}🟡start_device_login(authorization)
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.
输入模式
{
"type": "object",
"properties": {
"authorization": {
"default": "",
"type": "string"
}
},
"additionalProperties": false
}输出模式
{
"type": "object",
"properties": {
"challenge_id": {
"format": "uuid",
"title": "Challenge Id",
"type": "string"
},
"expires_in": {
"title": "Expires In",
"type": "integer"
},
"interval": {
"title": "Interval",
"type": "integer"
},
"user_code": {
"title": "User Code",
"type": "string"
},
"verification_uri": {
"title": "Verification Uri",
"type": "string"
},
"verification_uri_complete": {
"title": "Verification Uri Complete",
"type": "string"
}
},
"required": [
"challenge_id",
"verification_uri",
"verification_uri_complete",
"user_code",
"expires_in",
"interval"
],
"description": "Response for POST /v1/onboarding/registrations/device (UC-075).\n\nNever carries the Keycloak device_code or the agent client secret.",
"title": "DeviceChallengeOut"
}🟡verify_device_login(authorization, body)
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.
输入模式
{
"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
}输出模式
{
"type": "object"
}⚪start_account_registration(authorization, body)
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.
输入模式
{
"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
}输出模式
{
"type": "object",
"properties": {
"challenge_id": {
"format": "uuid",
"title": "Challenge Id",
"type": "string"
},
"expires_in_seconds": {
"title": "Expires In Seconds",
"type": "integer"
},
"next_step": {
"title": "Next Step",
"type": "string"
}
},
"required": [
"challenge_id",
"expires_in_seconds",
"next_step"
],
"title": "AccountChallengeOut"
}🟡verify_account_registration(authorization, body)
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.
输入模式
{
"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
}输出模式
{
"type": "object",
"properties": {
"account": {
"const": "created",
"title": "Account",
"type": "string"
},
"next_step": {
"title": "Next Step",
"type": "string"
}
},
"required": [
"account",
"next_step"
],
"title": "AccountCreatedOut"
}⚪start_registration(authorization)
DEPRECATED: use start_device_login. Deprecated — use start_device_login (same behaviour).
输入模式
{
"type": "object",
"properties": {
"authorization": {
"default": "",
"type": "string"
}
},
"additionalProperties": false
}输出模式
{
"type": "object",
"properties": {
"challenge_id": {
"format": "uuid",
"title": "Challenge Id",
"type": "string"
},
"expires_in": {
"title": "Expires In",
"type": "integer"
},
"interval": {
"title": "Interval",
"type": "integer"
},
"user_code": {
"title": "User Code",
"type": "string"
},
"verification_uri": {
"title": "Verification Uri",
"type": "string"
},
"verification_uri_complete": {
"title": "Verification Uri Complete",
"type": "string"
}
},
"required": [
"challenge_id",
"verification_uri",
"verification_uri_complete",
"user_code",
"expires_in",
"interval"
],
"description": "Response for POST /v1/onboarding/registrations/device (UC-075).\n\nNever carries the Keycloak device_code or the agent client secret.",
"title": "DeviceChallengeOut"
}⚪verify_registration(authorization, body)
DEPRECATED: use verify_device_login. Deprecated — use verify_device_login (same behaviour).
输入模式
{
"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
}输出模式
{
"type": "object"
}🟢get_onboarding_route(authorization)
Return the next onboarding step. If this doesn't answer your question, call `start_inquiry` to ask 4chems directly or request a call.
输入模式
{
"type": "object",
"properties": {
"authorization": {
"default": "",
"type": "string"
}
},
"additionalProperties": false
}输出模式
{
"type": "object",
"properties": {
"action": {
"title": "Action",
"type": "string",
"x-extensible-enum": [
"wizard",
"wizard_no_tenant_domain",
"request_access",
"trial_used",
"member",
"register"
]
},
"next_step": {
"anyOf": [
{
"type": "string"
},
{
"description": "What a `member` must do next: record consents to the listed documents (UC-093).",
"properties": {
"documents": {
"items": {
"additionalProperties": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"type": "object"
},
"title": "Documents",
"type": "array"
},
"operation": {
"title": "Operation",
"type": "string"
}
},
"required": [
"operation",
"documents"
],
"title": "NextStepOut",
"type": "object"
},
{
"type": "null"
}
],
"title": "Next Step"
},
"registration_methods": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"title": "Registration Methods"
},
"registration_url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Registration Url"
},
"subscription": {
"anyOf": [
{
"properties": {
"expires_at": {
"anyOf": [
{
"format": "date-time",
"type": "string"
},
{
"type": "null"
}
],
"title": "Expires At"
},
"grace_ends_at": {
"anyOf": [
{
"format": "date-time",
"type": "string"
},
{
"type": "null"
}
],
"title": "Grace Ends At"
},
"state": {
"description": "Commercial state (UC-096, UC-086 D7); `TrialStatus` is provisioning only.",
"enum": [
"trialing",
"expired",
"erased",
"active"
],
"title": "SubscriptionState",
"type": "string"
}
},
"required": [
"state",
"expires_at",
"grace_ends_at"
],
"title": "SubscriptionOut",
"type": "object"
},
{
"type": "null"
}
]
},
"tenant_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Tenant Name"
}
},
"required": [
"action"
],
"title": "RoutingOut"
}🟡create_self_service_tenant(authorization, body)
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.
输入模式
{
"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
}输出模式
{
"type": "object",
"properties": {
"created_at": {
"format": "date-time",
"title": "Created At",
"type": "string"
},
"error": {
"anyOf": [
{
"properties": {
"code": {
"title": "Code",
"type": "string"
},
"message": {
"title": "Message",
"type": "string"
}
},
"required": [
"code",
"message"
],
"title": "ErrorDetail",
"type": "object"
},
{
"type": "null"
}
]
},
"finished_at": {
"anyOf": [
{
"format": "date-time",
"type": "string"
},
{
"type": "null"
}
],
"title": "Finished At"
},
"operation_id": {
"format": "uuid",
"title": "Operation Id",
"type": "string"
},
"result": {
"anyOf": [
{},
{
"type": "null"
}
],
"title": "Result"
},
"status": {
"title": "Status",
"type": "string"
},
"target_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Target Id"
},
"target_type": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Target Type"
},
"type": {
"title": "Type",
"type": "string"
}
},
"required": [
"operation_id",
"status",
"type",
"created_at"
],
"title": "OperationOut"
}🟢get_my_operation(authorization, operation_id)
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.
输入模式
{
"type": "object",
"properties": {
"authorization": {
"type": "string"
},
"operation_id": {
"type": "string"
}
},
"required": [
"authorization",
"operation_id"
],
"additionalProperties": false
}输出模式
{
"type": "object",
"properties": {
"created_at": {
"format": "date-time",
"title": "Created At",
"type": "string"
},
"error": {
"anyOf": [
{
"properties": {
"code": {
"title": "Code",
"type": "string"
},
"message": {
"title": "Message",
"type": "string"
}
},
"required": [
"code",
"message"
],
"title": "ErrorDetail",
"type": "object"
},
{
"type": "null"
}
]
},
"finished_at": {
"anyOf": [
{
"format": "date-time",
"type": "string"
},
{
"type": "null"
}
],
"title": "Finished At"
},
"operation_id": {
"format": "uuid",
"title": "Operation Id",
"type": "string"
},
"result": {
"anyOf": [
{},
{
"type": "null"
}
],
"title": "Result"
},
"status": {
"title": "Status",
"type": "string"
},
"target_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Target Id"
},
"target_type": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Target Type"
},
"type": {
"title": "Type",
"type": "string"
}
},
"required": [
"operation_id",
"status",
"type",
"created_at"
],
"title": "OperationOut"
}🟢get_legal_entity_types(country, authorization)
Return the legal-entity types available for *country*, ordered alphabetically. If this doesn't answer your question, call `start_inquiry` to ask 4chems directly or request a call.
输入模式
{
"type": "object",
"properties": {
"country": {
"description": "ISO 3166-1 alpha-2 country code",
"type": "string"
},
"authorization": {
"default": "",
"type": "string"
}
},
"required": [
"country"
],
"additionalProperties": false
}输出模式
{
"type": "object",
"properties": {
"result": {
"items": {
"properties": {
"abbreviation": {
"title": "Abbreviation",
"type": "string"
},
"code": {
"title": "Code",
"type": "string"
},
"name": {
"title": "Name",
"type": "string"
}
},
"required": [
"code",
"abbreviation",
"name"
],
"title": "LegalEntityTypeOut",
"type": "object"
},
"title": "Response Get Legal Entity Types",
"type": "array"
}
},
"required": [
"result"
],
"x-fastmcp-wrap-result": true
}🟢get_billing(authorization, tenant_id)
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`).
输入模式
{
"type": "object",
"properties": {
"authorization": {
"type": "string"
},
"tenant_id": {
"default": "",
"type": "string"
}
},
"required": [
"authorization"
],
"additionalProperties": false
}输出模式
{
"type": "object",
"properties": {
"address_line1": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Address Line1"
},
"address_line2": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Address Line2"
},
"billing_completed": {
"title": "Billing Completed",
"type": "boolean"
},
"billing_completed_at": {
"anyOf": [
{
"format": "date-time",
"type": "string"
},
{
"type": "null"
}
],
"title": "Billing Completed At"
},
"city": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "City"
},
"country": {
"title": "Country",
"type": "string"
},
"invoice_email": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Invoice Email"
},
"legal_entity_type": {
"title": "Legal Entity Type",
"type": "string"
},
"name": {
"title": "Name",
"type": "string"
},
"other_label": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Other Label"
},
"po_reference": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Po Reference"
},
"postal_code": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Postal Code"
},
"vat_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Vat Id"
},
"vat_validated_at": {
"anyOf": [
{
"format": "date-time",
"type": "string"
},
{
"type": "null"
}
],
"title": "Vat Validated At"
}
},
"required": [
"name",
"country",
"legal_entity_type",
"billing_completed"
],
"description": "The stored billing data, `get_billing` (owner and billing contacts only).",
"title": "BillingOut"
}🟢complete_billing(authorization, tenant_id, body)
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.
输入模式
{
"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
}输出模式
{
"type": "object",
"properties": {
"created_at": {
"format": "date-time",
"title": "Created At",
"type": "string"
},
"error": {
"anyOf": [
{
"properties": {
"code": {
"title": "Code",
"type": "string"
},
"message": {
"title": "Message",
"type": "string"
}
},
"required": [
"code",
"message"
],
"title": "ErrorDetail",
"type": "object"
},
{
"type": "null"
}
]
},
"finished_at": {
"anyOf": [
{
"format": "date-time",
"type": "string"
},
{
"type": "null"
}
],
"title": "Finished At"
},
"operation_id": {
"format": "uuid",
"title": "Operation Id",
"type": "string"
},
"result": {
"anyOf": [
{},
{
"type": "null"
}
],
"title": "Result"
},
"status": {
"title": "Status",
"type": "string"
},
"target_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Target Id"
},
"target_type": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Target Type"
},
"type": {
"title": "Type",
"type": "string"
}
},
"required": [
"operation_id",
"status",
"type",
"created_at"
],
"title": "OperationOut"
}🟢list_invitations(authorization, tenant_id)
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.
输入模式
{
"type": "object",
"properties": {
"authorization": {
"type": "string"
},
"tenant_id": {
"default": "",
"type": "string"
}
},
"required": [
"authorization"
],
"additionalProperties": false
}输出模式
{
"type": "object",
"properties": {
"result": {
"items": {
"properties": {
"accepted_at": {
"anyOf": [
{
"format": "date-time",
"type": "string"
},
{
"type": "null"
}
],
"title": "Accepted At"
},
"billing_contact": {
"default": false,
"title": "Billing Contact",
"type": "boolean"
},
"created_at": {
"format": "date-time",
"title": "Created At",
"type": "string"
},
"email": {
"title": "Email",
"type": "string"
},
"expires_at": {
"format": "date-time",
"title": "Expires At",
"type": "string"
},
"id": {
"format": "uuid",
"title": "Id",
"type": "string"
},
"invited_by": {
"title": "Invited By",
"type": "string"
},
"level": {
"title": "Level",
"type": "string"
},
"status": {
"title": "Status",
"type": "string"
},
"tenant_id": {
"title": "Tenant Id",
"type": "string"
}
},
"required": [
"id",
"tenant_id",
"email",
"level",
"status",
"expires_at",
"invited_by",
"created_at"
],
"title": "InvitationOut",
"type": "object"
},
"title": "Response List Invitations",
"type": "array"
}
},
"required": [
"result"
],
"x-fastmcp-wrap-result": true
}🟡create_invitation(authorization, tenant_id, body)
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`.
输入模式
{
"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
}输出模式
{
"type": "object",
"properties": {
"accepted_at": {
"anyOf": [
{
"format": "date-time",
"type": "string"
},
{
"type": "null"
}
],
"title": "Accepted At"
},
"billing_contact": {
"default": false,
"title": "Billing Contact",
"type": "boolean"
},
"created_at": {
"format": "date-time",
"title": "Created At",
"type": "string"
},
"email": {
"title": "Email",
"type": "string"
},
"expires_at": {
"format": "date-time",
"title": "Expires At",
"type": "string"
},
"id": {
"format": "uuid",
"title": "Id",
"type": "string"
},
"invited_by": {
"title": "Invited By",
"type": "string"
},
"level": {
"title": "Level",
"type": "string"
},
"status": {
"title": "Status",
"type": "string"
},
"tenant_id": {
"title": "Tenant Id",
"type": "string"
},
"token": {
"title": "Token",
"type": "string"
}
},
"required": [
"id",
"tenant_id",
"email",
"level",
"status",
"expires_at",
"invited_by",
"created_at",
"token"
],
"description": "Returned only on POST — includes the raw token for sharing the invite link.",
"title": "InvitationCreatedOut"
}🔴revoke_invitation(authorization, invitation_id, tenant_id)
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.
输入模式
{
"type": "object",
"properties": {
"authorization": {
"type": "string"
},
"invitation_id": {
"type": "string"
},
"tenant_id": {
"default": "",
"type": "string"
}
},
"required": [
"authorization",
"invitation_id"
],
"additionalProperties": false
}🟢list_members(authorization, tenant_id)
List tenant members with their effective role x scope assignments.
输入模式
{
"type": "object",
"properties": {
"authorization": {
"type": "string"
},
"tenant_id": {
"default": "",
"type": "string"
}
},
"required": [
"authorization"
],
"additionalProperties": false
}输出模式
{
"type": "object",
"properties": {
"members": {
"items": {
"properties": {
"assignments": {
"items": {
"properties": {
"expires_at": {
"anyOf": [
{
"format": "date-time",
"type": "string"
},
{
"type": "null"
}
],
"title": "Expires At"
},
"granted_at": {
"format": "date-time",
"title": "Granted At",
"type": "string"
},
"granted_by": {
"title": "Granted By",
"type": "string"
},
"id": {
"format": "uuid",
"title": "Id",
"type": "string"
},
"role": {
"title": "Role",
"type": "string"
},
"scope_id": {
"title": "Scope Id",
"type": "string"
},
"scope_type": {
"title": "Scope Type",
"type": "string"
},
"subject": {
"title": "Subject",
"type": "string"
},
"subject_type": {
"title": "Subject Type",
"type": "string"
}
},
"required": [
"id",
"subject_type",
"subject",
"role",
"scope_type",
"scope_id",
"expires_at",
"granted_by",
"granted_at"
],
"title": "AssignmentOut",
"type": "object"
},
"title": "Assignments",
"type": "array"
},
"subject": {
"title": "Subject",
"type": "string"
}
},
"required": [
"subject",
"assignments"
],
"title": "MemberOut",
"type": "object"
},
"title": "Members",
"type": "array"
},
"tenant_id": {
"title": "Tenant Id",
"type": "string"
}
},
"required": [
"tenant_id",
"members"
],
"title": "MembersListOut"
}⚪grant_assignment(authorization, sub, tenant_id, body)
Grant a role x scope assignment to a tenant member.
输入模式
{
"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
}输出模式
{
"type": "object",
"properties": {
"expires_at": {
"anyOf": [
{
"format": "date-time",
"type": "string"
},
{
"type": "null"
}
],
"title": "Expires At"
},
"granted_at": {
"format": "date-time",
"title": "Granted At",
"type": "string"
},
"granted_by": {
"title": "Granted By",
"type": "string"
},
"id": {
"format": "uuid",
"title": "Id",
"type": "string"
},
"role": {
"title": "Role",
"type": "string"
},
"scope_id": {
"title": "Scope Id",
"type": "string"
},
"scope_type": {
"title": "Scope Type",
"type": "string"
},
"subject": {
"title": "Subject",
"type": "string"
},
"subject_type": {
"title": "Subject Type",
"type": "string"
}
},
"required": [
"id",
"subject_type",
"subject",
"role",
"scope_type",
"scope_id",
"expires_at",
"granted_by",
"granted_at"
],
"title": "AssignmentOut"
}🔴revoke_assignment(authorization, sub, id, tenant_id)
Revoke a role x scope assignment from a tenant member.
输入模式
{
"type": "object",
"properties": {
"authorization": {
"type": "string"
},
"sub": {
"type": "string"
},
"id": {
"type": "string"
},
"tenant_id": {
"default": "",
"type": "string"
}
},
"required": [
"authorization",
"sub",
"id"
],
"additionalProperties": false
}🟢list_tenant_services(authorization, tenant_id)
Return the caller's tenant's active service subscriptions. Call this before offering to add a service, to check what is already subscribed.
输入模式
{
"type": "object",
"properties": {
"authorization": {
"type": "string"
},
"tenant_id": {
"default": "",
"type": "string"
}
},
"required": [
"authorization"
],
"additionalProperties": false
}输出模式
{
"type": "object",
"properties": {
"result": {
"items": {
"additionalProperties": {
"type": "string"
},
"type": "object"
},
"title": "Response List Tenant Services",
"type": "array"
}
},
"required": [
"result"
],
"x-fastmcp-wrap-result": true
}🟡add_tenant_service(authorization, tenant_id, body)
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).
输入模式
{
"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
}输出模式
{
"type": "object",
"additionalProperties": {
"type": "string"
},
"title": "Response Add Tenant Service"
}社区
证据