@quidli/connect-mcp 0.5.5 → 0.5.7

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 CHANGED
@@ -1,6 +1,12 @@
1
1
  # Quidli Connect MCP
2
2
 
3
- Identity and reputation for agents. Resolve a social handle to a wallet, check reputation, and send tokens — from Cursor, Claude Desktop, Claude Code, or any MCP-compatible client.
3
+ [![npm version](https://img.shields.io/npm/v/@quidli/connect-mcp.svg)](https://www.npmjs.com/package/@quidli/connect-mcp)
4
+ [![npm downloads](https://img.shields.io/npm/dw/@quidli/connect-mcp.svg)](https://www.npmjs.com/package/@quidli/connect-mcp)
5
+ [![license](https://img.shields.io/npm/l/@quidli/connect-mcp.svg)](./LICENSE)
6
+
7
+ Open payments for multiplayer agents, powered by social reputation. Resolve a social handle to a wallet, check reputation, and send tokens — from Cursor, Claude Desktop, Claude Code, or any MCP-compatible client.
8
+
9
+ Multiplayer means parties who don't already know each other — an agent paying a person, or another agent, with no prior relationship and no account to fall back on. Connect is how it verifies who it's dealing with before sending anything.
4
10
 
5
11
  Public repository: [github.com/Quidli/connect-mcp](https://github.com/Quidli/connect-mcp)
6
12
 
@@ -46,7 +52,7 @@ Then ask your agent:
46
52
 
47
53
  Resolves across Telegram, Discord, Farcaster, X, GitHub, LinkedIn, email and phone — and generates a wallet for people who have never used Quidli.
48
54
 
49
- Lookup, scores, agent and price run without a key under a shared anonymous quota. Add a [Connect API key](https://connect.quid.li) for higher limits, your own profile (`connect_me`), and Smart Send.
55
+ Lookup, scores, and price run without a key under a shared anonymous quota. Add a [Connect API key](https://connect.quid.li) for higher limits, your own profile (`connect_me`), and Smart Send.
50
56
 
51
57
  ---
52
58
 
@@ -56,7 +62,7 @@ Lookup, scores, agent and price run without a key under a shared anonymous quota
56
62
  | | **Hosted** (`mcp.connect.quid.li`) | **Local** (`npx @quidli/connect-mcp`) |
57
63
  | --------------- | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ |
58
64
  | **Setup** | Add a URL in MCP settings | Run a local process via `npx` |
59
- | **Auth** | Optional API key. Without a key: lookup/scores/agent/price under a shared anonymous quota | API key, x402 pay-per-call, or none for lookup/scores/agent |
65
+ | **Auth** | Optional API key. Without a key: lookup/scores under a shared anonymous quota; price/chains are public | API key, x402 pay-per-call, or none for lookup/scores |
60
66
  | **Pros** | No install; try without a key; always on Quidli infrastructure | Wallet private key never leaves your machine; pay per call with USDC instead of an API key |
61
67
  | **Cons** | Anonymous traffic shares a global rate limit; no pay-per-call billing | Requires Node.js 20+; `npx` may download the package on first run |
62
68
  | **Limitations** | Cannot use x402 / wallet auth — do **not** send a private key to the hosted endpoint | x402 mode needs USDC on Base (mainnet `8453`); `connect_drop` requires an API key |
@@ -209,9 +215,9 @@ No API key. Authenticated calls pay automatically when the API returns HTTP 402.
209
215
 
210
216
  Use `84532` for Base Sepolia when pointing at a staging API.
211
217
 
212
- #### Option C — no credentials (lookup / scores / agent)
218
+ #### Option C — no credentials (lookup / scores)
213
219
 
214
- The MCP process starts without `CONNECT_API_KEY` or `EVM_PRIVATE_KEY`. `connect_lookup`, `connect_scores_*`, `connect_agent_prompt`, and `connect_get_price` call the API without auth. That succeeds when x402 is disabled (price `0`, typical for local). On production with x402 enabled, those tools return HTTP 402 until you set a key or wallet.
220
+ The MCP process starts without `CONNECT_API_KEY` or `EVM_PRIVATE_KEY`. `connect_lookup`, `connect_scores_*`, `connect_get_price`, and `connect_get_chains` call the API without auth. That succeeds when x402 is disabled (price `0`, typical for local). On production with x402 enabled, those tools return HTTP 402 until you set a key or wallet.
215
221
 
216
222
  `connect_me`, `connect_drop`, and `connect_drop_balance` still require `CONNECT_API_KEY`.
217
223
 
@@ -276,7 +282,7 @@ The MCP process starts without `CONNECT_API_KEY` or `EVM_PRIVATE_KEY`. `connect_
276
282
 
277
283
  If both `CONNECT_API_KEY` and `EVM_PRIVATE_KEY` are set, the API key is used.
278
284
 
279
- Credentials are optional in local mode. Without either variable, lookup/scores/agent still work when the API does not charge x402. `connect_me` and Smart Send tools require `CONNECT_API_KEY`.
285
+ Credentials are optional in local mode. Without either variable, lookup/scores still work when the API does not charge x402. `connect_me` and Smart Send tools require `CONNECT_API_KEY`.
280
286
 
281
287
  ---
282
288
 
@@ -286,6 +292,7 @@ Credentials are optional in local mode. Without either variable, lookup/scores/a
286
292
  | Tool | What it does |
287
293
  | ---------------------------- | --------------------------------------------------------- |
288
294
  | `connect_get_price` | List reference prices (no auth) |
295
+ | `connect_get_chains` | List supported chains and feature compatibility (no auth) |
289
296
  | `connect_lookup` | Resolve social identities to EVM and SOL wallet addresses |
290
297
  | `connect_lookup_exposed` | List platforms a recipient has exposed on Connect |
291
298
  | `connect_scores_batch` | Batch scores for accounts or usernames |
@@ -294,7 +301,6 @@ Credentials are optional in local mode. Without either variable, lookup/scores/a
294
301
  | `connect_me` | API key owner profile, scores, and linked accounts — **API key only** |
295
302
  | `connect_drop` | Smart Send (batch token transfer) — **API key only** |
296
303
  | `connect_drop_balance` | Smart Send wallet balances on a chain — **API key only** |
297
- | `connect_agent_prompt` | Natural-language agent for recipients discovery |
298
304
 
299
305
 
300
306
  Ask your client to use these tools when you need Connect data or actions.
@@ -1,5 +1,5 @@
1
1
  import { getJsonRpcMethod, getJsonRpcToolName } from './jsonrpc.js';
2
- export const ANON_QUOTA_EXEMPT_TOOLS = new Set(['connect_get_price']);
2
+ export const ANON_QUOTA_EXEMPT_TOOLS = new Set(['connect_get_price', 'connect_get_chains']);
3
3
  export const ANON_AGENT_TOOL = 'connect_agent_prompt';
4
4
  const GLOBAL_QUOTA_MESSAGE = 'Anonymous MCP quota exceeded. Get a Connect API key at https://connect.quid.li (Enable API access) for higher limits.';
5
5
  const AGENT_QUOTA_MESSAGE = 'Anonymous MCP agent quota exceeded. Get a Connect API key at https://connect.quid.li (Enable API access) for higher limits.';
package/dist/config.d.ts CHANGED
@@ -15,7 +15,7 @@ export interface HttpServerConfig {
15
15
  export declare function loadHttpServerConfig(env?: NodeJS.ProcessEnv): HttpServerConfig;
16
16
  /**
17
17
  * Stdio MCP: credentials are optional.
18
- * Lookup/scores/agent work without auth when the API allows it (x402 price 0)
18
+ * Lookup/scores work without auth when the API allows it (x402 price 0)
19
19
  * or with CONNECT_API_KEY / EVM_PRIVATE_KEY. /account/me and /drop require an API key.
20
20
  */
21
21
  export declare function loadConfig(env?: NodeJS.ProcessEnv): ConnectClientConfig;
package/dist/config.js CHANGED
@@ -25,7 +25,7 @@ export function loadHttpServerConfig(env = process.env) {
25
25
  }
26
26
  /**
27
27
  * Stdio MCP: credentials are optional.
28
- * Lookup/scores/agent work without auth when the API allows it (x402 price 0)
28
+ * Lookup/scores work without auth when the API allows it (x402 price 0)
29
29
  * or with CONNECT_API_KEY / EVM_PRIVATE_KEY. /account/me and /drop require an API key.
30
30
  */
31
31
  export function loadConfig(env = process.env) {
package/dist/schemas.d.ts CHANGED
@@ -15,15 +15,15 @@ export declare const linkedAccountSchema: z.ZodObject<{
15
15
  }, z.ZodTypeAny, "passthrough">>;
16
16
  export declare const lookupInputSchema: {
17
17
  recipients: z.ZodArray<z.ZodObject<{
18
- type: z.ZodEnum<["email", "phone", "telegram", "discord", "farcaster", "twitter", "github", "linkedin", "slack", "wallet", "username"]>;
18
+ type: z.ZodEnum<["email", "phone", "telegram", "discord", "farcaster", "twitter", "github", "linkedin", "slack"]>;
19
19
  id: z.ZodOptional<z.ZodString>;
20
20
  username: z.ZodOptional<z.ZodString>;
21
21
  }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
22
- type: z.ZodEnum<["email", "phone", "telegram", "discord", "farcaster", "twitter", "github", "linkedin", "slack", "wallet", "username"]>;
22
+ type: z.ZodEnum<["email", "phone", "telegram", "discord", "farcaster", "twitter", "github", "linkedin", "slack"]>;
23
23
  id: z.ZodOptional<z.ZodString>;
24
24
  username: z.ZodOptional<z.ZodString>;
25
25
  }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
26
- type: z.ZodEnum<["email", "phone", "telegram", "discord", "farcaster", "twitter", "github", "linkedin", "slack", "wallet", "username"]>;
26
+ type: z.ZodEnum<["email", "phone", "telegram", "discord", "farcaster", "twitter", "github", "linkedin", "slack"]>;
27
27
  id: z.ZodOptional<z.ZodString>;
28
28
  username: z.ZodOptional<z.ZodString>;
29
29
  }, z.ZodTypeAny, "passthrough">>, "many">;
@@ -98,7 +98,3 @@ export declare const dropInputSchema: {
98
98
  amountInWeiPerRecipient: z.ZodNullable<z.ZodOptional<z.ZodString>>;
99
99
  ignoreFailedRecipients: z.ZodOptional<z.ZodBoolean>;
100
100
  };
101
- export declare const agentPromptInputSchema: {
102
- prompt: z.ZodString;
103
- sessionId: z.ZodOptional<z.ZodString>;
104
- };
package/dist/schemas.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- const recipientTypeSchema = z.enum([
2
+ const lookupSocialTypeSchema = z.enum([
3
3
  'email',
4
4
  'phone',
5
5
  'telegram',
@@ -9,9 +9,13 @@ const recipientTypeSchema = z.enum([
9
9
  'github',
10
10
  'linkedin',
11
11
  'slack',
12
+ ]);
13
+ const recipientTypeSchema = z.enum([
14
+ ...lookupSocialTypeSchema.options,
12
15
  'wallet',
13
16
  'username',
14
17
  ]);
18
+ const exposureRecipientTypeSchema = recipientTypeSchema;
15
19
  /** Unified recipient — API validates fully; MCP forwards JSON. */
16
20
  export const linkedAccountSchema = z
17
21
  .object({
@@ -20,14 +24,28 @@ export const linkedAccountSchema = z
20
24
  username: z.string().optional(),
21
25
  })
22
26
  .passthrough();
27
+ const lookupRecipientSchema = z
28
+ .object({
29
+ type: lookupSocialTypeSchema,
30
+ id: z.string().optional(),
31
+ username: z.string().optional(),
32
+ })
33
+ .passthrough();
34
+ const exposureRecipientSchema = z
35
+ .object({
36
+ type: exposureRecipientTypeSchema,
37
+ id: z.string().optional(),
38
+ username: z.string().optional(),
39
+ })
40
+ .passthrough();
23
41
  export const lookupInputSchema = {
24
42
  recipients: z
25
- .array(linkedAccountSchema)
43
+ .array(lookupRecipientSchema)
26
44
  .min(1)
27
45
  .describe('Recipients to resolve to EVM/Solana wallets'),
28
46
  };
29
47
  export const lookupExposedInputSchema = {
30
- recipient: linkedAccountSchema.describe('Recipient whose exposed linked accounts and Connect profile should be listed'),
48
+ recipient: exposureRecipientSchema.describe('Social identity, exposed wallet (EVM/Solana/smart wallet), or Connect username whose exposed linked accounts and Connect profile should be listed'),
31
49
  };
32
50
  export const scoresBatchInputSchema = {
33
51
  users: z.array(linkedAccountSchema).min(1).describe('Users to fetch scores for'),
@@ -69,13 +87,23 @@ export const dropBalanceInputSchema = {
69
87
  };
70
88
  export const dropInputSchema = {
71
89
  idempotencyKey: z.string().uuid(),
72
- chainId: z.number().int(),
73
- tokenContract: z.string().nullable().optional(),
74
- recipients: z.array(linkedAccountSchema).min(1),
75
- amountInWeiPerRecipient: z.string().optional().nullable(),
76
- ignoreFailedRecipients: z.boolean().optional(),
77
- };
78
- export const agentPromptInputSchema = {
79
- prompt: z.string().min(1).max(4000),
80
- sessionId: z.string().uuid().optional(),
90
+ chainId: z.number().int().describe('EVM chain ID (Smart Send supported chains only)'),
91
+ tokenContract: z
92
+ .string()
93
+ .nullable()
94
+ .optional()
95
+ .describe('ERC-20 contract address. Omit or null for the chain native token (ETH, POL, AVAX). Do not use the zero address.'),
96
+ recipients: z
97
+ .array(linkedAccountSchema)
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.'),
100
+ amountInWeiPerRecipient: z
101
+ .string()
102
+ .optional()
103
+ .nullable()
104
+ .describe('Uniform amount in smallest units (wei). Native ETH uses 18 decimals; ERC-20 uses token decimals from connect_drop_balance (USDC usually 6). Omit when setting amountInWei on each recipient.'),
105
+ ignoreFailedRecipients: z
106
+ .boolean()
107
+ .optional()
108
+ .describe('When true, send to recipients that resolved successfully and skip failed lookups.'),
81
109
  };
@@ -1,4 +1,4 @@
1
1
  import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import type { ConnectClient } from '../client.js';
3
- export declare const CONNECT_MCP_TOOL_NAMES: readonly ["connect_get_price", "connect_lookup", "connect_lookup_exposed", "connect_scores_batch", "connect_scores_by_account", "connect_scores_by_username", "connect_me", "connect_drop", "connect_drop_balance", "connect_agent_prompt"];
3
+ export declare const CONNECT_MCP_TOOL_NAMES: readonly ["connect_get_price", "connect_get_chains", "connect_lookup", "connect_lookup_exposed", "connect_scores_batch", "connect_scores_by_account", "connect_scores_by_username", "connect_me", "connect_drop", "connect_drop_balance"];
4
4
  export declare function registerTools(server: McpServer, client: ConnectClient): void;
@@ -1,7 +1,7 @@
1
- import { agentPromptInputSchema, dropBalanceInputSchema, dropInputSchema, lookupExposedInputSchema, lookupInputSchema, scoresBatchInputSchema, scoresByAccountInputSchema, scoresByUsernameInputSchema, } from '../schemas.js';
2
- const AGENT_TIMEOUT_MS = 65_000;
1
+ import { dropBalanceInputSchema, dropInputSchema, lookupExposedInputSchema, lookupInputSchema, scoresBatchInputSchema, scoresByAccountInputSchema, scoresByUsernameInputSchema, } from '../schemas.js';
3
2
  export const CONNECT_MCP_TOOL_NAMES = [
4
3
  'connect_get_price',
4
+ 'connect_get_chains',
5
5
  'connect_lookup',
6
6
  'connect_lookup_exposed',
7
7
  'connect_scores_batch',
@@ -10,16 +10,16 @@ export const CONNECT_MCP_TOOL_NAMES = [
10
10
  'connect_me',
11
11
  'connect_drop',
12
12
  'connect_drop_balance',
13
- 'connect_agent_prompt',
14
13
  ];
15
14
  export function registerTools(server, client) {
16
- server.tool('connect_get_price', 'Get public x402 list prices for lookup, scores, and agent (reference only; live paywall amounts are in 402 responses).', {}, async () => client.request({ method: 'GET', path: '/price', authenticated: false }));
15
+ server.tool('connect_get_price', 'Get public x402 list prices for lookup and scores (reference only; live paywall amounts are in 402 responses).', {}, async () => client.request({ method: 'GET', path: '/price', authenticated: false }));
16
+ server.tool('connect_get_chains', 'List product chains with per-feature compatibility. lookup is true for EVM catalog chains and Solana; drop is true only for Smart Send EVM chains (use those chainIds for connect_drop / connect_drop_balance).', {}, async () => client.request({ method: 'GET', path: '/chains', authenticated: false }));
17
17
  server.tool('connect_lookup', 'Resolve social identities to EVM and Solana wallet addresses. If status is processing, retry the same payload.', lookupInputSchema, async ({ recipients }) => client.request({
18
18
  method: 'POST',
19
19
  path: '/lookup',
20
20
  body: { recipients },
21
21
  }));
22
- server.tool('connect_lookup_exposed', 'List platforms a recipient has exposed on Connect, with enriched profile, scores, and wallet addresses. May require x402 payment when the profile owner charges for lookups.', lookupExposedInputSchema, async ({ recipient }) => client.request({
22
+ server.tool('connect_lookup_exposed', 'List platforms a recipient has exposed on Connect, with enriched profile, scores, and wallet addresses. Recipient may be a social account, an exposed wallet (EVM/Solana/smart wallet), or a Connect username. May require x402 payment when the profile owner charges for lookups.', lookupExposedInputSchema, async ({ recipient }) => client.request({
23
23
  method: 'POST',
24
24
  path: '/lookup/exposed',
25
25
  body: { recipient },
@@ -41,7 +41,7 @@ export function registerTools(server, client) {
41
41
  method: 'GET',
42
42
  path: '/account/me',
43
43
  }));
44
- server.tool('connect_drop', 'Execute a Smart Send (batch token transfer). Returns 201 when submitted or 202 when recipients still processing — retry with same idempotencyKey.', dropInputSchema, async ({ ignoreFailedRecipients, ...body }) => client.request({
44
+ server.tool('connect_drop', 'Execute a Smart Send (batch native or ERC-20 transfer). Omit tokenContract or set it to null for the chain native token (ETH on 1/8453/10/42161/480, POL on 137, AVAX on 43114); pass the ERC-20 contract address otherwise — do not use the zero address. Amounts are smallest-unit integer strings; use connect_drop_balance decimals (native ETH = 18, USDC usually 6). Returns 201 when submitted or 202 when recipients still processing — retry with the same idempotencyKey.', dropInputSchema, async ({ ignoreFailedRecipients, ...body }) => client.request({
45
45
  method: 'POST',
46
46
  path: '/drop',
47
47
  body,
@@ -56,13 +56,4 @@ export function registerTools(server, client) {
56
56
  requireApiKey: true,
57
57
  query: { chainId: String(chainId) },
58
58
  }));
59
- server.tool('connect_agent_prompt', 'Natural-language agent turn for Farcaster/Lens cohort discovery. Blocking up to 60s. Omit sessionId to start; include to continue. Do not send requester.', agentPromptInputSchema, async ({ prompt, sessionId }) => client.request({
60
- method: 'POST',
61
- path: '/agent',
62
- body: {
63
- prompt,
64
- ...(sessionId ? { sessionId } : {}),
65
- },
66
- timeoutMs: AGENT_TIMEOUT_MS,
67
- }));
68
59
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@quidli/connect-mcp",
3
- "version": "0.5.5",
4
- "description": "Identity and reputation for AI agents: resolve social handles to wallet addresses, check reputation scores, and send tokens from any MCP client.",
3
+ "version": "0.5.7",
4
+ "description": "Identity and reputation for multiplayer agents: resolve social handles to wallet addresses, check reputation from public history, and send tokens from any MCP client.",
5
5
  "keywords": [
6
6
  "mcp",
7
7
  "mcp-server",
@@ -10,6 +10,7 @@
10
10
  "agent",
11
11
  "web3-agent",
12
12
  "agent-payments",
13
+ "multiplayer-agents",
13
14
  "identity",
14
15
  "identity-resolution",
15
16
  "reputation",
@@ -17,9 +18,16 @@
17
18
  "wallet",
18
19
  "usdc",
19
20
  "farcaster",
20
- "x402"
21
+ "x402",
22
+ "ethereum",
23
+ "solana",
24
+ "base",
25
+ "crypto",
26
+ "claude",
27
+ "cursor",
28
+ "claude-desktop"
21
29
  ],
22
- "homepage": "https://quidli.xyz",
30
+ "homepage": "https://connect.quid.li",
23
31
  "repository": {
24
32
  "type": "git",
25
33
  "url": "git+https://github.com/Quidli/connect-mcp.git"