arcid-mcp 0.1.0 → 0.2.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 +21 -1
- package/dist/http.js +49 -0
- package/dist/server.js +1 -1
- package/dist/tools.js +2 -1
- package/package.json +8 -4
package/README.md
CHANGED
|
@@ -17,7 +17,21 @@ Read-only. No wallet or API key needed.
|
|
|
17
17
|
| `get_registry_stats` | Index totals |
|
|
18
18
|
| `get_indexer_health` | How far the indexer is behind the chain head |
|
|
19
19
|
|
|
20
|
-
##
|
|
20
|
+
## Connect
|
|
21
|
+
|
|
22
|
+
### Remote (claude.ai, ChatGPT, any URL-based client)
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
https://mcp.arcusid.com/mcp
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Streamable HTTP, stateless, no authentication.
|
|
29
|
+
|
|
30
|
+
- **claude.ai / Claude Desktop:** Settings → Connectors → Add custom connector → paste the URL.
|
|
31
|
+
- **ChatGPT:** Settings → Apps & Connectors → Advanced → enable Developer mode → Create → paste the URL, authentication: none.
|
|
32
|
+
- **Claude Code:** `claude mcp add --transport http arcid https://mcp.arcusid.com/mcp`
|
|
33
|
+
|
|
34
|
+
### Local (stdio via npx)
|
|
21
35
|
|
|
22
36
|
No install step needed; clients run it with `npx`.
|
|
23
37
|
|
|
@@ -55,8 +69,14 @@ npm run dev # run from source (tsx)
|
|
|
55
69
|
npm test # vitest
|
|
56
70
|
npm run test:coverage # 80% threshold enforced
|
|
57
71
|
npm run inspect # MCP Inspector against dist/
|
|
72
|
+
npm run worker:dev # remote endpoint locally (wrangler)
|
|
73
|
+
npm run worker:deploy # typecheck, test, deploy the Worker
|
|
58
74
|
```
|
|
59
75
|
|
|
76
|
+
The remote endpoint is `worker/index.ts`: a Cloudflare Worker that serves the same tools over Streamable HTTP
|
|
77
|
+
(`src/http.ts`). It reaches the ArcID API through a service binding and forwards the caller's IP, so API rate
|
|
78
|
+
limits apply per user.
|
|
79
|
+
|
|
60
80
|
## License
|
|
61
81
|
|
|
62
82
|
MIT
|
package/dist/http.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
|
|
2
|
+
import { createServer } from "./server.js";
|
|
3
|
+
// Remote (Streamable HTTP) transport for runtimes with web-standard Request/Response, e.g. Cloudflare Workers.
|
|
4
|
+
// Stateless: every POST gets a fresh server and transport, so no session state lives between requests.
|
|
5
|
+
export const MCP_PATH = "/mcp";
|
|
6
|
+
export const MAX_BODY_BYTES = 64 * 1024;
|
|
7
|
+
const CORS_HEADERS = {
|
|
8
|
+
"access-control-allow-origin": "*",
|
|
9
|
+
"access-control-allow-methods": "POST, OPTIONS",
|
|
10
|
+
"access-control-allow-headers": "content-type, accept, authorization, mcp-protocol-version, mcp-session-id, last-event-id",
|
|
11
|
+
"access-control-expose-headers": "mcp-session-id, mcp-protocol-version",
|
|
12
|
+
"access-control-max-age": "600",
|
|
13
|
+
};
|
|
14
|
+
function withCors(res) {
|
|
15
|
+
const headers = new Headers(res.headers);
|
|
16
|
+
for (const [k, v] of Object.entries(CORS_HEADERS))
|
|
17
|
+
headers.set(k, v);
|
|
18
|
+
return new Response(res.body, { status: res.status, statusText: res.statusText, headers });
|
|
19
|
+
}
|
|
20
|
+
function rpcError(status, message, extra = {}) {
|
|
21
|
+
const body = JSON.stringify({ jsonrpc: "2.0", error: { code: -32000, message }, id: null });
|
|
22
|
+
return withCors(new Response(body, { status, headers: { "content-type": "application/json", ...extra } }));
|
|
23
|
+
}
|
|
24
|
+
export async function handleMcpHttp(request, client) {
|
|
25
|
+
if (request.method === "OPTIONS")
|
|
26
|
+
return withCors(new Response(null, { status: 204 }));
|
|
27
|
+
if (request.method !== "POST") {
|
|
28
|
+
return rpcError(405, "Method not allowed. This endpoint is stateless: send JSON-RPC over POST.", { allow: "POST, OPTIONS" });
|
|
29
|
+
}
|
|
30
|
+
const server = createServer(client);
|
|
31
|
+
const transport = new WebStandardStreamableHTTPServerTransport({
|
|
32
|
+
sessionIdGenerator: undefined,
|
|
33
|
+
enableJsonResponse: true,
|
|
34
|
+
maxRequestBodySize: MAX_BODY_BYTES,
|
|
35
|
+
});
|
|
36
|
+
try {
|
|
37
|
+
await server.connect(transport);
|
|
38
|
+
return withCors(await transport.handleRequest(request));
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
console.error("[arcid-mcp] http transport error", err);
|
|
42
|
+
return rpcError(500, "Internal error");
|
|
43
|
+
}
|
|
44
|
+
finally {
|
|
45
|
+
// Response bodies are fully materialised in JSON mode, so closing here is safe.
|
|
46
|
+
await transport.close().catch(() => { });
|
|
47
|
+
await server.close().catch(() => { });
|
|
48
|
+
}
|
|
49
|
+
}
|
package/dist/server.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
2
|
import { registerTools } from "./tools.js";
|
|
3
3
|
export const SERVER_NAME = "arcid";
|
|
4
|
-
export const SERVER_VERSION = "0.
|
|
4
|
+
export const SERVER_VERSION = "0.2.0";
|
|
5
5
|
export function createServer(client) {
|
|
6
6
|
const server = new McpServer({ name: SERVER_NAME, version: SERVER_VERSION }, {
|
|
7
7
|
instructions: "ArcID indexes AI agent identities and reputation from the ERC-8004 registries on Arc. " +
|
package/dist/tools.js
CHANGED
|
@@ -30,7 +30,8 @@ export function registerTools(server, client) {
|
|
|
30
30
|
inputSchema: {
|
|
31
31
|
query: z.string().trim().max(120).optional().describe("Full-text search (prefix match on words)"),
|
|
32
32
|
owner: z.string().regex(/^0x[0-9a-fA-F]{40}$/, "owner must be a 0x address").optional().describe("Owner wallet address"),
|
|
33
|
-
readable_only: z.boolean().
|
|
33
|
+
readable_only: z.boolean().default(true)
|
|
34
|
+
.describe("Only agents with a readable profile (name, description). Default true; set false to include unnamed agents"),
|
|
34
35
|
sort: z.enum(["newest", "score", "feedback", "settled", "relevance"]).optional()
|
|
35
36
|
.describe("Default: relevance when a query is given, otherwise newest"),
|
|
36
37
|
page,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "arcid-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "MCP server for ArcID: look up AI agent identity and reputation (ERC-8004) on Arc",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -15,11 +15,13 @@
|
|
|
15
15
|
"scripts": {
|
|
16
16
|
"dev": "tsx src/index.ts",
|
|
17
17
|
"build": "tsc -p tsconfig.build.json",
|
|
18
|
-
"typecheck": "tsc --noEmit",
|
|
18
|
+
"typecheck": "tsc --noEmit && tsc -p worker/tsconfig.json",
|
|
19
19
|
"test": "vitest run",
|
|
20
20
|
"test:coverage": "vitest run --coverage",
|
|
21
21
|
"inspect": "npx @modelcontextprotocol/inspector node dist/index.js",
|
|
22
|
-
"prepublishOnly": "npm run typecheck && npm test && npm run build"
|
|
22
|
+
"prepublishOnly": "npm run typecheck && npm test && npm run build",
|
|
23
|
+
"worker:dev": "wrangler dev",
|
|
24
|
+
"worker:deploy": "npm run typecheck && npm test && wrangler deploy"
|
|
23
25
|
},
|
|
24
26
|
"keywords": [
|
|
25
27
|
"mcp",
|
|
@@ -48,10 +50,12 @@
|
|
|
48
50
|
"zod": "^4.6.5"
|
|
49
51
|
},
|
|
50
52
|
"devDependencies": {
|
|
53
|
+
"@cloudflare/workers-types": "^5.20260927.1",
|
|
51
54
|
"@types/node": "^26.6.3",
|
|
52
55
|
"@vitest/coverage-v8": "^5.0.2",
|
|
53
56
|
"tsx": "^4.23.15",
|
|
54
57
|
"typescript": "^5.9.3",
|
|
55
|
-
"vitest": "^5.0.2"
|
|
58
|
+
"vitest": "^5.0.2",
|
|
59
|
+
"wrangler": "^4.142.0"
|
|
56
60
|
}
|
|
57
61
|
}
|