@quidli/connect-mcp 0.5.8 → 0.6.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.
- package/README.md +73 -1
- package/dist/index-http.js +0 -0
- package/dist/index.js +0 -0
- package/dist/schemas.js +5 -5
- package/dist/tools/register.js +8 -3
- package/package.json +15 -13
package/README.md
CHANGED
|
@@ -153,6 +153,17 @@ Without a key, `initialize` / `tools/list` always succeed. Anonymous `tools/call
|
|
|
153
153
|
|
|
154
154
|
---
|
|
155
155
|
|
|
156
|
+
### Grok
|
|
157
|
+
|
|
158
|
+
1. Go to [grok.com/connectors](https://grok.com/connectors) and select **Custom**.
|
|
159
|
+
2. Enter the server URL: `https://mcp.connect.quid.li`
|
|
160
|
+
|
|
161
|
+
This gives Grok access to the anonymous-tier tools -- lookup, scores, agent, and price -- under the shared quota.
|
|
162
|
+
|
|
163
|
+
**Current limitation:** Grok's custom connector UI does not currently support attaching an API key or custom header. That means `connect_me`, `connect_drop`, and `connect_drop_balance` (all **API key only**) are not usable through Grok yet -- calls to them will return an unauthorized error. This isn't a `connect-mcp` limitation; it's Grok's custom-connector setup not exposing an auth field at this time.
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
156
167
|
## Smithery
|
|
157
168
|
|
|
158
169
|
If you already use [Smithery](https://smithery.ai/servers/quidli/connect), it will handle auth and sessions for you. Requires a Smithery account.
|
|
@@ -286,6 +297,67 @@ Credentials are optional in local mode. Without either variable, lookup/scores s
|
|
|
286
297
|
|
|
287
298
|
---
|
|
288
299
|
|
|
300
|
+
## Troubleshooting
|
|
301
|
+
|
|
302
|
+
### `npx` hangs with no output when run from a background service
|
|
303
|
+
|
|
304
|
+
If you're launching `@quidli/connect-mcp` via `npx` from inside a background
|
|
305
|
+
process manager -- a macOS `launchd` agent, a systemd unit, a supervisor, or
|
|
306
|
+
any client config running without a normal interactive shell -- it can hang
|
|
307
|
+
**indefinitely with zero output and no error**. This isn't a crash; `npx` is
|
|
308
|
+
stuck resolving `PATH` in an environment that doesn't provide the same shell
|
|
309
|
+
initialization an interactive terminal gets.
|
|
310
|
+
|
|
311
|
+
**Workaround:** if you have [Bun](https://bun.sh) installed, use `bunx`
|
|
312
|
+
instead of `npx`. It performs the same job -- running the package without a
|
|
313
|
+
local install -- but doesn't hit this hang in restricted-`PATH` environments.
|
|
314
|
+
|
|
315
|
+
```json
|
|
316
|
+
{
|
|
317
|
+
"mcpServers": {
|
|
318
|
+
"quidli-connect": {
|
|
319
|
+
"command": "bunx",
|
|
320
|
+
"args": ["-y", "@quidli/connect-mcp"],
|
|
321
|
+
"env": {
|
|
322
|
+
"CONNECT_API_KEY": "your-api-key"
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
If you're spawning the process yourself (rather than through a client's MCP
|
|
330
|
+
config) and want to be resilient to `bunx` not being on `PATH` either,
|
|
331
|
+
resolve it by absolute path first:
|
|
332
|
+
|
|
333
|
+
```ts
|
|
334
|
+
import { spawn } from "node:child_process";
|
|
335
|
+
import { existsSync } from "node:fs";
|
|
336
|
+
import { homedir } from "node:os";
|
|
337
|
+
import { join } from "node:path";
|
|
338
|
+
|
|
339
|
+
const BUNX_PATH = (() => {
|
|
340
|
+
const candidate = join(homedir(), ".bun", "bin", "bunx");
|
|
341
|
+
return existsSync(candidate) ? candidate : "bunx";
|
|
342
|
+
})();
|
|
343
|
+
|
|
344
|
+
const proc = spawn(BUNX_PATH, ["-y", "@quidli/connect-mcp"], {
|
|
345
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
346
|
+
});
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
This isn't a general claim that Bun is better than npm -- it's a targeted fix
|
|
350
|
+
for one specific, reproducible failure mode when `npx` is spawned outside an
|
|
351
|
+
interactive shell.
|
|
352
|
+
|
|
353
|
+
### Wrong environment variable name for the API key
|
|
354
|
+
|
|
355
|
+
Double-check you're setting `CONNECT_API_KEY`, not `API_KEY` -- the server
|
|
356
|
+
only reads `CONNECT_API_KEY`, and a mismatch here fails silently: your calls
|
|
357
|
+
will run in anonymous/unauthenticated mode instead of erroring, which can
|
|
358
|
+
look like a working-but-oddly-limited connection rather than a config
|
|
359
|
+
mistake.
|
|
360
|
+
|
|
289
361
|
## Tools
|
|
290
362
|
|
|
291
363
|
|
|
@@ -299,7 +371,7 @@ Credentials are optional in local mode. Without either variable, lookup/scores s
|
|
|
299
371
|
| `connect_scores_by_account` | Scores for one linked account |
|
|
300
372
|
| `connect_scores_by_username` | Scores by Connect username |
|
|
301
373
|
| `connect_me` | API key owner profile, scores, and linked accounts — **API key only** |
|
|
302
|
-
| `connect_drop` | Smart Send (batch
|
|
374
|
+
| `connect_drop` | Smart Send (EVM batch or Solana SOL/SPL) — **API key only** |
|
|
303
375
|
| `connect_drop_balance` | Smart Send wallet balances on a chain — **API key only** |
|
|
304
376
|
|
|
305
377
|
|
package/dist/index-http.js
CHANGED
|
File without changes
|
package/dist/index.js
CHANGED
|
File without changes
|
package/dist/schemas.js
CHANGED
|
@@ -83,25 +83,25 @@ export const scoresByUsernameInputSchema = {
|
|
|
83
83
|
username: z.string().min(1),
|
|
84
84
|
};
|
|
85
85
|
export const dropBalanceInputSchema = {
|
|
86
|
-
chainId: z.number().int().describe('EVM chain ID (Smart Send
|
|
86
|
+
chainId: z.number().int().describe('EVM chain ID or 1399811149 for Solana mainnet (Smart Send)'),
|
|
87
87
|
};
|
|
88
88
|
export const dropInputSchema = {
|
|
89
89
|
idempotencyKey: z.string().uuid(),
|
|
90
|
-
chainId: z.number().int().describe('EVM chain ID
|
|
90
|
+
chainId: z.number().int().describe('EVM chain ID or 1399811149 for Solana mainnet'),
|
|
91
91
|
tokenContract: z
|
|
92
92
|
.string()
|
|
93
93
|
.nullable()
|
|
94
94
|
.optional()
|
|
95
|
-
.describe('ERC-20 contract
|
|
95
|
+
.describe('EVM ERC-20 contract or Solana SPL mint. Omit or null for the native token (ETH/POL/AVAX, or SOL on 1399811149). Do not use the zero address.'),
|
|
96
96
|
recipients: z
|
|
97
97
|
.array(linkedAccountSchema)
|
|
98
98
|
.min(1)
|
|
99
|
-
.describe('Wallet or social recipients (all wallet or all social, no mix). Optional amountInWei per recipient uses the same smallest-unit rules as amountInWeiPerRecipient.'),
|
|
99
|
+
.describe('Wallet or social recipients (all wallet or all social, no mix). Optional amountInWei per recipient uses the same smallest-unit rules as amountInWeiPerRecipient. On Solana, wallet ids are base58 pubkeys; social lookup pays solWalletAddress.'),
|
|
100
100
|
amountInWeiPerRecipient: z
|
|
101
101
|
.string()
|
|
102
102
|
.optional()
|
|
103
103
|
.nullable()
|
|
104
|
-
.describe('Uniform amount in smallest units
|
|
104
|
+
.describe('Uniform amount in smallest units. Native ETH uses 18 decimals; SOL uses 9; ERC-20/SPL uses token decimals from connect_drop_balance (USDC usually 6). Omit when setting amountInWei on each recipient.'),
|
|
105
105
|
ignoreFailedRecipients: z
|
|
106
106
|
.boolean()
|
|
107
107
|
.optional()
|
package/dist/tools/register.js
CHANGED
|
@@ -31,7 +31,7 @@ const SPENDS_FUNDS = {
|
|
|
31
31
|
};
|
|
32
32
|
export function registerTools(server, client) {
|
|
33
33
|
server.tool('connect_get_price', 'Get public x402 list prices for lookup and scores (reference only; live paywall amounts are in 402 responses).', {}, READ_ONLY, async () => client.request({ method: 'GET', path: '/price', authenticated: false }));
|
|
34
|
-
server.tool('connect_get_chains', 'List product chains with per-feature compatibility. lookup is true for EVM catalog chains and Solana; drop is true
|
|
34
|
+
server.tool('connect_get_chains', 'List product chains with per-feature compatibility. lookup is true for EVM catalog chains and Solana; drop is true for Smart Send EVM chains and Solana (chainId 1399811149 for connect_drop / connect_drop_balance).', {}, READ_ONLY, async () => client.request({ method: 'GET', path: '/chains', authenticated: false }));
|
|
35
35
|
server.tool('connect_lookup', 'Resolve social identities to EVM and Solana wallet addresses. Resolving a recipient who has no wallet provisions one for them, so this is read-only for the caller but not for the recipient. If status is processing, retry the same payload.', lookupInputSchema, READ_ONLY, async ({ recipients }) => client.request({
|
|
36
36
|
method: 'POST',
|
|
37
37
|
path: '/lookup',
|
|
@@ -59,7 +59,10 @@ export function registerTools(server, client) {
|
|
|
59
59
|
method: 'GET',
|
|
60
60
|
path: '/account/me',
|
|
61
61
|
}));
|
|
62
|
-
server.tool('connect_drop', 'Execute a Smart Send
|
|
62
|
+
server.tool('connect_drop', 'Execute a Smart Send from the API key owner Connect embedded wallet. EVM: batch native or ERC-20 (need native gas plus the token). Solana (chainId 1399811149): SOL or SPL from the Solana embedded wallet. Lookup social recipients and pay solWalletAddress, never ethWalletAddress. Omit tokenContract or set it to null for the native token; pass an ERC-20 contract or SPL mint otherwise — do not use the zero address. Amounts are smallest-unit integer strings (ETH 18 decimals, SOL 9, USDC usually 6). Packs up to 20 SOL or 10 SPL recipients per transaction. ' +
|
|
63
|
+
'Solana native (tokenContract null): no ATA. Sending to a new or empty wallet requires amount ≥ 890880 lamports (rent-exempt minimum for a system account); that SOL stays with the recipient. Below that the tx fails. Sender also pays a ~5000-lamport fee. ' +
|
|
64
|
+
'Solana SPL: tokens sit in Associated Token Accounts (ATA), not on the wallet pubkey. Recipients need not already hold the token — the API prepends CreateIdempotent. The sender (not the recipient) pays ~2039280 lamports (~0.002039 SOL) rent per newly created dest ATA, plus tx fees, on top of the token amount (which can be as small as 1 unit). A 400 "Insufficient funds" on SPL is often missing SOL for ATA rent, not missing USDC. Token-2022 is not supported; USDC mint is EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v. ' +
|
|
65
|
+
'Always call connect_drop_balance first. Returns 201 when submitted or 202 when recipients still processing — retry with the same idempotencyKey.', dropInputSchema, SPENDS_FUNDS, async ({ ignoreFailedRecipients, ...body }) => client.request({
|
|
63
66
|
method: 'POST',
|
|
64
67
|
path: '/drop',
|
|
65
68
|
body,
|
|
@@ -68,7 +71,9 @@ export function registerTools(server, client) {
|
|
|
68
71
|
? { ignoreFailedRecipients: 'true' }
|
|
69
72
|
: undefined,
|
|
70
73
|
}));
|
|
71
|
-
server.tool('connect_drop_balance', 'Get native and
|
|
74
|
+
server.tool('connect_drop_balance', 'Get native and token balances for the API key owner Smart Send embedded wallet on a chain. Always call before connect_drop. Zero balances are omitted, so a missing token means balance 0. ' +
|
|
75
|
+
'EVM: confirm native gas plus the ERC-20 being sent. ' +
|
|
76
|
+
'Solana (chainId 1399811149): SOL in this response is spendable lamports on the wallet pubkey (rent locked in existing token accounts is not included). Native SOL drop to a new/empty recipient: amount itself must be ≥ 890880 lamports and sender SOL must cover amount + ~5000 lamports fee. SPL drop: token balance ≥ total amount, and SOL ≥ tx fee + ~2039280 lamports (~0.002039 SOL) per recipient that may need a new Associated Token Account — even when sending USDC. Insufficient SOL for ATA rent fails before the token transfer.', dropBalanceInputSchema, READ_ONLY, async ({ chainId }) => client.request({
|
|
72
77
|
method: 'GET',
|
|
73
78
|
path: '/drop/balance',
|
|
74
79
|
requireApiKey: true,
|
package/package.json
CHANGED
|
@@ -1,28 +1,30 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quidli/connect-mcp",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.6.0",
|
|
4
|
+
"description": "MCP server for agent identity and reputation: resolve social handles to wallet addresses, score onchain reputation, and send USDC from any MCP client.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mcp",
|
|
7
7
|
"mcp-server",
|
|
8
8
|
"model-context-protocol",
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"web3-agent",
|
|
12
|
-
"agent-payments",
|
|
13
|
-
"multiplayer-agents",
|
|
9
|
+
"reputation",
|
|
10
|
+
"onchain-reputation",
|
|
14
11
|
"identity",
|
|
15
12
|
"identity-resolution",
|
|
16
|
-
"reputation",
|
|
17
|
-
"payments",
|
|
18
13
|
"wallet",
|
|
14
|
+
"wallet-lookup",
|
|
15
|
+
"agent",
|
|
16
|
+
"ai",
|
|
17
|
+
"agent-payments",
|
|
18
|
+
"payments",
|
|
19
19
|
"usdc",
|
|
20
|
-
"
|
|
20
|
+
"crypto",
|
|
21
|
+
"web3-agent",
|
|
22
|
+
"multiplayer-agents",
|
|
21
23
|
"x402",
|
|
22
24
|
"ethereum",
|
|
23
25
|
"solana",
|
|
24
26
|
"base",
|
|
25
|
-
"
|
|
27
|
+
"farcaster",
|
|
26
28
|
"claude",
|
|
27
29
|
"cursor",
|
|
28
30
|
"claude-desktop"
|
|
@@ -53,8 +55,8 @@
|
|
|
53
55
|
"./http": "./dist/http.js"
|
|
54
56
|
},
|
|
55
57
|
"scripts": {
|
|
56
|
-
"build": "tsc",
|
|
57
|
-
"prepublishOnly": "npm run build
|
|
58
|
+
"build": "tsc && chmod +x dist/index.js dist/index-http.js",
|
|
59
|
+
"prepublishOnly": "npm run build",
|
|
58
60
|
"start": "node dist/index.js",
|
|
59
61
|
"start:http": "node dist/index-http.js",
|
|
60
62
|
"test": "vitest run",
|