Skip to main content
Glama

produce_message

Write one or more messages to existing Kafka topics, including content no producer sent, and encode values to Schema Registry schemas. Use it to inject or repair records; writes require confirm.

Instructions

Write 1 to 500 new messages in one call through items, or any number from an upload, to existing topics on this or another configured cluster. The caller supplies the key, value and headers, so unlike copy_message this can write content no producer ever sent. Writing one message is an items array of length one.

Every message carries provenance headers naming this tool, the time and the principal, so a fabricated message stays distinguishable from a genuine one.

upload sends a file on the user's own machine, one item per line as JSON, such as the file a transform_messages download saves. Over stdio the file is read at once; over HTTP the response is a link and a command to run there, once, as each run sends the file again. The file is never stored on the server, and the summary counts lines, shows a few examples and the failing lines by number. Without confirm the upload only checks the file.

Nothing is written unless confirm is true; one confirm covers the whole batch, and writing is not atomic because Kafka cannot retract a record produced before a later item failed. Results follow items order, each carrying index with result or error.

A produced message cannot be deleted: it stays until retention removes it, and any consumer reading the topic will process it. The destination must be writable and requires Kafka write permission; the endpoint you call may itself be read-only.

Omit partition unless the exact partition matters. The key decides placement, and naming a partition puts a keyed message where its key does not hash to, which breaks ordering for that key.

A topic whose consumers read Avro, Protobuf or JSON Schema needs value_schema: give the value as JSON and it is encoded to the destination registry's schema, refused with the offending field when it does not fit. A topic with a format configured in topic_formats is encoded to it without being asked. Check get_message or sample_messages first: a schema_id on the existing messages means the topic needs value_schema, and writing plain JSON there breaks its consumers.

Input Schema

NameRequiredDescriptionDefault
itemsNoThe messages to write, 1 to 500 of them. Writing one message is an array of length one. Two identical items mean two messages, which is allowed: appending the same payload twice is a real request. Give either items or upload, not both.
uploadNoOptional. Instead of items, send messages from a file on the user's own machine. Over stdio the file is read right away and the response carries its summary in file; over HTTP the response is a link and a command, e.g. curl -T, to run there, which prints the summary. Run an upload command once: each run sends the file again. The file holds one item per line as JSON, with the same fields as an entry of items, such as the file transform_messages download saves. It is read as it uploads and never stored on the server. Use it for more messages than items allows, or for a set saved and inspected first. Without confirm the upload writes nothing and its response counts the valid lines and reports the invalid ones by line number; call again with confirm to send. Give either items or upload, not both.
confirmNoOptional. When false or omitted, nothing is written and the response shows the messages that would be produced. Must be true to actually write them. One confirm covers the whole batch.

Output Schema

NameRequiredDescriptionDefault
fileNo
atomicYes
failedYes
uploadNo
appliedYes
resultsYes
succeededYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed5 schema fields changedv0.2.7
    • changedInput schema / properties / items / description
      Previous value: -"The messages to write, 1 to 20 of them. Writing one message is an array of length one. Two identical items mean two messages, which is allowed: appending the same payload twice is a real request."New value: +"The messages to write, 1 to 500 of them. Writing one message is an array of length one. Two identical items mean two messages, which is allowed: appending the same payload twice is a real request. Give either items or upload, not both."
    • addedInput schema / properties / upload
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "Optional. Instead of items, send messages from a file on the user's own machine. Over stdio the file is read right away and the response carries its summary in file; over HTTP the response is a link and a command, e.g. curl -T, to run there, which prints the summary. Run an upload command once: each run sends the file again. The file holds one item per line as JSON, with the same fields as an entry of items, such as the file transform_messages download saves. It is read as it uploads and never stored on the server. Use it for more messages than items allows, or for a set saved and inspected first. Without confirm the upload writes nothing and its response counts the valid lines and reports the invalid ones by line number; call again with confirm to send. Give either items or upload, not both.",
      +  "properties": {
      +    "filename": {
      +      "description": "Optional name of the file on the user's machine. Over stdio it may be a path, relative to the server's working directory or absolute; over HTTP it is a plain file name used in the command. Defaults to messages.jsonl.",
      +      "type": "string"
      +    }
      +  },
      +  "type": [
      +    "null",
      +    "object"
      +  ]
      +}
    • removedInput schema / required
      Removed value: -[
      -  "items"
      -]
    • addedOutput schema / properties / file
      Added value: +{
      +  "additionalProperties": false,
      +  "properties": {
      +    "applied": {
      +      "type": "boolean"
      +    },
      +    "confirm": {
      +      "type": "boolean"
      +    },
      +    "errors": {
      +      "items": {
      +        "additionalProperties": false,
      +        "properties": {
      +          "error": {
      +            "type": "string"
      +          },
      +          "line": {
      +            "type": "integer"
      +          }
      +        },
      +        "required": [
      +          "line",
      +          "error"
      +        ],
      +        "type": "object"
      +      },
      +      "type": [
      +        "null",
      +        "array"
      +      ]
      +    },
      +    "errors_truncated": {
      +      "type": "boolean"
      +    },
      +    "examples": {
      +      "items": {
      +        "additionalProperties": false,
      +        "properties": {
      +          "applied": {
      +            "type": "boolean"
      +          },
      +          "destination_cluster": {
      +            "type": "string"
      +          },
      +          "key_encoding": {
      +            "additionalProperties": false,
      +            "properties": {
      +              "format": {
      +                "type": "string"
      +              },
      +              "message_type": {
      +                "type": "string"
      +              },
      +              "schema_id": {
      +                "type": "integer"
      +              },
      +              "subject": {
      +                "type": "string"
      +              },
      +              "version": {
      +                "type": "integer"
      +              }
      +            },
      +            "required": [
      +              "format"
      +            ],
      +            "type": [
      +              "null",
      +              "object"
      +            ]
      +          },
      +          "message": {
      +            "additionalProperties": false,
      +            "properties": {
      +              "decode_error": {
      +                "type": "string"
      +              },
      +              "encoding": {
      +                "type": "string"
      +              },
      +              "format": {
      +                "type": "string"
      +              },
      +              "headers": {
      +                "additionalProperties": {
      +                  "type": "string"
      +                },
      +                "type": "object"
      +              },
      +              "key": {
      +                "type": "string"
      +              },
      +              "key_format": {
      +                "type": "string"
      +              },
      +              "key_schema_id": {
      +                "type": "integer"
      +              },
      +              "message_type": {
      +                "type": "string"
      +              },
      +              "offset": {
      +                "type": "integer"
      +              },
      +              "partition": {
      +                "maximum": 2147483647,
      +                "minimum": -2147483648,
      +                "type": "integer"
      +              },
      +              "schema_id": {
      +                "type": "integer"
      +              },
      +              "timestamp": {
      +                "type": "string"
      +              },
      +              "truncated": {
      +                "type": "boolean"
      +              },
      +              "value": {
      +                "type": "string"
      +              },
      +              "value_bytes": {
      +                "type": "integer"
      +              }
      +            },
      +            "required": [
      +              "partition",
      +              "offset",
      +              "timestamp",
      +              "key",
      +              "value",
      +              "encoding",
      +              "format",
      +              "value_bytes",
      +              "truncated"
      +            ],
      +            "type": "object"
      +          },
      +          "note": {
      +            "type": "string"
      +          },
      +          "provenance_headers": {
      +            "items": {
      +              "type": "string"
      +            },
      +            "type": [
      +              "null",
      +              "array"
      +            ]
      +          },
      +          "topic": {
      +            "type": "string"
      +          },
      +          "value_encoding": {
      +            "additionalProperties": false,
      +            "properties": {
      +              "format": {
      +                "type": "string"
      +              },
      +              "message_type": {
      +                "type": "string"
      +              },
      +              "schema_id": {
      +                "type": "integer"
      +              },
      +              "subject": {
      +                "type": "string"
      +              },
      +              "version": {
      +                "type": "integer"
      +              }
      +            },
      +            "required": [
      +              "format"
      +            ],
      +            "type": [
      +              "null",
      +              "object"
      +            ]
      +          },
      +          "warnings": {
      +            "items": {
      +              "type": "string"
      +            },
      +            "type": [
      +              "null",
      +              "array"
      +            ]
      +          },
      +          "written_offset": {
      +            "type": "integer"
      +          },
      +          "written_partition": {
      +            "maximum": 2147483647,
      +            "minimum": -2147483648,
      +            "type": "integer"
      +          }
      +        },
      +        "required": [
      +          "destination_cluster",
      +          "topic",
      +          "message",
      +          "applied",
      +          "written_partition",
      +          "written_offset"
      +        ],
      +        "type": "object"
      +      },
      +      "type": [
      +        "null",
      +        "array"
      +      ]
      +    },
      +    "failed": {
      +      "type": "integer"
      +    },
      +    "invalid": {
      +      "type": "integer"
      +    },
      +    "lines": {
      +      "type": "integer"
      +    },
      +    "note": {
      +      "type": "string"
      +    },
      +    "valid": {
      +      "type": "integer"
      +    },
      +    "written": {
      +      "type": "integer"
      +    }
      +  },
      +  "required": [
      +    "confirm",
      +    "lines",
      +    "valid",
      +    "invalid",
      +    "written",
      +    "failed",
      +    "applied",
      +    "examples",
      +    "errors"
      +  ],
      +  "type": [
      +    "null",
      +    "object"
      +  ]
      +}
    • addedOutput schema / properties / upload
      Added value: +{
      +  "additionalProperties": false,
      +  "properties": {
      +    "command": {
      +      "type": "string"
      +    },
      +    "expires_at": {
      +      "type": [
      +        "null",
      +        "string"
      +      ]
      +    },
      +    "method": {
      +      "type": "string"
      +    },
      +    "note": {
      +      "type": "string"
      +    },
      +    "path": {
      +      "type": "string"
      +    },
      +    "result": true,
      +    "url": {
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "method",
      +    "note"
      +  ],
      +  "type": [
      +    "null",
      +    "object"
      +  ]
      +}
  2. First observedv0.2.0

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does so: nothing is written unless confirm is true, one confirm covers the whole batch, writes are non-atomic because Kafka cannot retract an earlier record, produced messages cannot be deleted until retention, the destination needs Kafka write permission while the called endpoint may be read-only, and upload files are read as they stream and never stored on the server. Provenance headers and the stdio-vs-HTTP upload difference are also disclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core capability and otherwise dense with useful facts, but it runs seven paragraphs and repeats the partition guidance and the items-vs-upload exclusion that already appear verbatim in the schema property descriptions.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a multi-mode, high-risk write tool with a rich output schema, it covers invocation modes, confirmation gating, ordering of results, schema encoding requirements, and failure reporting (failing lines by number). An agent has everything needed to call it correctly without trial and error.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline would be 3, but the description adds non-obvious semantics: the items/upload mutual exclusion, that confirm gates the entire batch, that value_schema is required when existing messages carry a schema_id, and the partition/key-ordering tradeoff. These are decision-relevant facts not derivable from the schema text alone.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb and resource plus capacity bounds: write 1 to 500 new messages via items, or any number from an upload, to existing topics on this or another cluster. It explicitly distinguishes itself from copy_message by noting the caller supplies key/value/headers so it can write content no producer ever sent.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit routing rules: use items vs upload (items for up to 500, upload for larger or pre-inspected sets), call get_message or sample_messages first to detect a schema_id, use value_schema when the topic's consumers read Avro/Protobuf/JSON Schema, and omit partition unless the exact partition matters. Exclusions and named alternatives are both present.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.