@nooticr/mcp 1.26.46 → 1.26.47
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 +2 -1
- package/dist/shared/loading-plans.js +1 -0
- package/dist/shared/output-schemas.js +17 -0
- package/dist/shared/tools-def.js +6 -0
- package/dist/shared/tools.js +39 -1
- package/dist/shared/ui-template.js +45 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -52,7 +52,7 @@ npx @nooticr/mcp login # one-time sign-in (Google)
|
|
|
52
52
|
|
|
53
53
|
## Tools
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
87 tools, grouped by what you are trying to do. Prices are in nooticr credits and
|
|
56
56
|
match what the server actually charges.
|
|
57
57
|
|
|
58
58
|
The job tools under **Answer a question you actually have** are not
|
|
@@ -174,6 +174,7 @@ a `scanId` for the rest.
|
|
|
174
174
|
| `check_nooticr_credits` | free | Balance and billing URL. |
|
|
175
175
|
| `list_tool_runs` | free | Your tool-call history: what ran, whether it worked, and the credits each call actually took (0 for a free, refunded, cached or replayed call). `scope: "workspace"` shows every member's runs to owners and admins. |
|
|
176
176
|
| `get_tool_run` | free | One run from that history by id, with its full error. |
|
|
177
|
+
| `get_usage_report` | free | The run ledger added up over a window: total calls, failures and credits actually taken, per tool, per day and the most recent failures. `scope: "workspace"` adds one row per seat, for the workspace's owners and admins. |
|
|
177
178
|
| `nooticr_login` | free | Re-link the account when a call fails with an authentication error. |
|
|
178
179
|
| `list_social_connections` | free | What you have connected and what each connection is actually allowed to do — read the account, publish a post, manage comments — as yes, no or **unknown**. "Manage comments" reports the platform's grant; no nooticr tool posts or replies to a comment. Unknown means the grant predates scope recording: treat it as "try it", not as a refusal. Also says which platforms can be linked at all, which is a smaller set than the networks nooticr reads. |
|
|
179
180
|
| `connect_social_account` | free | A link the user opens to connect one account. They approve at the provider in their own browser; nothing is connected until they do, and no credential passes through the tool or the model's context. Each call mints a fresh link — an old one does not work twice. |
|
|
@@ -495,6 +495,7 @@ export const LOADING_PLANS = {
|
|
|
495
495
|
check_nooticr_credits: { label: "Checking your balance", kind: "text", n: 1, steps: [], free: true },
|
|
496
496
|
list_tool_runs: { label: "Reading your run history", kind: "text", n: 1, steps: [], free: true },
|
|
497
497
|
get_tool_run: { label: "Reading the run", kind: "text", n: 1, steps: [], free: true },
|
|
498
|
+
get_usage_report: { label: "Adding up the run ledger", kind: "text", n: 1, steps: [], free: true },
|
|
498
499
|
nooticr_getting_started: { label: "Reading where your account stands", kind: "text", n: 1, steps: [], free: true },
|
|
499
500
|
nooticr_login: { label: "Getting a sign-in link", kind: "text", n: 1, steps: [], free: true },
|
|
500
501
|
watch_creator: { label: "Adding to your watchlist", kind: "text", n: 1, steps: [], free: true },
|
|
@@ -1135,6 +1135,23 @@ export const OUTPUT_SCHEMAS = {
|
|
|
1135
1135
|
userId: scalar().describe("Whose run it was; only in the workspace scope."),
|
|
1136
1136
|
}).nullish(),
|
|
1137
1137
|
}),
|
|
1138
|
+
get_usage_report: open({
|
|
1139
|
+
report: scalar(),
|
|
1140
|
+
scope: scalar().describe("mine or workspace."),
|
|
1141
|
+
from: scalar(),
|
|
1142
|
+
to: scalar(),
|
|
1143
|
+
totals: open({
|
|
1144
|
+
calls: scalar(),
|
|
1145
|
+
failures: scalar(),
|
|
1146
|
+
credits: scalar().describe("Credits actually taken: free first uses, refunds and replays are zero."),
|
|
1147
|
+
tools: scalar(),
|
|
1148
|
+
seats: scalar(),
|
|
1149
|
+
}).nullish(),
|
|
1150
|
+
byTool: listOf(open({ tool: scalar(), calls: scalar(), failures: scalar(), credits: scalar(), lastUsedAt: scalar() })),
|
|
1151
|
+
bySeat: listOf(open({ userId: scalar(), email: scalar(), name: scalar(), calls: scalar(), failures: scalar(), credits: scalar() })).describe("Workspace reports only; empty on a personal one."),
|
|
1152
|
+
byDay: listOf(open({ day: scalar(), calls: scalar(), failures: scalar(), credits: scalar() })),
|
|
1153
|
+
recentFailures: listOf(open({ id: scalar(), tool: scalar(), error: scalar(), startedAt: scalar(), userId: scalar(), credits: scalar() })),
|
|
1154
|
+
}),
|
|
1138
1155
|
nooticr_login: open({
|
|
1139
1156
|
signedIn: scalar().describe("true when the session is already good and no link is needed."),
|
|
1140
1157
|
loginUrl: scalar().describe("Only present when a sign-in is actually required."),
|
package/dist/shared/tools-def.js
CHANGED
|
@@ -222,6 +222,12 @@ export const TOOL_DEFINITIONS = [
|
|
|
222
222
|
description: "One run from list_tool_runs by its id, with its full error text, credentials scrubbed. A run outside your scope reads as not found. No cost to call. Use to look closely at one charge.",
|
|
223
223
|
inputSchema: z.object({ id: z.number().int(), scope: z.enum(["mine", "workspace"]).optional() }).strict(),
|
|
224
224
|
},
|
|
225
|
+
{
|
|
226
|
+
name: "get_usage_report",
|
|
227
|
+
title: "Get Usage Report",
|
|
228
|
+
description: "A usage report over a window: total calls, failures and credits actually taken, per tool, per day, and recent failures; scope workspace adds one row per seat, for owners and admins. No cost to call.",
|
|
229
|
+
inputSchema: z.object({ days: z.number().int().min(1).max(366).optional(), from: z.string().optional(), to: z.string().optional(), scope: z.enum(["mine", "workspace"]).optional() }).strict(),
|
|
230
|
+
},
|
|
225
231
|
{
|
|
226
232
|
name: "nooticr_login",
|
|
227
233
|
title: "Nooticr Login",
|
package/dist/shared/tools.js
CHANGED
|
@@ -30,7 +30,7 @@ import { registerCollabTools } from "./collab.js";
|
|
|
30
30
|
import { registerAmazonTools } from "./amazon.js";
|
|
31
31
|
import { registerMarketplaceTools } from "./marketplace.js";
|
|
32
32
|
/** Current MCP server version — bumped on every deploy for traceability. */
|
|
33
|
-
export const MCP_SERVER_VERSION = "1.26.
|
|
33
|
+
export const MCP_SERVER_VERSION = "1.26.47";
|
|
34
34
|
/** MCP Apps extension identifier */
|
|
35
35
|
const UI_EXTENSION = "io.modelcontextprotocol/ui";
|
|
36
36
|
/** MIME type for MCP Apps HTML resources */
|
|
@@ -604,6 +604,7 @@ export function createMcpServer(rawMakeClient, opts) {
|
|
|
604
604
|
"check_nooticr_credits",
|
|
605
605
|
"list_tool_runs",
|
|
606
606
|
"get_tool_run",
|
|
607
|
+
"get_usage_report",
|
|
607
608
|
"list_watchlist",
|
|
608
609
|
"nooticr_getting_started",
|
|
609
610
|
"understand_social_post",
|
|
@@ -2610,6 +2611,43 @@ export function createMcpServer(rawMakeClient, opts) {
|
|
|
2610
2611
|
return toolError("get_tool_run failed", err);
|
|
2611
2612
|
}
|
|
2612
2613
|
});
|
|
2614
|
+
// The run ledger added up (#93): the question an owner or a security review
|
|
2615
|
+
// asks ("what did the team run this month, what did it cost, what failed")
|
|
2616
|
+
// answered from the same rows as the history, never from memory.
|
|
2617
|
+
server.registerTool("get_usage_report", {
|
|
2618
|
+
title: "Get Usage Report",
|
|
2619
|
+
description: "A usage report over a window: total calls, failures and credits actually taken; one row " +
|
|
2620
|
+
"per tool, most expensive first; one row per day, quiet days included; and the ten most " +
|
|
2621
|
+
"recent failures with their errors, credentials scrubbed. scope: \"workspace\" covers " +
|
|
2622
|
+
"every member of your workspace and adds one row per seat; it is for the workspace's " +
|
|
2623
|
+
"owners and admins. Reads the stored run ledger, so it is free and says what happened, " +
|
|
2624
|
+
"not what is running. No cost to call. Use for \"what did we spend this month and on " +
|
|
2625
|
+
"what\" or an audit of what nooticr did on the workspace's behalf; list_tool_runs is the " +
|
|
2626
|
+
"call-by-call view.",
|
|
2627
|
+
_meta: {
|
|
2628
|
+
ui: { resourceUri: uiResource("get_usage_report") },
|
|
2629
|
+
"ui/resourceUri": uiResource("get_usage_report"),
|
|
2630
|
+
"openai/outputTemplate": appsSdkResource("get_usage_report"),
|
|
2631
|
+
},
|
|
2632
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
2633
|
+
outputSchema: OUTPUT_SCHEMAS.get_usage_report,
|
|
2634
|
+
inputSchema: z
|
|
2635
|
+
.object({
|
|
2636
|
+
days: z.number().int().min(1).max(366).optional().describe("The window, in days back from now (default 30)."),
|
|
2637
|
+
from: z.string().optional().describe("Start of the window, ISO date or timestamp. Overrides days."),
|
|
2638
|
+
to: z.string().optional().describe("End of the window, ISO date or timestamp (default now)."),
|
|
2639
|
+
scope: runFilters.scope,
|
|
2640
|
+
})
|
|
2641
|
+
.strict(),
|
|
2642
|
+
}, async (args, extra) => {
|
|
2643
|
+
const client = await makeClient({ ...extra, arguments: args });
|
|
2644
|
+
try {
|
|
2645
|
+
return await toToolResult(await client.callTool("get_usage_report", { ...args }));
|
|
2646
|
+
}
|
|
2647
|
+
catch (err) {
|
|
2648
|
+
return toolError("get_usage_report failed", err);
|
|
2649
|
+
}
|
|
2650
|
+
});
|
|
2613
2651
|
server.registerTool("nooticr_login", {
|
|
2614
2652
|
title: "Nooticr Login",
|
|
2615
2653
|
description: "Get a fresh login URL to re-authenticate your MCP session. Call this tool when you need to reconnect or when the session has expired. No cost to call." +
|
|
@@ -45,6 +45,7 @@ export const NOOTICR_UI_TEMPLATE = `<!DOCTYPE html>
|
|
|
45
45
|
check_nooticr_credits:"Check Credits",
|
|
46
46
|
list_tool_runs:"Tool Runs",
|
|
47
47
|
get_tool_run:"Tool Run",
|
|
48
|
+
get_usage_report:"Usage Report",
|
|
48
49
|
list_watchlist:"Watchlist",
|
|
49
50
|
detect_spoken_mentions:"Spoken Mentions",
|
|
50
51
|
nooticr_getting_started:"Getting Started",
|
|
@@ -84,6 +85,7 @@ export const NOOTICR_UI_TEMPLATE = `<!DOCTYPE html>
|
|
|
84
85
|
check_nooticr_credits:"View your Nooticr credit balance and usage.",
|
|
85
86
|
list_tool_runs:"Where your credits went: every call, what it cost, and whether it worked.",
|
|
86
87
|
get_tool_run:"One call from your history, with its full error.",
|
|
88
|
+
get_usage_report:"What was spent, on what, by whom, and what failed.",
|
|
87
89
|
list_watchlist:"The creators you are watching, and when you last caught up on each.",
|
|
88
90
|
detect_spoken_mentions:"Brands named out loud in a video, beside what its caption says.",
|
|
89
91
|
nooticr_getting_started:"Where your account stands and what to try first.",
|
|
@@ -3152,6 +3154,48 @@ export const NOOTICR_UI_TEMPLATE = `<!DOCTYPE html>
|
|
|
3152
3154
|
return '<div class="fade-in">'+head+body+"</div>";
|
|
3153
3155
|
}
|
|
3154
3156
|
|
|
3157
|
+
// ─── Usage report (get_usage_report) ───
|
|
3158
|
+
//
|
|
3159
|
+
// A spend table: the totals first, then where it went. Credits are what was
|
|
3160
|
+
// actually taken, so a free first use or a refund reads as 0, not as the
|
|
3161
|
+
// tool's price.
|
|
3162
|
+
function renderUsageReport(d){
|
|
3163
|
+
var t=d.totals||{};
|
|
3164
|
+
function tile(label,val){
|
|
3165
|
+
return '<div style="flex:1;min-width:110px;padding:10px 12px;border:1px solid var(--border);border-radius:10px">'
|
|
3166
|
+
+'<div style="font-size:11px;color:var(--muted);text-transform:uppercase;letter-spacing:.05em">'+esc(label)+"</div>"
|
|
3167
|
+
+'<div style="font-size:18px;font-weight:700;margin-top:3px">'+esc(String(val==null?"—":val))+"</div></div>";
|
|
3168
|
+
}
|
|
3169
|
+
function table(title,cols,rows){
|
|
3170
|
+
if(!rows.length)return "";
|
|
3171
|
+
return '<div class="sec-label" style="margin-top:14px">'+esc(title)+"</div>"
|
|
3172
|
+
+'<table style="width:100%;border-collapse:collapse;font-size:13px">'
|
|
3173
|
+
+"<tr>"+cols.map(function(c,i){return '<th style="text-align:'+(i?"right":"left")+';font-weight:600;color:var(--muted);padding:4px 0">'+esc(c)+"</th>";}).join("")+"</tr>"
|
|
3174
|
+
+rows.map(function(r){return '<tr data-usage-row style="border-top:1px solid var(--border)">'+r.map(function(v,i){return '<td style="padding:6px 0;text-align:'+(i?"right":"left")+'">'+esc(String(v))+"</td>";}).join("")+"</tr>";}).join("")
|
|
3175
|
+
+"</table>";
|
|
3176
|
+
}
|
|
3177
|
+
var from=String(d.from||"").slice(0,10),to=String(d.to||"").slice(0,10);
|
|
3178
|
+
var days=(d.byDay||[]),max=1;
|
|
3179
|
+
days.forEach(function(x){max=Math.max(max,Number(x.credits)||0);});
|
|
3180
|
+
var bars=days.length?'<div class="sec-label" style="margin-top:14px">Credits per day</div><div style="display:flex;align-items:flex-end;gap:2px;height:48px">'
|
|
3181
|
+
+days.map(function(x){var c=Number(x.credits)||0;return '<span title="'+esc(String(x.day))+": "+c+' cr" style="flex:1;min-width:2px;background:var(--fg);opacity:'+(c?".6":".12")+';height:'+Math.max(2,Math.round(c/max*46))+'px"></span>';}).join("")+"</div>":"";
|
|
3182
|
+
var fails=(d.recentFailures||[]).map(function(f){
|
|
3183
|
+
return '<div style="padding:6px 0;border-top:1px solid var(--border);font-size:12.5px"><b>'+esc(f.tool||"")+"</b> "
|
|
3184
|
+
+'<span style="color:var(--muted)">'+esc(String(f.startedAt||"").slice(0,16).split("T").join(" "))+"</span>"
|
|
3185
|
+
+(f.error?'<div style="color:var(--muted);word-break:break-word">'+esc(f.error)+"</div>":"")+"</div>";
|
|
3186
|
+
}).join("");
|
|
3187
|
+
return '<div class="fade-in">'
|
|
3188
|
+
+'<div style="font-size:15px;font-weight:700">'+(d.scope==="workspace"?"Workspace usage":"Your usage")+"</div>"
|
|
3189
|
+
+'<div style="font-size:12px;color:var(--muted);margin:2px 0 12px">'+esc(from)+" → "+esc(to)+"</div>"
|
|
3190
|
+
+'<div style="display:flex;gap:8px;flex-wrap:wrap">'+tile("Credits",t.credits)+tile("Calls",t.calls)+tile("Failures",t.failures)
|
|
3191
|
+
+(d.scope==="workspace"?tile("Seats",t.seats):"")+"</div>"
|
|
3192
|
+
+table("By tool",["Tool","Calls","Failed","Credits"],(d.byTool||[]).map(function(r){return [r.tool,r.calls,r.failures,r.credits];}))
|
|
3193
|
+
+table("By seat",["Member","Calls","Failed","Credits"],(d.bySeat||[]).map(function(r){return [r.name||r.email||String(r.userId||"").slice(0,8),r.calls,r.failures,r.credits];}))
|
|
3194
|
+
+bars
|
|
3195
|
+
+(fails?'<div class="sec-label" style="margin-top:14px">Recent failures</div>'+fails:"")
|
|
3196
|
+
+"</div>";
|
|
3197
|
+
}
|
|
3198
|
+
|
|
3155
3199
|
// ─── Vetting strip ───
|
|
3156
3200
|
//
|
|
3157
3201
|
// Only show_collab_shortlist sends these fields, so every other creator card
|
|
@@ -4850,6 +4894,7 @@ export const NOOTICR_UI_TEMPLATE = `<!DOCTYPE html>
|
|
|
4850
4894
|
// Credits
|
|
4851
4895
|
if(d.gettingStarted===true){app.innerHTML=renderGettingStarted(d);setTimeout(reportSize,50);return;}
|
|
4852
4896
|
if(d.connector==="google_analytics"||d.connector==="search_console"||d.connector==="posthog"){app.innerHTML=renderConnector(d);setTimeout(reportSize,50);return;}
|
|
4897
|
+
if(d.report===true&&d.totals){app.innerHTML=renderUsageReport(d);setTimeout(reportSize,50);return;}
|
|
4853
4898
|
if(d.balance!=null||d.tier){
|
|
4854
4899
|
var bal=Number(d.balance)||0,tier=d.tier||"",ff=d.firstFreeTools||[];
|
|
4855
4900
|
var freeHtml="";
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nooticr/mcp",
|
|
3
3
|
"mcpName": "com.nooticr/mcp",
|
|
4
|
-
"version": "1.26.
|
|
4
|
+
"version": "1.26.47",
|
|
5
5
|
"description": "MCP server for nooticr - fetch, discover and understand TikTok/Instagram/YouTube/X/Reddit/LinkedIn/Weibo posts with AI (media metadata, niche discovery, brand monitoring, hook & viral analysis)",
|
|
6
6
|
"homepage": "https://mcp.nooticr.com",
|
|
7
7
|
"repository": {
|