aipou-mcp-server 0.2.0 → 0.2.2
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 +12 -12
- package/dist/claims.d.ts +2 -1
- package/dist/claims.js +41 -3
- package/dist/contract.d.ts +1 -0
- package/dist/contract.js +4 -0
- package/dist/index.js +17 -4
- package/dist/protocol.test.js +2 -0
- package/dist/status.d.ts +1 -0
- package/dist/status.js +73 -0
- package/dist/store.d.ts +6 -0
- package/dist/store.js +10 -0
- package/dist/types.d.ts +11 -0
- package/package.json +18 -18
- package/server.json +3 -3
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# AIPOU MCP Server
|
|
2
2
|
|
|
3
|
-
`aipou-mcp-server` records private, signed receipts for authorized AI tasks. It supports local receipt collection and optional claims for validated work on Base.
|
|
3
|
+
`aipou-mcp-server` records private, signed receipts for authorized AI tasks. It supports local receipt collection, reward status checks, and optional claims for validated work on Base.
|
|
4
4
|
|
|
5
5
|
It does not detect hidden AI use, prove task quality, replace payment rails, or require raw prompts and outputs to leave the user's machine.
|
|
6
6
|
|
|
@@ -18,9 +18,17 @@ npm run demo
|
|
|
18
18
|
|
|
19
19
|
The demo launches this MCP server over stdio, creates a local signed receipt with an ephemeral wallet, and prints the `receiptId` reference a framework can attach to metadata. It does not claim rewards or move funds.
|
|
20
20
|
|
|
21
|
+
## Run From npm
|
|
22
|
+
|
|
23
|
+
MCP clients can launch the published package with:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npx -y aipou-mcp-server
|
|
27
|
+
```
|
|
28
|
+
|
|
21
29
|
## Run locally from this repository
|
|
22
30
|
|
|
23
|
-
|
|
31
|
+
For local development or source review, run the MCP server from a checkout:
|
|
24
32
|
|
|
25
33
|
```bash
|
|
26
34
|
npm install
|
|
@@ -34,14 +42,6 @@ For development:
|
|
|
34
42
|
npm run dev -w mcp-server
|
|
35
43
|
```
|
|
36
44
|
|
|
37
|
-
## Run after npm publication
|
|
38
|
-
|
|
39
|
-
After the package is published to npm, MCP clients can launch it with:
|
|
40
|
-
|
|
41
|
-
```bash
|
|
42
|
-
npx -y aipou-mcp-server
|
|
43
|
-
```
|
|
44
|
-
|
|
45
45
|
Required configuration:
|
|
46
46
|
|
|
47
47
|
```text
|
|
@@ -50,13 +50,13 @@ AIPOU_CONTRACT_ADDRESS=0x55f0Cc5e51A1284D20337d6cbb18938C8A1ABCbB
|
|
|
50
50
|
AIPOU_CLAIMS_ADDRESS=0x4ca4C98fB784D20EdC8E2A7F531dAab4c6e53058
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
-
Use a new dedicated farming wallet, never a primary wallet. Do not commit the private key. Optional claims and settlement occur only after an explicit user request.
|
|
53
|
+
Use a new dedicated farming wallet, never a primary wallet. Do not commit the private key. Status checks can show already claimed and pending AIPOU without moving funds. Optional claims and settlement occur only after an explicit user request.
|
|
54
54
|
|
|
55
55
|
Do not configure `AIPOU_VALIDATOR_PRIVATE_KEY` on a user installation. That key is only for the separate protocol validator service. The local Ed25519 collector key and receipt metadata are stored unencrypted under `AIPOU_DATA_DIR`; restrict that directory with operating-system permissions and use encrypted backups.
|
|
56
56
|
|
|
57
57
|
The default network is Base mainnet. `AIPOU_RPC_URL` and `AIPOU_DATA_DIR` can be set when a custom RPC endpoint or receipt directory is needed.
|
|
58
58
|
|
|
59
|
-
Publication
|
|
59
|
+
Publication details: [docs/npm-publication.md](https://github.com/0xddneto/AI-Proof-of-Us/blob/main/docs/npm-publication.md).
|
|
60
60
|
|
|
61
61
|
## Documentation
|
|
62
62
|
|
package/dist/claims.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import type { SettlementResult } from "./types.js";
|
|
1
|
+
import type { SettlementAllResult, SettlementResult } from "./types.js";
|
|
2
2
|
export declare function settleRewards(maxReceipts?: number): Promise<SettlementResult>;
|
|
3
|
+
export declare function settleAllRewards(batchSize?: number, maxBatches?: number): Promise<SettlementAllResult>;
|
package/dist/claims.js
CHANGED
|
@@ -86,16 +86,17 @@ async function verifyReceipt(receipt, trustedCollectors) {
|
|
|
86
86
|
throw new Error(`Invalid trust tier for ${receipt.receiptId}`);
|
|
87
87
|
}
|
|
88
88
|
export async function settleRewards(maxReceipts = 25) {
|
|
89
|
-
const candidates = await unsettledReceipts(
|
|
89
|
+
const candidates = await unsettledReceipts(Number.MAX_SAFE_INTEGER);
|
|
90
90
|
if (candidates.length === 0)
|
|
91
91
|
throw new Error("There are no unsettled receipts");
|
|
92
92
|
const policy = settlementPolicyFromEnv();
|
|
93
93
|
const recentlySettled = await settledReceiptsSince(Date.now() - DAY_MS);
|
|
94
|
-
const { eligible
|
|
95
|
-
if (
|
|
94
|
+
const { eligible, skipped } = filterEligibleReceipts(candidates, recentlySettled, policy);
|
|
95
|
+
if (eligible.length === 0) {
|
|
96
96
|
const reasons = skipped.map((item) => `${item.receiptId.slice(0, 10)}…: ${item.reason}`).join("; ");
|
|
97
97
|
throw new Error(`No receipts pass the settlement policy. Skipped: ${reasons}`);
|
|
98
98
|
}
|
|
99
|
+
const receipts = eligible.slice(0, maxReceipts);
|
|
99
100
|
const trustedCollectors = await trustedCollectorFingerprints();
|
|
100
101
|
for (const receipt of receipts)
|
|
101
102
|
await verifyReceipt(receipt, trustedCollectors);
|
|
@@ -148,3 +149,40 @@ export async function settleRewards(maxReceipts = 25) {
|
|
|
148
149
|
await markBatchSettled(batch);
|
|
149
150
|
return { ...batch, skippedReceipts: skipped };
|
|
150
151
|
}
|
|
152
|
+
export async function settleAllRewards(batchSize = 100, maxBatches = 20) {
|
|
153
|
+
const batches = [];
|
|
154
|
+
const skippedByReceiptId = new Map();
|
|
155
|
+
let stoppedReason;
|
|
156
|
+
for (let index = 0; index < maxBatches; index += 1) {
|
|
157
|
+
try {
|
|
158
|
+
const batch = await settleRewards(batchSize);
|
|
159
|
+
batches.push(batch);
|
|
160
|
+
for (const skipped of batch.skippedReceipts) {
|
|
161
|
+
skippedByReceiptId.set(skipped.receiptId, skipped);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
166
|
+
if (message === "There are no unsettled receipts")
|
|
167
|
+
break;
|
|
168
|
+
stoppedReason = message;
|
|
169
|
+
break;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
if (!stoppedReason && batches.length === maxBatches) {
|
|
173
|
+
stoppedReason = `Stopped after maxBatches=${maxBatches}; run settle_all_ai_rewards again for any remaining receipts`;
|
|
174
|
+
}
|
|
175
|
+
const pendingReceiptCount = (await unsettledReceipts(Number.MAX_SAFE_INTEGER)).length;
|
|
176
|
+
const skippedReceipts = [...skippedByReceiptId.values()];
|
|
177
|
+
return {
|
|
178
|
+
batches,
|
|
179
|
+
batchCount: batches.length,
|
|
180
|
+
settledReceiptCount: batches.reduce((total, batch) => total + batch.receiptIds.length, 0),
|
|
181
|
+
skippedReceipts,
|
|
182
|
+
pendingReceiptCount,
|
|
183
|
+
publishTransactions: batches.map((batch) => batch.publishTransaction),
|
|
184
|
+
claimTransactions: batches.map((batch) => batch.claimTransaction),
|
|
185
|
+
stoppedReason,
|
|
186
|
+
settledAt: new Date().toISOString()
|
|
187
|
+
};
|
|
188
|
+
}
|
package/dist/contract.d.ts
CHANGED
package/dist/contract.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { readFile } from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
|
+
const DEFAULT_LOGO_URI = "https://raw.githubusercontent.com/0xddneto/AI-Proof-of-Us/main/assets/token/aipou.png";
|
|
3
4
|
export const aipouTokenAbi = [
|
|
4
5
|
"function name() view returns (string)",
|
|
5
6
|
"function symbol() view returns (string)",
|
|
@@ -39,6 +40,7 @@ function envConfig() {
|
|
|
39
40
|
name: "AI Proof of Use",
|
|
40
41
|
symbol: "AIPOU",
|
|
41
42
|
address,
|
|
43
|
+
logoURI: process.env.AIPOU_LOGO_URI || DEFAULT_LOGO_URI,
|
|
42
44
|
decimals: 18,
|
|
43
45
|
chainId: Number(process.env.AIPOU_CHAIN_ID || 8453),
|
|
44
46
|
chainName: process.env.AIPOU_CHAIN_NAME || "Base Mainnet",
|
|
@@ -61,6 +63,7 @@ async function deploymentFileConfig() {
|
|
|
61
63
|
name: deployment.token?.name || "AI Proof of Use",
|
|
62
64
|
symbol: deployment.token?.symbol || "AIPOU",
|
|
63
65
|
address,
|
|
66
|
+
logoURI: deployment.token?.logoURI || process.env.AIPOU_LOGO_URI || DEFAULT_LOGO_URI,
|
|
64
67
|
decimals: deployment.token?.decimals || 18,
|
|
65
68
|
chainId: deployment.chain?.id || 8453,
|
|
66
69
|
chainName: deployment.chain?.name || "Base Mainnet",
|
|
@@ -89,6 +92,7 @@ export async function getTokenContractConfig() {
|
|
|
89
92
|
name: "AI Proof of Use",
|
|
90
93
|
symbol: "AIPOU",
|
|
91
94
|
address: null,
|
|
95
|
+
logoURI: process.env.AIPOU_LOGO_URI || DEFAULT_LOGO_URI,
|
|
92
96
|
decimals: 18,
|
|
93
97
|
chainId: 8453,
|
|
94
98
|
chainName: "Base Mainnet",
|
package/dist/index.js
CHANGED
|
@@ -3,22 +3,24 @@ import "dotenv/config";
|
|
|
3
3
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
4
4
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
5
5
|
import { z } from "zod";
|
|
6
|
-
import { settleRewards } from "./claims.js";
|
|
6
|
+
import { settleAllRewards, settleRewards } from "./claims.js";
|
|
7
7
|
import { collectorFingerprint, getCollectorPublicKey } from "./collector.js";
|
|
8
8
|
import { aipouClaimsAbi, aipouTokenAbi, getTokenContractConfig } from "./contract.js";
|
|
9
9
|
import { agentWallet } from "./identity.js";
|
|
10
10
|
import { beginTask, completeTask, exportReceipts } from "./receipts.js";
|
|
11
11
|
import { estimateReward } from "./rewards.js";
|
|
12
|
+
import { getAipouStatus } from "./status.js";
|
|
12
13
|
const bytes32 = z.string().regex(/^0x[a-fA-F0-9]{64}$/);
|
|
13
14
|
const usageCounts = {
|
|
14
15
|
inputTokens: z.number().int().min(0).max(10_000_000),
|
|
15
16
|
outputTokens: z.number().int().min(0).max(10_000_000),
|
|
16
17
|
durationSeconds: z.number().int().min(0).max(86_400)
|
|
17
18
|
};
|
|
18
|
-
const server = new McpServer({ name: "aipou-mcp", version: "0.2.
|
|
19
|
+
const server = new McpServer({ name: "aipou-mcp", version: "0.2.2" }, {
|
|
19
20
|
instructions: "For meaningful AI tasks, call begin_ai_task before work and complete_ai_task after work using hashes, never raw prompts or outputs. " +
|
|
20
21
|
"Use the dedicated farming identity only. Never reveal private keys or local collector state. " +
|
|
21
|
-
"Call
|
|
22
|
+
"Call settle_all_ai_rewards after a broad user request such as 'claim my AIPOU' or 'settle all pending AIPOU'. " +
|
|
23
|
+
"Call settle_ai_rewards only when the user asks for a single limited batch. Settlement submits on-chain transactions. " +
|
|
22
24
|
"The host client and its user always keep the final say on transaction confirmation policy."
|
|
23
25
|
});
|
|
24
26
|
server.tool("get_aipou_contract", "Return the configured AIPOU token contract address, Base network details, explorer URL, and minimal ABI.", {}, async () => {
|
|
@@ -37,6 +39,10 @@ server.tool("get_aipou_identity", "Return the dedicated farming wallet address a
|
|
|
37
39
|
}]
|
|
38
40
|
};
|
|
39
41
|
});
|
|
42
|
+
server.tool("get_aipou_status", "Show recorded, pending, and already claimed AIPOU receipts plus the farming wallet's on-chain AIPOU balance. Does not reveal private keys or full receipt payloads.", {}, async () => {
|
|
43
|
+
const status = await getAipouStatus();
|
|
44
|
+
return { content: [{ type: "text", text: JSON.stringify(status, null, 2) }] };
|
|
45
|
+
});
|
|
40
46
|
server.tool("estimate_ai_reward", "Estimate the client-signed AIPOU reward before a task is completed. The final tier is derived by the validator.", usageCounts, async (input) => ({
|
|
41
47
|
content: [{
|
|
42
48
|
type: "text",
|
|
@@ -76,9 +82,16 @@ server.tool("export_ai_receipts", "Export stored signed AI task receipts, option
|
|
|
76
82
|
const receipts = await exportReceipts(wallet);
|
|
77
83
|
return { content: [{ type: "text", text: JSON.stringify({ count: receipts.length, receipts }, null, 2) }] };
|
|
78
84
|
});
|
|
79
|
-
server.tool("settle_ai_rewards", "After an explicit user claim request, validate eligible receipts against the settlement policy, publish a Merkle root, and mint the included rewards. Submits two on-chain transactions; the host's own confirmation policy applies.", { maxReceipts: z.number().int().min(1).max(100).default(25) }, async ({ maxReceipts }) => {
|
|
85
|
+
server.tool("settle_ai_rewards", "After an explicit user claim request for one limited batch, validate eligible receipts against the settlement policy, publish a Merkle root, and mint the included rewards. Submits two on-chain transactions; the host's own confirmation policy applies.", { maxReceipts: z.number().int().min(1).max(100).default(25) }, async ({ maxReceipts }) => {
|
|
80
86
|
const batch = await settleRewards(maxReceipts);
|
|
81
87
|
return { content: [{ type: "text", text: JSON.stringify(batch, null, 2) }] };
|
|
82
88
|
});
|
|
89
|
+
server.tool("settle_all_ai_rewards", "After an explicit broad claim request, settle all currently pending eligible receipts from the shared AIPOU data directory by submitting as many bounded batches as needed. Each batch publishes one Merkle root and submits one claim transaction.", {
|
|
90
|
+
batchSize: z.number().int().min(1).max(100).default(100),
|
|
91
|
+
maxBatches: z.number().int().min(1).max(50).default(20)
|
|
92
|
+
}, async ({ batchSize, maxBatches }) => {
|
|
93
|
+
const result = await settleAllRewards(batchSize, maxBatches);
|
|
94
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
95
|
+
});
|
|
83
96
|
const transport = new StdioServerTransport();
|
|
84
97
|
await server.connect(transport);
|
package/dist/protocol.test.js
CHANGED
|
@@ -53,6 +53,8 @@ test("creates verifiable receipts and rejects nonce/evidence replay", async () =
|
|
|
53
53
|
chainId: 8453,
|
|
54
54
|
verifyingContract
|
|
55
55
|
});
|
|
56
|
+
assert.match(repeatedSession.nonce, /^0x[0-9a-f]{64}$/);
|
|
57
|
+
assert.notEqual(repeatedSession.nonce, session.nonce);
|
|
56
58
|
await assert.rejects(completeTask({
|
|
57
59
|
nonce: repeatedSession.nonce,
|
|
58
60
|
inputTokens: 1200,
|
package/dist/status.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getAipouStatus(): Promise<Record<string, unknown>>;
|
package/dist/status.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { Contract, JsonRpcProvider, formatUnits } from "ethers";
|
|
2
|
+
import { aipouTokenAbi, getTokenContractConfig } from "./contract.js";
|
|
3
|
+
import { agentWallet } from "./identity.js";
|
|
4
|
+
import { exportStoredReceipts, protocolStateCounts, unsettledReceipts } from "./store.js";
|
|
5
|
+
function sumRewards(receipts) {
|
|
6
|
+
const total = receipts.reduce((sum, receipt) => sum + Number(receipt.estimatedReward), 0);
|
|
7
|
+
return Number.isInteger(total) ? total.toFixed(0) : total.toFixed(6).replace(/0+$/, "").replace(/\.$/, "");
|
|
8
|
+
}
|
|
9
|
+
export async function getAipouStatus() {
|
|
10
|
+
const wallet = agentWallet().address;
|
|
11
|
+
const contract = await getTokenContractConfig();
|
|
12
|
+
const receipts = await exportStoredReceipts(wallet);
|
|
13
|
+
const pendingReceipts = await unsettledReceipts(Number.MAX_SAFE_INTEGER);
|
|
14
|
+
const walletPendingReceipts = pendingReceipts.filter((receipt) => receipt.wallet.toLowerCase() === wallet.toLowerCase());
|
|
15
|
+
const claimedReceipts = receipts.filter((receipt) => receipt.claimTransaction);
|
|
16
|
+
const counts = await protocolStateCounts();
|
|
17
|
+
let onchain = { available: false };
|
|
18
|
+
if (contract.address) {
|
|
19
|
+
try {
|
|
20
|
+
const provider = new JsonRpcProvider(contract.rpcUrl);
|
|
21
|
+
const token = new Contract(contract.address, aipouTokenAbi, provider);
|
|
22
|
+
const [decimals, balance, totalSupply] = await Promise.all([
|
|
23
|
+
token.decimals(),
|
|
24
|
+
token.balanceOf(wallet),
|
|
25
|
+
token.totalSupply()
|
|
26
|
+
]);
|
|
27
|
+
onchain = {
|
|
28
|
+
available: true,
|
|
29
|
+
wallet,
|
|
30
|
+
balance: formatUnits(balance, decimals),
|
|
31
|
+
totalSupply: formatUnits(totalSupply, decimals),
|
|
32
|
+
explorerUrl: `${contract.blockExplorer}/token/${contract.address}?a=${wallet}`
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
onchain = {
|
|
37
|
+
available: false,
|
|
38
|
+
error: error instanceof Error ? error.message : String(error)
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
const lastClaim = claimedReceipts
|
|
43
|
+
.filter((receipt) => receipt.claimTransaction)
|
|
44
|
+
.sort((a, b) => Date.parse(b.recordedAt) - Date.parse(a.recordedAt))[0];
|
|
45
|
+
return {
|
|
46
|
+
wallet,
|
|
47
|
+
chainId: contract.chainId,
|
|
48
|
+
tokenAddress: contract.address,
|
|
49
|
+
claimsAddress: contract.claimsAddress,
|
|
50
|
+
receipts: {
|
|
51
|
+
recorded: receipts.length,
|
|
52
|
+
claimed: claimedReceipts.length,
|
|
53
|
+
pending: walletPendingReceipts.length,
|
|
54
|
+
incompleteSessions: counts.incompleteSessions,
|
|
55
|
+
batches: counts.batches
|
|
56
|
+
},
|
|
57
|
+
rewards: {
|
|
58
|
+
claimedEstimated: sumRewards(claimedReceipts),
|
|
59
|
+
pendingEstimated: sumRewards(walletPendingReceipts),
|
|
60
|
+
totalEstimated: sumRewards(receipts),
|
|
61
|
+
unit: "AIPOU"
|
|
62
|
+
},
|
|
63
|
+
latestClaim: lastClaim
|
|
64
|
+
? {
|
|
65
|
+
receiptId: lastClaim.receiptId,
|
|
66
|
+
transaction: lastClaim.claimTransaction,
|
|
67
|
+
explorerUrl: `${contract.blockExplorer}/tx/${lastClaim.claimTransaction}`,
|
|
68
|
+
recordedAt: lastClaim.recordedAt
|
|
69
|
+
}
|
|
70
|
+
: null,
|
|
71
|
+
onchain
|
|
72
|
+
};
|
|
73
|
+
}
|
package/dist/store.d.ts
CHANGED
|
@@ -4,5 +4,11 @@ export declare function getSession(nonce: string): Promise<TaskSession | null>;
|
|
|
4
4
|
export declare function saveCompletedReceipt(evidenceKey: string, receipt: UsageReceipt): Promise<void>;
|
|
5
5
|
export declare function exportStoredReceipts(wallet?: string): Promise<UsageReceipt[]>;
|
|
6
6
|
export declare function unsettledReceipts(limit: number): Promise<UsageReceipt[]>;
|
|
7
|
+
export declare function protocolStateCounts(): Promise<{
|
|
8
|
+
sessions: number;
|
|
9
|
+
completedSessions: number;
|
|
10
|
+
incompleteSessions: number;
|
|
11
|
+
batches: number;
|
|
12
|
+
}>;
|
|
7
13
|
export declare function settledReceiptsSince(sinceMs: number): Promise<UsageReceipt[]>;
|
|
8
14
|
export declare function markBatchSettled(batch: ClaimBatch): Promise<void>;
|
package/dist/store.js
CHANGED
|
@@ -103,6 +103,16 @@ export async function exportStoredReceipts(wallet) {
|
|
|
103
103
|
export async function unsettledReceipts(limit) {
|
|
104
104
|
return (await readState()).receipts.filter((receipt) => !receipt.claimTransaction).slice(0, limit);
|
|
105
105
|
}
|
|
106
|
+
export async function protocolStateCounts() {
|
|
107
|
+
const state = await readState();
|
|
108
|
+
const sessions = Object.values(state.sessions);
|
|
109
|
+
return {
|
|
110
|
+
sessions: sessions.length,
|
|
111
|
+
completedSessions: sessions.filter((session) => session.completedAt).length,
|
|
112
|
+
incompleteSessions: sessions.filter((session) => !session.completedAt).length,
|
|
113
|
+
batches: state.batches.length
|
|
114
|
+
};
|
|
115
|
+
}
|
|
106
116
|
export async function settledReceiptsSince(sinceMs) {
|
|
107
117
|
const receipts = [...(await readArchivedReceipts()), ...(await readState()).receipts];
|
|
108
118
|
return receipts.filter((receipt) => receipt.claimTransaction && Date.parse(receipt.recordedAt) >= sinceMs);
|
package/dist/types.d.ts
CHANGED
|
@@ -64,6 +64,17 @@ export interface SkippedReceipt {
|
|
|
64
64
|
export interface SettlementResult extends ClaimBatch {
|
|
65
65
|
skippedReceipts: SkippedReceipt[];
|
|
66
66
|
}
|
|
67
|
+
export interface SettlementAllResult {
|
|
68
|
+
batches: SettlementResult[];
|
|
69
|
+
batchCount: number;
|
|
70
|
+
settledReceiptCount: number;
|
|
71
|
+
skippedReceipts: SkippedReceipt[];
|
|
72
|
+
pendingReceiptCount: number;
|
|
73
|
+
publishTransactions: string[];
|
|
74
|
+
claimTransactions: string[];
|
|
75
|
+
stoppedReason?: string;
|
|
76
|
+
settledAt: string;
|
|
77
|
+
}
|
|
67
78
|
export interface ProtocolState {
|
|
68
79
|
sessions: Record<string, TaskSession>;
|
|
69
80
|
receipts: UsageReceipt[];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
{
|
|
1
|
+
{
|
|
2
2
|
"name": "aipou-mcp-server",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"mcpName": "io.github.0xddneto/ai-proof-of-us",
|
|
5
5
|
"description": "MCP server for private, signed AI task receipts and optional validated AIPOU claims.",
|
|
6
6
|
"keywords": [
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"url": "git+https://github.com/0xddneto/AI-Proof-of-Us.git",
|
|
19
19
|
"directory": "mcp-server"
|
|
20
20
|
},
|
|
21
|
-
"homepage": "https://github.
|
|
21
|
+
"homepage": "https://0xddneto.github.io/AI-Proof-of-Us/",
|
|
22
22
|
"bugs": {
|
|
23
23
|
"url": "https://github.com/0xddneto/AI-Proof-of-Us/issues"
|
|
24
24
|
},
|
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
"bin": {
|
|
34
34
|
"aipou-mcp": "dist/index.js"
|
|
35
35
|
},
|
|
36
|
-
"scripts": {
|
|
37
|
-
"build": "tsc -p tsconfig.json",
|
|
36
|
+
"scripts": {
|
|
37
|
+
"build": "tsc -p tsconfig.json",
|
|
38
38
|
"test": "npm run build && node --test dist/protocol.test.js",
|
|
39
39
|
"pack:check": "npm test && npm pack --dry-run",
|
|
40
40
|
"dev": "tsx src/index.ts",
|
|
@@ -47,16 +47,16 @@
|
|
|
47
47
|
"engines": {
|
|
48
48
|
"node": ">=20"
|
|
49
49
|
},
|
|
50
|
-
"dependencies": {
|
|
51
|
-
"@modelcontextprotocol/sdk": "^1.13.0",
|
|
52
|
-
"dotenv": "^16.6.1",
|
|
53
|
-
"ethers": "^6.17.0",
|
|
54
|
-
"merkletreejs": "^0.6.0",
|
|
55
|
-
"zod": "^3.23.8"
|
|
56
|
-
},
|
|
57
|
-
"devDependencies": {
|
|
58
|
-
"@types/node": "^22.5.4",
|
|
59
|
-
"tsx": "^4.19.0",
|
|
60
|
-
"typescript": "^5.5.4"
|
|
61
|
-
}
|
|
62
|
-
}
|
|
50
|
+
"dependencies": {
|
|
51
|
+
"@modelcontextprotocol/sdk": "^1.13.0",
|
|
52
|
+
"dotenv": "^16.6.1",
|
|
53
|
+
"ethers": "^6.17.0",
|
|
54
|
+
"merkletreejs": "^0.6.0",
|
|
55
|
+
"zod": "^3.23.8"
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@types/node": "^22.5.4",
|
|
59
|
+
"tsx": "^4.19.0",
|
|
60
|
+
"typescript": "^5.5.4"
|
|
61
|
+
}
|
|
62
|
+
}
|
package/server.json
CHANGED
|
@@ -3,18 +3,18 @@
|
|
|
3
3
|
"name": "io.github.0xddneto/ai-proof-of-us",
|
|
4
4
|
"title": "AI Proof of Us",
|
|
5
5
|
"description": "Private signed AI task receipts with replay checks and optional validated AIPOU claims.",
|
|
6
|
-
"websiteUrl": "https://github.
|
|
6
|
+
"websiteUrl": "https://0xddneto.github.io/AI-Proof-of-Us/",
|
|
7
7
|
"repository": {
|
|
8
8
|
"url": "https://github.com/0xddneto/AI-Proof-of-Us",
|
|
9
9
|
"source": "github",
|
|
10
10
|
"subfolder": "mcp-server"
|
|
11
11
|
},
|
|
12
|
-
"version": "0.2.
|
|
12
|
+
"version": "0.2.2",
|
|
13
13
|
"packages": [
|
|
14
14
|
{
|
|
15
15
|
"registryType": "npm",
|
|
16
16
|
"identifier": "aipou-mcp-server",
|
|
17
|
-
"version": "0.2.
|
|
17
|
+
"version": "0.2.2",
|
|
18
18
|
"transport": {
|
|
19
19
|
"type": "stdio"
|
|
20
20
|
},
|