Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ The format is inspired by Keep a Changelog, and this project adheres to semantic

## [Unreleased]

## [2.4.1] - 2026-09-25

### Fixed
- `nostr_publish_event` dropped empty tag values and trimmed the rest. Tags are positional, so
`["p", pk, "", "mention"]` went out as `["p", pk, "mention"]`, putting the marker in the
relay-hint slot, and a signed event could differ from the one previewed for approval. Tag
values are now passed through verbatim.

## [2.4.0] - 2026-09-21

### Added
Expand Down
2 changes: 1 addition & 1 deletion docs/howto/multi-relay-publishing.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ send a private direct message.
<dependency>
<groupId>xyz.tcheeric</groupId>
<artifactId>nostr-java-api</artifactId>
<version>2.4.0</version>
<version>2.4.1</version>
</dependency>
```

Expand Down
2 changes: 1 addition & 1 deletion nostr-java-api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>xyz.tcheeric</groupId>
<artifactId>nostr-java</artifactId>
<version>2.4.0</version>
<version>2.4.1</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion nostr-java-client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>xyz.tcheeric</groupId>
<artifactId>nostr-java</artifactId>
<version>2.4.0</version>
<version>2.4.1</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion nostr-java-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>xyz.tcheeric</groupId>
<artifactId>nostr-java</artifactId>
<version>2.4.0</version>
<version>2.4.1</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion nostr-java-event/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>xyz.tcheeric</groupId>
<artifactId>nostr-java</artifactId>
<version>2.4.0</version>
<version>2.4.1</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion nostr-java-identity/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>xyz.tcheeric</groupId>
<artifactId>nostr-java</artifactId>
<version>2.4.0</version>
<version>2.4.1</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion nostr-java-mcp/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>xyz.tcheeric</groupId>
<artifactId>nostr-java</artifactId>
<version>2.4.0</version>
<version>2.4.1</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,9 @@ public Map<String, List<String>> tagFilters(@NonNull String name) {
* <p>A single flat list is read as one entry, since a model given an example of nested arrays
* will sometimes send just the inner one.
*
* <p>Values are kept verbatim, unlike {@link #texts}: tags are positional, so dropping an empty
* relay hint in {@code ["p", pk, "", "mention"]} would move the marker into its place.
*
* @param name the argument to read
* @return each inner list's values
*/
Expand All @@ -139,14 +142,18 @@ public List<List<String>> nestedTexts(@NonNull String name) {
return List.of();
}
if (outer.stream().noneMatch(List.class::isInstance)) {
return List.of(texts(name));
return List.of(verbatim(outer));
}
return outer.stream()
.filter(List.class::isInstance)
.map(inner -> new ToolArguments(Map.of("v", inner)).texts("v"))
.map(inner -> verbatim((List<?>) inner))
.toList();
}

private static List<String> verbatim(List<?> values) {
return values.stream().map(String::valueOf).toList();
}

private int parseInteger(String name, String text) {
try {
return (int) Double.parseDouble(text);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package nostr.mcp.argument;

import org.junit.jupiter.api.Test;

import java.util.List;
import java.util.Map;

import static org.junit.jupiter.api.Assertions.assertEquals;

/** Verifies tool arguments are read without changing what the caller meant. */
class ToolArgumentsTest {

// Verifies an empty tag value keeps its position, since NIP-01 tags are positional and
// dropping the empty relay hint in ["p", pk, "", "mention"] moves the marker into its place.
@Test
void nestedTextsKeepEmptyValuesInPlace() {
var arguments = new ToolArguments(Map.of("tags", List.of(List.of("p", "abc", "", "mention"))));

assertEquals(List.of(List.of("p", "abc", "", "mention")), arguments.nestedTexts("tags"));
}

// Verifies tag values are not trimmed, since a tag can carry quoted text that must go out
// byte-for-byte.
@Test
void nestedTextsDoNotTrim() {
var arguments = new ToolArguments(Map.of("tags", List.of(List.of("comment", " spaced \n"))));

assertEquals(List.of(List.of("comment", " spaced \n")), arguments.nestedTexts("tags"));
}

// Verifies a single flat tag is read the same way, since that path is taken when a model sends
// only the inner array.
@Test
void aFlatTagKeepsEmptyValuesInPlace() {
var arguments = new ToolArguments(Map.of("tags", List.of("p", "abc", "", "mention")));

assertEquals(List.of(List.of("p", "abc", "", "mention")), arguments.nestedTexts("tags"));
}
}
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

<groupId>xyz.tcheeric</groupId>
<artifactId>nostr-java</artifactId>
<version>2.4.0</version>
<version>2.4.1</version>
<packaging>pom</packaging>

<name>nostr-java</name>
Expand Down
Loading