@blockrun/mcp 0.2.2 → 0.3.0

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.
Files changed (3) hide show
  1. package/README.md +28 -2
  2. package/dist/index.js +221 -1
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -122,11 +122,34 @@ blockrun list models
122
122
  blockrun show OpenAI models with pricing
123
123
  ```
124
124
 
125
- ### Wallet Management
125
+ ### Real-Time X/Twitter Search
126
+
127
+ Get live data from X/Twitter using Grok's real-time search:
128
+
129
+ ```
130
+ blockrun twitter: what is @elonmusk posting about today
131
+
132
+ blockrun twitter: trending AI news
133
+
134
+ blockrun twitter: reactions to [recent event]
135
+ ```
136
+
137
+ ### Wallet & Balance
126
138
 
127
139
  ```
128
140
  blockrun setup # First-time setup instructions
129
141
  blockrun wallet # Check your wallet address
142
+ blockrun balance # Check on-chain USDC balance
143
+ ```
144
+
145
+ ### Budget Management
146
+
147
+ Control your session spending:
148
+
149
+ ```
150
+ blockrun budget check # View current spending
151
+ blockrun budget set $1.00 # Set $1.00 limit
152
+ blockrun budget clear # Remove limit
130
153
  ```
131
154
 
132
155
  ## Supported Models & Pricing
@@ -259,7 +282,10 @@ The MCP couldn't find or create a wallet. Check that `~/.blockrun/` directory is
259
282
  Some models have rate limits. Try `blockrun smart cheap` or `blockrun smart fast` to use alternative models.
260
283
 
261
284
  ### Check wallet balance
262
- Say `blockrun wallet` or visit: `https://basescan.org/address/YOUR_ADDRESS`
285
+ Say `blockrun balance` to check your on-chain USDC balance, or visit: `https://basescan.org/address/YOUR_ADDRESS`
286
+
287
+ ### Budget limit reached
288
+ If you've set a session budget and hit the limit, use `blockrun budget clear` to remove it or `blockrun budget set $X` to increase it.
263
289
 
264
290
  ## Configuration
265
291
 
package/dist/index.js CHANGED
@@ -22,6 +22,13 @@ var walletWasCreated = false;
22
22
  var walletAddress = null;
23
23
  var client = null;
24
24
  var cachedModels = null;
25
+ var sessionBudget = { limit: null, spent: 0, calls: 0 };
26
+ var USDC_ADDRESS = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
27
+ var BASE_RPC_URLS = [
28
+ "https://mainnet.base.org",
29
+ "https://base.llamarpc.com",
30
+ "https://1rpc.io/base"
31
+ ];
25
32
  function getOrCreateWalletKey() {
26
33
  const envKey = process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY;
27
34
  if (envKey) {
@@ -130,9 +137,47 @@ SECURITY NOTE:
130
137
  ================================================================================
131
138
  `;
132
139
  }
140
+ async function getUsdcBalance(address) {
141
+ const data = {
142
+ jsonrpc: "2.0",
143
+ method: "eth_call",
144
+ params: [{
145
+ to: USDC_ADDRESS,
146
+ data: `0x70a08231000000000000000000000000${address.slice(2)}`
147
+ }, "latest"],
148
+ id: 1
149
+ };
150
+ for (const rpcUrl of BASE_RPC_URLS) {
151
+ try {
152
+ const response = await fetch(rpcUrl, {
153
+ method: "POST",
154
+ headers: { "Content-Type": "application/json" },
155
+ body: JSON.stringify(data)
156
+ });
157
+ const result = await response.json();
158
+ if (result.result) {
159
+ return parseInt(result.result, 16) / 1e6;
160
+ }
161
+ } catch {
162
+ continue;
163
+ }
164
+ }
165
+ return null;
166
+ }
167
+ function recordSpending(cost) {
168
+ sessionBudget.spent += cost;
169
+ sessionBudget.calls += 1;
170
+ }
171
+ function checkBudget() {
172
+ if (sessionBudget.limit === null) {
173
+ return { allowed: true, remaining: null };
174
+ }
175
+ const remaining = sessionBudget.limit - sessionBudget.spent;
176
+ return { allowed: remaining > 0, remaining };
177
+ }
133
178
  var server = new McpServer({
134
179
  name: "blockrun-mcp",
135
- version: "0.2.0"
180
+ version: "0.3.0"
136
181
  });
137
182
  server.registerTool(
138
183
  "blockrun_chat",
@@ -433,6 +478,181 @@ Returns:
433
478
  return { content: [{ type: "text", text: getWalletSetupInstructions() }] };
434
479
  }
435
480
  );
481
+ server.registerTool(
482
+ "blockrun_twitter",
483
+ {
484
+ description: `Search real-time X/Twitter data using Grok's live search.
485
+
486
+ Use this tool for:
487
+ - Checking what people are saying about a topic
488
+ - Finding recent tweets from specific accounts
489
+ - Getting trending discussions
490
+ - Real-time news and events
491
+
492
+ Example queries:
493
+ - "what is @elonmusk posting about today"
494
+ - "trending AI news"
495
+ - "reactions to [event]"`,
496
+ inputSchema: {
497
+ query: z.string().describe("Search query - can include @handles, topics, or natural language questions"),
498
+ max_results: z.number().optional().default(10).describe("Maximum number of results to return (1-25)")
499
+ },
500
+ outputSchema: {
501
+ query: z.string(),
502
+ model: z.string(),
503
+ response: z.string()
504
+ }
505
+ },
506
+ async ({ query, max_results }) => {
507
+ const budget = checkBudget();
508
+ if (!budget.allowed) {
509
+ return {
510
+ content: [{ type: "text", text: `Budget limit reached. Spent $${sessionBudget.spent.toFixed(4)} of $${sessionBudget.limit?.toFixed(2)} limit.
511
+
512
+ Use blockrun_budget to check or adjust your budget.` }],
513
+ isError: true
514
+ };
515
+ }
516
+ try {
517
+ const llm = getClient();
518
+ const model = "xai/grok-3";
519
+ const system = `You are a real-time X/Twitter search assistant.
520
+ When searching, focus on:
521
+ - Recent and relevant posts
522
+ - Key accounts and verified sources
523
+ - Engagement metrics when relevant
524
+ Format your response clearly with sources when available.
525
+ Max results requested: ${max_results}`;
526
+ const response = await llm.chat(model, query, {
527
+ system,
528
+ search: true
529
+ });
530
+ recordSpending(2e-3);
531
+ return {
532
+ content: [{ type: "text", text: `[X/Twitter Search via Grok]
533
+
534
+ ${response}` }],
535
+ structuredContent: { query, model, response }
536
+ };
537
+ } catch (error) {
538
+ const errorMessage = error instanceof Error ? error.message : String(error);
539
+ return {
540
+ content: [{ type: "text", text: formatError(errorMessage) }],
541
+ isError: true
542
+ };
543
+ }
544
+ }
545
+ );
546
+ server.registerTool(
547
+ "blockrun_balance",
548
+ {
549
+ description: `Check your on-chain USDC balance on Base network.
550
+
551
+ Returns:
552
+ - Current USDC balance
553
+ - Wallet address
554
+ - Link to view on Basescan
555
+
556
+ Use this to see how much funding you have available for BlockRun API calls.`,
557
+ inputSchema: {},
558
+ outputSchema: {
559
+ address: z.string(),
560
+ balance: z.number().nullable(),
561
+ network: z.string(),
562
+ basescanUrl: z.string()
563
+ }
564
+ },
565
+ async () => {
566
+ const llm = getClient();
567
+ const address = llm.getWalletAddress();
568
+ const balance = await getUsdcBalance(address);
569
+ const balanceStr = balance !== null ? `$${balance.toFixed(6)} USDC` : "Unable to fetch (try again)";
570
+ const text = `BlockRun Wallet Balance
571
+ =======================
572
+
573
+ Address: ${address}
574
+ Balance: ${balanceStr}
575
+ Network: Base (Chain ID: 8453)
576
+
577
+ View on Basescan: https://basescan.org/address/${address}
578
+
579
+ ${balance !== null && balance < 1 ? "\u26A0\uFE0F Low balance. Consider adding funds to continue using BlockRun." : ""}`;
580
+ return {
581
+ content: [{ type: "text", text }],
582
+ structuredContent: {
583
+ address,
584
+ balance,
585
+ network: "Base",
586
+ basescanUrl: `https://basescan.org/address/${address}`
587
+ }
588
+ };
589
+ }
590
+ );
591
+ server.registerTool(
592
+ "blockrun_budget",
593
+ {
594
+ description: `Manage your session spending budget.
595
+
596
+ Actions:
597
+ - check: View current spending and budget status
598
+ - set: Set a spending limit (e.g., $1.00)
599
+ - clear: Remove spending limit (unlimited)
600
+
601
+ Use this to control how much you spend per session on BlockRun API calls.`,
602
+ inputSchema: {
603
+ action: z.enum(["check", "set", "clear"]).describe("Budget action to perform"),
604
+ amount: z.number().optional().describe("Budget limit in USD (required for 'set' action)")
605
+ },
606
+ outputSchema: {
607
+ limit: z.number().nullable(),
608
+ spent: z.number(),
609
+ calls: z.number(),
610
+ remaining: z.number().nullable()
611
+ }
612
+ },
613
+ async ({ action, amount }) => {
614
+ switch (action) {
615
+ case "set":
616
+ if (amount === void 0 || amount <= 0) {
617
+ return {
618
+ content: [{ type: "text", text: "Error: Please provide a positive amount for the budget limit (e.g., amount: 1.00 for $1.00)" }],
619
+ isError: true
620
+ };
621
+ }
622
+ sessionBudget.limit = amount;
623
+ break;
624
+ case "clear":
625
+ sessionBudget.limit = null;
626
+ break;
627
+ case "check":
628
+ default:
629
+ break;
630
+ }
631
+ const remaining = sessionBudget.limit !== null ? sessionBudget.limit - sessionBudget.spent : null;
632
+ const limitStr = sessionBudget.limit !== null ? `$${sessionBudget.limit.toFixed(2)}` : "Unlimited";
633
+ const remainingStr = remaining !== null ? `$${remaining.toFixed(4)}` : "N/A";
634
+ const text = `BlockRun Session Budget
635
+ =======================
636
+
637
+ Limit: ${limitStr}
638
+ Spent: $${sessionBudget.spent.toFixed(4)}
639
+ Calls: ${sessionBudget.calls}
640
+ Remaining: ${remainingStr}
641
+
642
+ ${action === "set" ? `\u2705 Budget set to $${amount?.toFixed(2)}` : ""}
643
+ ${action === "clear" ? "\u2705 Budget limit removed (unlimited spending)" : ""}
644
+ ${remaining !== null && remaining < 0.01 ? "\u26A0\uFE0F Budget nearly exhausted!" : ""}`;
645
+ return {
646
+ content: [{ type: "text", text }],
647
+ structuredContent: {
648
+ limit: sessionBudget.limit,
649
+ spent: sessionBudget.spent,
650
+ calls: sessionBudget.calls,
651
+ remaining
652
+ }
653
+ };
654
+ }
655
+ );
436
656
  server.registerResource(
437
657
  "wallet",
438
658
  "blockrun://wallet",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blockrun/mcp",
3
- "version": "0.2.2",
3
+ "version": "0.3.0",
4
4
  "mcpName": "io.github.BlockRunAI/blockrun-mcp",
5
5
  "description": "BlockRun MCP Server - Access 30+ AI models via x402 micropayments. No API keys needed.",
6
6
  "type": "module",