SuperAPI AI Directory

publish-nats-message

Agents & models

View repository

Updated 10-16 01:35

About this skill

Skill: Publish NATS Message

Purpose

Enable collaborating projects to "produce messages correctly" — publish a message via the NATS MCP tool according to a cross-team contract, ensuring subject / headers / payload / QoS are strictly aligned specs/nats-messaging.md. When there is no contract for an event for the first time, guide the generation of a contract and persist it to the producer repo.


Core Objective

Primary Objective: Publish a contract-compliant message via the NATS MCP tool; if the contract does not exist, generate the contract first, then send.

Success Criteria:

  1. ✅ Project cache .cortex/nats.yaml has been read (if it does not exist, guide its generation)
  2. ✅ The <event>-contract.md corresponding to the event is in place (if it exists, read it; if it does not exist, draft it and prompt to commit)
  3. ✅ The actually sent subject / headers / payload strictly conform to the contract definition
  4. ✅ Nats-Msg-Id is the UUID v7 generated for this time (or reuse the original ID on retry of the same message)
  5. ✅ JetStream send receives ack; at-most-once only does fire-and-forget
  6. ✅ The user gets the send result (success + actual headers digest / failure + reason)

Acceptance Test: On the consumer side, use consume-nats-message to subscribe to the same subject, and it can correctly decode headers + payload with no validation failure.


Scope Boundaries

This skill is responsible for:

  • Reading the project cache + loading the contract
  • Drafting the contract according to specs/nats-messaging.md + specs/cross-team-contract.md when the contract is missing for the first time
  • Constructing a compliant message (subject + headers + payload)
  • Completing publish / jetstream_publish / request via the NATS MCP tool
  • Ack validation and failure retry (according to the contract retry policy)

This skill is not responsible for:

  • Actually writing publisher code → not within the Skill's scope (application engineering responsibility)
  • Creating / modifying JetStream stream / consumer / KV → IaC responsibility (see spec §5.5.2)
  • Subscribing / consuming messages → use consume-nats-message

Prerequisites

  • Already connected to the NATS MCP server (provides mcp__nats__publish / mcp__nats__jetstream_publish / mcp__nats__request and other tools; the specific tool names are subject to the connected server)
  • The current working directory is the producer repo (used to read .cortex/nats.yaml and the contract file)
  • The user can authorize publish permission to the broker

Execution Flow

Phase 0: Announcement

"I am using the publish-nats-message skill to send a NATS message."

Phase 1: Read Project Cache

  1. Read .cortex/nats.yaml(producer repo root directory)
  2. Extract fields:broker_url / service_source / default_stream / contract_dir / iac_owner
  3. Cache does not exist: Enter the "cache initialization subflow" — ask for the above fields, write .cortex/nats.yaml, prompt the user to review and commit; subsequent steps reuse the values filled in this time
  4. Cache exists but fields are missing: Ask only about the missing fields, update the cache

Phase 2: Locate Contract

  1. Parse the event description from user input (e.g., "send clarification.session.requested")
  2. Glob <contract_dir>/**/<event>-contract.md
  3. Hit: Read the contract → proceed to Phase 4
  4. Miss: Proceed to Phase 3 to draft the contract

Phase 3: Contract Drafting Subflow (only the first time for an event)

Ask for the minimum necessary information (the rest is obtained from the cache):

  • Consumer name (one or more)
  • QoS selection (default at-least-once; user may choose at-most-once but must specify the lossy scenario)
  • Whether it is a multi-turn session scenario (if yes → X-Correlation-Id marked as conditionally required, plan the sessionId position within the subject)
  • Business field table (payload schema draft; user may be asked to list the main field types and requiredness)
  • DLQ + retry parameters (default values: DLQ <subject>.dlq、max_deliver=5、exponential backoff base 1s max 30s)

Generate contract file:

After completion:

  • Prompt the user to review + commit the contract file
  • Wait for user confirmationAfter the contract is ok, proceed to Phase 4 actual sending (avoid sending polluted messages based on an unconfirmed contract)

Phase 4: Construct message

Fill fields per contract:

Item Value
subject Subject defined in the contract's "Contract Scope" section
Nats-Msg-Id Generate UUID v7 on site (reuse the original ID on retry)
X-Source Cache service_source
X-Type Event type string defined by the contract
Traceparent If the runtime environment has an OTel context, inject it; otherwise skip
X-Correlation-Id Required for multi-turn session scenarios; the caller provides the original ID
X-Schema-Url Fill in when the contract defines a schema URL
payload User-provided business data, validated field by field per the contract field table (all required fields present, types correct, enum values valid)

Validation failure → report an error indicating the violating fields,do not send。

Phase 5: Call the MCP NATS tool to send

Select the tool by QoS:

Scenario MCP tool Notes
at-most-once (telemetry / heartbeat) mcp__nats__publish No ack, fire-and-forget
at-least-once (cross-team default) mcp__nats__jetstream_publish Must wait for ack; triggers duplicate_window deduplication
Synchronous request-response (< 5s) mcp__nats__request Includes reply subject + X-Correlation-Id

The specific tool names are subject to what the connected NATS MCP server provides; if the tool signatures are inconsistent, the Skill adapts the mapping (headers parameter / subject parameter).

Phase 6: Self-check and receipt

  • JetStream: wait for ack; timeout / no ack → treat as failure
  • Failure retry: resend per the contract retry policy,reuse the same Nats-Msg-Id(broker-side deduplication); if it still fails after reaching max_deliver → report to the user
  • Success receipt: output
    • subject
    • Actual header values (sensitive fields may be masked if any)
    • ack information (JetStream sequence / stream / domain)
    • Duration

Error handling

Situation Handling
MCP NATS server not connected Prompt the user to check the MCP configuration and list the expected tool names
.cortex/nats.yaml does not exist Enter the cache initialization sub-flow (Phase 1)
Contract does not exist Enter the contract drafting sub-flow (Phase 3)
Payload field validation failed List the violating fields and require correction before resending
JetStream ack timeout Retry with contract-based backoff; report to the user on final failure
Stream does not exist (Subject domain not IaC-managed) The error indicates a violation of specs/nats-messaging.md §5.5.2; prompt to contact the IaC owner

Anti-patterns

  • ❌ Creating Stream / Consumer / KV at application code runtime (violates spec §5.5.2) —— error out and point to IaC
  • ❌ Cross-team messages going over Core NATS without persistence —— default to JetStream; only downgrade with explicit user confirmation
  • ❌ Using a new Nats-Msg-Id on retry —— must be reused, otherwise broker deduplication fails
  • ❌ Stuffing metadata into the payload JSON envelope (id / source / time , etc.) —— must go through Headers
  • ❌ Repeatedly asking for broker_url / service_source and other basic information without reading the cache
  • ❌ Sending directly when no contract exists —— must first draft and prompt to commit

Relationships with other assets

  • Structural contract ruler:specs/nats-messaging.md——the authority on subject / headers / payload / QoS / validation rules
  • Contract document skeleton:specs/cross-team-contract.md——apply its frontmatter + section structure when drafting a contract for the first time
  • Consumer-side companion:consume-nats-message——the other end of the same contract
  • Broker behavior authority:https://docs.nats.io——NATS protocol / JetStream / Services API defer to the official documentation