@radsoft/markbase-mcp 2026.11.3 → 2026.11.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -0
- package/dist/index.js +10 -4
- package/package.json +1 -1
- package/server.json +2 -2
package/README.md
CHANGED
|
@@ -52,6 +52,16 @@ including duplicates. Invalid or rejected batches do not consume monthly quota.
|
|
|
52
52
|
Accepted batches consume their full name count even if a search fails; the tool
|
|
53
53
|
does not retry automatically.
|
|
54
54
|
|
|
55
|
+
## Unreleased: opt-in phonetic clearance
|
|
56
|
+
|
|
57
|
+
Both screening tools accept an optional `phonetic` boolean in the source server.
|
|
58
|
+
The API mode is not enabled in production yet. Omit the parameter to keep current
|
|
59
|
+
spelling-only behavior; an unavailable opt-in request returns 503 rather than
|
|
60
|
+
silently downgrading. Successful opt-in responses preserve the API's separate
|
|
61
|
+
matching metadata and exact, spelling, and phonetic evidence. Scores and risk
|
|
62
|
+
thresholds keep their existing spelling meaning. See the
|
|
63
|
+
[unreleased contract](../docs/phonetic-clearance.md) for limits and publication steps.
|
|
64
|
+
|
|
55
65
|
## Why the class matters
|
|
56
66
|
|
|
57
67
|
Trademark rights are scoped to goods and services. DELTA coexists as an airline, a
|
package/dist/index.js
CHANGED
|
@@ -56,7 +56,7 @@ server.registerTool("search_trademarks", {
|
|
|
56
56
|
});
|
|
57
57
|
server.registerTool("check_trademark_availability", {
|
|
58
58
|
title: "Screen a proposed name against existing trademarks",
|
|
59
|
-
description: "Screen a proposed brand or company name against the US register and get existing marks
|
|
59
|
+
description: "Screen a proposed brand or company name against the US register and get ranked existing marks, each with a spelling similarity score and risk level. Use this BEFORE suggesting a company, product, or brand name to a user. This is a first-pass screening signal, not legal advice.",
|
|
60
60
|
inputSchema: {
|
|
61
61
|
name: z.string().describe("The proposed brand or company name to screen"),
|
|
62
62
|
trademark_class: z
|
|
@@ -64,21 +64,26 @@ server.registerTool("check_trademark_availability", {
|
|
|
64
64
|
.optional()
|
|
65
65
|
.describe("Nice class 1-45 for the goods/services. Strongly recommended — trademark rights are class-scoped, so screening without one produces noise."),
|
|
66
66
|
limit: z.number().int().min(1).max(25).optional().describe("Max conflicts to return, default 10"),
|
|
67
|
+
phonetic: z.boolean().optional().describe("Unreleased opt-in phonetic matching. Omit or use false for spelling-only results; true returns 503 while unavailable."),
|
|
67
68
|
},
|
|
68
|
-
}, async ({ name, trademark_class, limit }) => {
|
|
69
|
+
}, async ({ name, trademark_class, limit, phonetic }) => {
|
|
69
70
|
try {
|
|
70
71
|
const p = new URLSearchParams({ mark: name, limit: String(limit ?? 10) });
|
|
71
72
|
if (trademark_class)
|
|
72
73
|
p.set("class", padClass(trademark_class));
|
|
74
|
+
if (phonetic !== undefined)
|
|
75
|
+
p.set("phonetic", String(phonetic));
|
|
73
76
|
const data = await request(`/clearance?${p}`);
|
|
74
77
|
return ok({
|
|
75
78
|
proposed_name: data.mark,
|
|
76
79
|
scoped_to_class: data.class ? String(parseInt(data.class, 10)) : null,
|
|
77
80
|
highest_risk: data.highest_risk,
|
|
81
|
+
...(data.matching ? { matching: data.matching } : {}),
|
|
78
82
|
conflicts: data.matches.map((m) => ({
|
|
79
83
|
...shapeMark(m),
|
|
80
84
|
similarity: m.similarity,
|
|
81
85
|
risk: m.risk,
|
|
86
|
+
...(m.signals ? { signals: m.signals } : {}),
|
|
82
87
|
})),
|
|
83
88
|
disclaimer: "Screening signal only. Likelihood of confusion is a legal judgment and this does not cover state or common-law rights. Recommend a trademark attorney before adopting a name.",
|
|
84
89
|
});
|
|
@@ -95,12 +100,13 @@ server.registerTool("screen_trademark_names", {
|
|
|
95
100
|
trademark_class: z.string().regex(/^\d{1,3}$/).refine((value) => Number(value) >= 1 && Number(value) <= 45).optional()
|
|
96
101
|
.describe("Shared Nice class 1–45 for the goods or services"),
|
|
97
102
|
limit: z.number().int().min(1).max(50).optional().describe("Maximum matches per name; default 20"),
|
|
103
|
+
phonetic: z.boolean().optional().describe("Unreleased opt-in phonetic matching for every name. Omit or use false for spelling-only results; true returns 503 while unavailable."),
|
|
98
104
|
},
|
|
99
|
-
}, async ({ names, trademark_class, limit }) => {
|
|
105
|
+
}, async ({ names, trademark_class, limit, phonetic }) => {
|
|
100
106
|
try {
|
|
101
107
|
const data = await request("/clearance/batch", {
|
|
102
108
|
method: "POST",
|
|
103
|
-
body: JSON.stringify({ marks: names, class: trademark_class ? padClass(trademark_class) : undefined, limit }),
|
|
109
|
+
body: JSON.stringify({ marks: names, class: trademark_class ? padClass(trademark_class) : undefined, limit, phonetic }),
|
|
104
110
|
});
|
|
105
111
|
return ok({ ...data, disclaimer: "Screening signal only. Consult a trademark attorney before adopting a name." });
|
|
106
112
|
}
|
package/package.json
CHANGED
package/server.json
CHANGED
|
@@ -9,12 +9,12 @@
|
|
|
9
9
|
"source": "github",
|
|
10
10
|
"subfolder": "mcp"
|
|
11
11
|
},
|
|
12
|
-
"version": "2026.11.
|
|
12
|
+
"version": "2026.11.4",
|
|
13
13
|
"packages": [
|
|
14
14
|
{
|
|
15
15
|
"registryType": "npm",
|
|
16
16
|
"identifier": "@radsoft/markbase-mcp",
|
|
17
|
-
"version": "2026.11.
|
|
17
|
+
"version": "2026.11.4",
|
|
18
18
|
"transport": {
|
|
19
19
|
"type": "stdio"
|
|
20
20
|
},
|