> ## Documentation Index
> Fetch the complete documentation index at: https://docs.slng.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Publish Tool

> Run the publish gates for the draft and, when they all pass, create the next immutable version. If any gate fails, returns 409 with the same PublishResult body, published set to false, and the per-gate check results.



## OpenAPI

````yaml /api-reference/agents/shared-resources.oas.yaml post /v1/agents/tools/{tool_id}/publish
openapi: 3.1.0
info:
  title: SLNG Agent Resources API
  version: 1.0.0
  description: >-
    Public control-plane API for agent resources: tools, MCP servers, Vault
    secrets and variables, and client models.
servers:
  - url: https://api.agents.slng.ai
    description: Production
security:
  - bearerAuth: []
tags:
  - name: Tools
    description: Create, test, publish, version, and attach agent tools.
    x-page-icon: wrench
  - name: MCP servers
    description: Configure MCP servers and refresh their live capabilities.
    x-page-icon: plug
  - name: Vault
    description: >-
      Store organisation secrets and readable variables without exposing secret
      values.
    x-page-icon: key
  - name: Client models
    description: Manage bring-your-own LLM provider credentials.
    x-page-icon: brain
paths:
  /v1/agents/tools/{tool_id}/publish:
    post:
      tags:
        - Tools
      summary: Publish Tool
      description: >-
        Run the publish gates for the draft and, when they all pass, create the
        next immutable version. If any gate fails, returns 409 with the same
        PublishResult body, published set to false, and the per-gate check
        results.
      operationId: publishTool
      parameters:
        - name: tool_id
          in: path
          required: true
          description: >-
            The tool UUID. Curated tools are visible but read-only, and a tool
            owned by another organisation returns 404.
          schema:
            type: string
            format: uuid
            title: Tool Id
      responses:
        '200':
          description: >-
            The publish result. A new immutable version is created and the
            per-gate checks are reported; if a gate fails, the same body is
            returned with a 409 and published set to false.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublishResult'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '403':
          $ref: '#/components/responses/ForbiddenError'
        '404':
          $ref: '#/components/responses/NotFoundError'
        '409':
          description: One or more gates failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublishResult'
        '422':
          $ref: '#/components/responses/ValidationError'
        '429':
          $ref: '#/components/responses/RateLimitError'
        '500':
          $ref: '#/components/responses/InternalServerError'
components:
  schemas:
    PublishResult:
      properties:
        published:
          type: boolean
          title: Published
        version_number:
          anyOf:
            - type: integer
            - type: 'null'
          title: Version Number
        checks:
          $ref: '#/components/schemas/GateStatus'
      type: object
      required:
        - published
        - checks
      title: PublishResult
      description: >-
        Outcome of a publish attempt, with the new version number and per-gate
        checks.
      example:
        published: true
        version_number: 4
        checks:
          static:
            config_valid:
              passed: true
            secrets_exist:
              passed: true
            name_unique:
              passed: true
          green_run:
            passed: true
    GateStatus:
      properties:
        static:
          anyOf:
            - $ref: '#/components/schemas/StaticGate'
            - $ref: '#/components/schemas/TypedStaticGate'
            - type: 'null'
          title: Static
        green_run:
          anyOf:
            - $ref: '#/components/schemas/GreenRun'
            - type: 'null'
        config_valid:
          anyOf:
            - $ref: '#/components/schemas/CheckResult'
            - type: 'null'
        code_environment:
          anyOf:
            - $ref: '#/components/schemas/CheckResult'
            - type: 'null'
        content_current:
          anyOf:
            - $ref: '#/components/schemas/CheckResult'
            - type: 'null'
      type: object
      title: GateStatus
      description: |-
        Gate set is selected by tool_type (V2): data → static + green_run;
        code also reports config_valid; ctx-bound → config_valid ONLY.
    ApiErrorResponse:
      type: object
      description: Standard error envelope returned for failed requests.
      required:
        - detail
        - error
      properties:
        detail:
          type: string
          description: Short human-readable summary of the error.
        error:
          $ref: '#/components/schemas/ApiErrorDetail'
      example:
        detail: A shared secret or variable named 'STRIPE_KEY' already exists
        error:
          code: RESOURCE_CONFLICT
          message: A shared secret or variable named 'STRIPE_KEY' already exists
          request_id: 018f9b2c-7e4a-7c3d-9a1b-2c3d4e5f6a7b
    StaticGate:
      properties:
        parse:
          $ref: '#/components/schemas/CheckResult'
        models:
          $ref: '#/components/schemas/CheckResult'
        schema:
          $ref: '#/components/schemas/CheckResult'
        secrets_exist:
          $ref: '#/components/schemas/CheckResult'
        name_unique:
          $ref: '#/components/schemas/CheckResult'
      type: object
      required:
        - parse
        - models
        - schema
        - secrets_exist
        - name_unique
      title: Static gate
      description: A publish readiness gate evaluated from static analysis.
    TypedStaticGate:
      properties:
        config_valid:
          $ref: '#/components/schemas/CheckResult'
        secrets_exist:
          $ref: '#/components/schemas/CheckResult'
        name_unique:
          $ref: '#/components/schemas/CheckResult'
      type: object
      required:
        - config_valid
        - secrets_exist
        - name_unique
      title: Typed static gate
      description: A typed publish readiness gate evaluated from static analysis.
    GreenRun:
      properties:
        passed:
          type: boolean
          title: Passed
        proven_hash:
          anyOf:
            - type: string
            - type: 'null'
          title: Proven Hash
      type: object
      required:
        - passed
      title: GreenRun
      description: >-
        Result of the green-run gate, with the hash proven by a successful test
        run.
    CheckResult:
      properties:
        passed:
          type: boolean
          title: Passed
        detail:
          anyOf:
            - type: string
            - type: 'null'
          title: Detail
      type: object
      required:
        - passed
      title: CheckResult
      description: >-
        Result of one publish readiness check, with a pass flag and optional
        detail.
    ApiErrorDetail:
      type: object
      description: Structured error detail carried inside an error response.
      required:
        - code
        - message
      properties:
        code:
          type: string
          description: Stable machine-readable error code.
          example: RESOURCE_CONFLICT
        message:
          type: string
          description: Human-readable explanation of the error.
          example: A shared secret or variable named STRIPE_KEY already exists
        request_id:
          type:
            - string
            - 'null'
          description: Identifier for this request, useful when contacting support.
          example: req_01H8XY7Z9QEXAMPLE
        retryable:
          type: boolean
          description: Whether retrying the same request may succeed.
          example: false
        fields:
          type: array
          description: >-
            Per-field validation problems, when the error relates to specific
            request fields.
          items:
            type: object
            additionalProperties: true
          example: []
      example:
        code: PUBLIC_SHARED_RESOURCES_DISABLED
        message: Public shared resources are disabled for this organisation
        request_id: req_01H8XY7Z9QEXAMPLE
        retryable: false
  responses:
    UnauthorizedError:
      description: The API key is missing or invalid.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiErrorResponse'
          example:
            detail: Invalid API key
            error:
              code: AUTH_REQUIRED
              message: Invalid API key
              request_id: 018f9b2c-7e4a-7c3d-9a1b-2c3d4e5f6a7b
              retryable: false
    ForbiddenError:
      description: >-
        The caller lacks permission, or the public shared-resource API is
        disabled for the organisation.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiErrorResponse'
          examples:
            permission_denied:
              summary: Owner or admin access required
              value:
                detail: Organisation owner or admin access required
                error:
                  code: PERMISSION_DENIED
                  message: Organisation owner or admin access required
                  request_id: 018f9b2c-7e4a-7c3d-9a1b-2c3d4e5f6a7b
                  retryable: false
            api_disabled:
              summary: Public shared-resource API disabled for the organisation
              value:
                detail: >-
                  Public shared-resource API access is disabled for this
                  organisation
                error:
                  code: PUBLIC_SHARED_RESOURCES_DISABLED
                  message: >-
                    Public shared-resource API access is disabled for this
                    organisation
                  request_id: 018f9b2c-7e4a-7c3d-9a1b-2c3d4e5f6a7b
                  retryable: false
    NotFoundError:
      description: The requested resource does not exist for this organisation.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiErrorResponse'
          example:
            detail: The requested resource was not found.
            error:
              code: RESOURCE_NOT_FOUND
              message: The requested resource was not found.
              request_id: 018f9b2c-7e4a-7c3d-9a1b-2c3d4e5f6a7b
    ValidationError:
      description: Request validation failed. See error.fields for the offending fields.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiErrorResponse'
          example:
            detail: >-
              Request validation failed. Fix the highlighted fields and try
              again.
            error:
              code: VALIDATION_FAILED
              message: >-
                Request validation failed. Fix the highlighted fields and try
                again.
              request_id: 018f9b2c-7e4a-7c3d-9a1b-2c3d4e5f6a7b
              retryable: false
              fields:
                - path: name
                  message: >-
                    Name must be SCREAMING_SNAKE_CASE: start with a letter, then
                    letters, digits, or underscores (e.g. STRIPE_API_KEY)
    RateLimitError:
      description: >-
        The organisation exceeded its request rate limit. Retry after the window
        resets.
      headers:
        Retry-After:
          schema:
            type: integer
        X-RateLimit-Limit:
          schema:
            type: integer
        X-RateLimit-Remaining:
          schema:
            type: integer
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiErrorResponse'
          example:
            detail: Rate limit exceeded. Maximum 60 requests per 60 seconds.
            error:
              code: INTERNAL_ERROR
              message: Rate limit exceeded. Maximum 60 requests per 60 seconds.
              request_id: 018f9b2c-7e4a-7c3d-9a1b-2c3d4e5f6a7b
              retryable: false
    InternalServerError:
      description: The request failed unexpectedly. Secret values are never exposed.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiErrorResponse'
          example:
            detail: An unexpected error occurred.
            error:
              code: INTERNAL_ERROR
              message: An unexpected error occurred.
              request_id: 018f9b2c-7e4a-7c3d-9a1b-2c3d4e5f6a7b
              retryable: false
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: SLNG API key
      description: Your SLNG consumer API key.

````