otto-intel-mcp 0.1.1 → 0.1.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 +5 -3
- package/dist/data-source.d.ts +19 -0
- package/dist/data-source.js +2 -1
- package/dist/execution-registration.js +6 -1
- package/dist/mcp-server.d.ts +1 -1
- package/dist/mcp-server.js +12 -1
- package/dist/package-version.d.ts +6 -0
- package/dist/package-version.js +9 -0
- package/dist/x402-read-source.d.ts +8 -1
- package/dist/x402-read-source.js +19 -1
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -62,7 +62,9 @@ claude mcp add otto-intel -e X402_PRIVATE_KEY=0x… -- npx -y otto-intel-mcp
|
|
|
62
62
|
}
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
-
Requires Node 22 or newer. Optional: `X402_RPC_URL` (your own Base RPC), `X402_TIMEOUT_MS` (default 30000).
|
|
65
|
+
Requires Node 22 or newer. Optional: `X402_RPC_URL` (your own Base RPC), `X402_TIMEOUT_MS` (default 30000). The local server serves the 10 intelligence tools only — **the four constructors are hosted-only**: to get an envelope, call `otto_prepare_swap` on `https://mcp.ottoai.services` (free). A paid local call carries the rail's settlement receipt in the result metadata under `com.ottoai/payment-response`, exactly like the hosted server.
|
|
66
|
+
|
|
67
|
+
`npm audit` on a fresh install reports findings that all sit in the local server's third-party venue clients (`@polymarket/clob-client-v2` → ethers v5 → `ws`, `@nktkas/hyperliquid` → `valibot`, the optional `@coinbase/cdp-sdk` → an older `axios`), none of which the library entries (`otto-intel-mcp/execution`, `/adapter`, `/adapter-cdp`) or `otto-execute` load — `otto-execute` on its own installs 19 packages with 0 findings. `npm install otto-intel-mcp --omit=optional` drops the Coinbase subtree if you do not delegate.
|
|
66
68
|
|
|
67
69
|
## What you get
|
|
68
70
|
|
|
@@ -94,7 +96,7 @@ A constructor builds the transaction; **your wallet signs and sends it.** Give i
|
|
|
94
96
|
| `otto_prepare_polymarket_order` | A Polymarket CTF Exchange V2 limit order as typed data, tick and size validated against the live market | Your Polygon EOA |
|
|
95
97
|
| `otto_prepare_perp_order` | A Hyperliquid perp limit order (optional take-profit / stop-loss), as the L1 action plus the exact EIP-712 recipe to sign | Your Hyperliquid account |
|
|
96
98
|
|
|
97
|
-
To verify, sign and submit an envelope from the command line or from code, use the companion `otto-execute` (CLI + library,
|
|
99
|
+
To verify, sign and submit an envelope from the command line or from code, use the companion [`otto-execute`](https://www.npmjs.com/package/otto-execute) (CLI + library, `npm install otto-execute`) — see the [execution seam docs](https://docs.useotto.xyz/acp-swarm/execution-seam).
|
|
98
100
|
|
|
99
101
|
### Always free
|
|
100
102
|
|
|
@@ -229,6 +231,6 @@ Field-by-field documentation: https://docs.useotto.xyz/acp-swarm/execution-seam.
|
|
|
229
231
|
- Docs: https://docs.useotto.xyz/acp-swarm/otto-intel-mcp · execution seam: https://docs.useotto.xyz/acp-swarm/execution-seam
|
|
230
232
|
- The full Otto x402 catalog: https://x402.ottoai.services
|
|
231
233
|
- Otto AI: https://useotto.xyz · X: [@useOttoAI](https://x.com/useOttoAI)
|
|
232
|
-
- Changelog: 0.1.1 — README rewritten for first-time users and agents, source maps removed from the package, publish gated by a privacy audit; 0.1.0 — first release (hosted + local server, execution constructors, library entries).
|
|
234
|
+
- Changelog: 0.1.2 — the hosted front door (`GET /`, `/health`) reports the live tool registry (21 tools, never a literal), the local server carries the settlement receipt like the hosted one, constructor descriptions state the freshness window, `serverInfo.version` = the package version; 0.1.1 — README rewritten for first-time users and agents, source maps removed from the package, publish gated by a privacy audit; 0.1.0 — first release (hosted + local server, execution constructors, library entries).
|
|
233
235
|
|
|
234
236
|
Running the hosted server yourself, or building from the monorepo: see `SETUP.md` in the repository.
|
package/dist/data-source.d.ts
CHANGED
|
@@ -2,6 +2,25 @@ import type { IntelToolDefinition, ToolArguments } from './tool-definitions.js';
|
|
|
2
2
|
export interface IntelReadOptions {
|
|
3
3
|
readonly signal?: AbortSignal;
|
|
4
4
|
}
|
|
5
|
+
/** The `_meta` name under which BOTH servers (hosted and local) carry the settlement receipt, `{ header, value }`. */
|
|
6
|
+
export declare const PAYMENT_RECEIPT_META = "com.ottoai/payment-response";
|
|
7
|
+
/** The paid rail's own settlement receipt: the header name it used and the value, verbatim. */
|
|
8
|
+
export interface IntelSettlementReceipt {
|
|
9
|
+
readonly header: string;
|
|
10
|
+
readonly value: string;
|
|
11
|
+
}
|
|
12
|
+
export interface IntelPaidRead {
|
|
13
|
+
readonly value: unknown;
|
|
14
|
+
/** Present only when the rail settled a payment for this read. */
|
|
15
|
+
readonly receipt?: IntelSettlementReceipt;
|
|
16
|
+
}
|
|
5
17
|
export interface IntelDataSource {
|
|
6
18
|
read(definition: IntelToolDefinition, input: ToolArguments, options?: IntelReadOptions): Promise<unknown>;
|
|
19
|
+
/**
|
|
20
|
+
* A read that also surfaces the settlement receipt when the source paid for it. A source that never
|
|
21
|
+
* pays (the hosted free path, the internal read source) leaves this undefined; the local x402 source
|
|
22
|
+
* implements it so the stdio server can carry the receipt under `com.ottoai/payment-response` exactly
|
|
23
|
+
* as the hosted server does — a receipt only the hosted path surfaced was the 0.1.1 local gap.
|
|
24
|
+
*/
|
|
25
|
+
readPaid?(definition: IntelToolDefinition, input: ToolArguments, options?: IntelReadOptions): Promise<IntelPaidRead>;
|
|
7
26
|
}
|
package/dist/data-source.js
CHANGED
|
@@ -86,10 +86,15 @@ export async function callDelegationAdminDefinition(runtime, run, rawInput, head
|
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
88
|
export function registerExecutionTools(server, runtime, admission) {
|
|
89
|
+
// The freshness window is stated in the description from the runtime's OWN config — never a literal:
|
|
90
|
+
// the 0.1.1 docs said "10 minutes" (the ceiling) while every hosted envelope carried 5 (the default),
|
|
91
|
+
// and a submit paced on the doc halts mid-plan with STALE_ARTIFACT.
|
|
92
|
+
const windowSeconds = Math.round(runtime.config.artifactTtlMs / 1000);
|
|
93
|
+
const freshness = ` Every envelope from this server is valid for ${windowSeconds} seconds from construction (valid_until); a stale envelope is refused by the verifier — request a fresh one.`;
|
|
89
94
|
for (const definition of EXECUTION_TOOL_DEFINITIONS) {
|
|
90
95
|
server.registerTool(definition.name, {
|
|
91
96
|
title: definition.title,
|
|
92
|
-
description: definition.description,
|
|
97
|
+
description: definition.description + freshness,
|
|
93
98
|
inputSchema: definition.inputSchema,
|
|
94
99
|
outputSchema: definition.outputSchema,
|
|
95
100
|
annotations: EXECUTION_TOOL_ANNOTATIONS,
|
package/dist/mcp-server.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
-
import type
|
|
2
|
+
import { type IntelDataSource } from './data-source.js';
|
|
3
3
|
import type { ExecutionToolRuntime } from './execution-tools.js';
|
|
4
4
|
export declare function createIntelMcpServer(dataSource: IntelDataSource, executionRuntime?: ExecutionToolRuntime): McpServer;
|
package/dist/mcp-server.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { PAYMENT_RECEIPT_META } from './data-source.js';
|
|
2
3
|
import { mapToolError } from './errors.js';
|
|
3
4
|
import { registerExecutionTools } from './execution-registration.js';
|
|
5
|
+
import { PACKAGE_VERSION } from './package-version.js';
|
|
4
6
|
import { TOOL_DEFINITIONS } from './tool-definitions.js';
|
|
5
7
|
const READ_ONLY_ANNOTATIONS = Object.freeze({
|
|
6
8
|
readOnlyHint: true,
|
|
@@ -14,6 +16,15 @@ function stringify(value) {
|
|
|
14
16
|
async function callDefinition(dataSource, definition, rawInput) {
|
|
15
17
|
const input = definition.inputSchema.parse(rawInput);
|
|
16
18
|
try {
|
|
19
|
+
if (dataSource.readPaid) {
|
|
20
|
+
const paid = await dataSource.readPaid(definition, input);
|
|
21
|
+
return {
|
|
22
|
+
content: [{ type: 'text', text: stringify(paid.value) }],
|
|
23
|
+
...(paid.receipt
|
|
24
|
+
? { _meta: { [PAYMENT_RECEIPT_META]: { header: paid.receipt.header, value: paid.receipt.value } } }
|
|
25
|
+
: {}),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
17
28
|
const result = await dataSource.read(definition, input);
|
|
18
29
|
return {
|
|
19
30
|
content: [{ type: 'text', text: stringify(result) }],
|
|
@@ -27,7 +38,7 @@ export function createIntelMcpServer(dataSource, executionRuntime) {
|
|
|
27
38
|
const server = new McpServer({
|
|
28
39
|
name: 'otto-intel',
|
|
29
40
|
title: 'Otto Intel',
|
|
30
|
-
version:
|
|
41
|
+
version: PACKAGE_VERSION,
|
|
31
42
|
});
|
|
32
43
|
for (const definition of TOOL_DEFINITIONS) {
|
|
33
44
|
server.registerTool(definition.name, {
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* package-version.ts — the version the servers announce in `serverInfo`, read from package.json so it
|
|
3
|
+
* cannot drift from what npm shows (0.1.1 on npm announced `0.1.0` in `initialize`). `dist/` sits one
|
|
4
|
+
* level below the package root in both the monorepo and the published tarball.
|
|
5
|
+
*/
|
|
6
|
+
export declare const PACKAGE_VERSION: string;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* package-version.ts — the version the servers announce in `serverInfo`, read from package.json so it
|
|
3
|
+
* cannot drift from what npm shows (0.1.1 on npm announced `0.1.0` in `initialize`). `dist/` sits one
|
|
4
|
+
* level below the package root in both the monorepo and the published tarball.
|
|
5
|
+
*/
|
|
6
|
+
import { readFileSync } from 'node:fs';
|
|
7
|
+
const pkg = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'));
|
|
8
|
+
export const PACKAGE_VERSION = pkg.version;
|
|
9
|
+
//# sourceMappingURL=package-version.js.map
|
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
import type { SelectPaymentRequirements } from '@x402/axios';
|
|
2
2
|
import type { LocalX402Config } from './local-config.js';
|
|
3
|
-
import type { IntelDataSource } from './data-source.js';
|
|
3
|
+
import type { IntelDataSource, IntelPaidRead } from './data-source.js';
|
|
4
4
|
import type { IntelToolDefinition, ToolArguments } from './tool-definitions.js';
|
|
5
|
+
/** Header names the paid rail may use for the settlement receipt, in precedence order (same set as the hosted proxy). */
|
|
6
|
+
export declare const SETTLEMENT_RECEIPT_HEADERS: readonly ["payment-response", "x-payment-response"];
|
|
5
7
|
export declare function boundedPaymentSelector(maxPaymentAtomic: bigint): SelectPaymentRequirements;
|
|
6
8
|
export declare class X402ReadSource implements IntelDataSource {
|
|
7
9
|
private readonly config;
|
|
8
10
|
private readonly scheme;
|
|
9
11
|
constructor(config: LocalX402Config);
|
|
10
12
|
read(definition: IntelToolDefinition, input: ToolArguments): Promise<unknown>;
|
|
13
|
+
/**
|
|
14
|
+
* The read plus the rail's settlement receipt, taken from the response header the rail used
|
|
15
|
+
* (`payment-response`, or the v1 `x-payment-response`) — relayed verbatim, never re-encoded.
|
|
16
|
+
*/
|
|
17
|
+
readPaid(definition: IntelToolDefinition, input: ToolArguments): Promise<IntelPaidRead>;
|
|
11
18
|
}
|
package/dist/x402-read-source.js
CHANGED
|
@@ -6,6 +6,8 @@ import { createPublicClient, http } from 'viem';
|
|
|
6
6
|
import { base } from 'viem/chains';
|
|
7
7
|
import { privateKeyToAccount } from 'viem/accounts';
|
|
8
8
|
import { WarmReadUnavailableError, X402PaymentError } from './errors.js';
|
|
9
|
+
/** Header names the paid rail may use for the settlement receipt, in precedence order (same set as the hosted proxy). */
|
|
10
|
+
export const SETTLEMENT_RECEIPT_HEADERS = ['payment-response', 'x-payment-response'];
|
|
9
11
|
const BASE_NETWORK = 'eip155:8453';
|
|
10
12
|
const BASE_USDC = '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913';
|
|
11
13
|
function amountOf(requirement) {
|
|
@@ -50,6 +52,13 @@ export class X402ReadSource {
|
|
|
50
52
|
this.scheme = new ExactEvmScheme(signer);
|
|
51
53
|
}
|
|
52
54
|
async read(definition, input) {
|
|
55
|
+
return (await this.readPaid(definition, input)).value;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* The read plus the rail's settlement receipt, taken from the response header the rail used
|
|
59
|
+
* (`payment-response`, or the v1 `x-payment-response`) — relayed verbatim, never re-encoded.
|
|
60
|
+
*/
|
|
61
|
+
async readPaid(definition, input) {
|
|
53
62
|
const paymentClient = new x402Client(boundedPaymentSelector(definition.maxPaymentAtomic));
|
|
54
63
|
paymentClient.register('eip155:*', this.scheme);
|
|
55
64
|
const httpClient = wrapAxiosWithPayment(axios.create({
|
|
@@ -62,7 +71,16 @@ export class X402ReadSource {
|
|
|
62
71
|
const response = await httpClient.get(definition.publicPath, {
|
|
63
72
|
params: definition.toQuery(input),
|
|
64
73
|
});
|
|
65
|
-
|
|
74
|
+
const receiptHeader = SETTLEMENT_RECEIPT_HEADERS.find((name) => {
|
|
75
|
+
const value = response.headers[name];
|
|
76
|
+
return typeof value === 'string' && value.length > 0;
|
|
77
|
+
});
|
|
78
|
+
return {
|
|
79
|
+
value: response.data,
|
|
80
|
+
...(receiptHeader
|
|
81
|
+
? { receipt: { header: receiptHeader, value: response.headers[receiptHeader] } }
|
|
82
|
+
: {}),
|
|
83
|
+
};
|
|
66
84
|
}
|
|
67
85
|
catch (error) {
|
|
68
86
|
if (axios.isAxiosError(error) && error.response?.status === 503) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "otto-intel-mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Otto AI market intelligence + execution constructors over MCP — hosted at mcp.ottoai.services (first call free, then pay per call in USDC via x402) or local via `npx otto-intel-mcp`. Library entries: otto-intel-mcp/execution, /adapter, /adapter-cdp.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"homepage": "https://docs.useotto.xyz/acp-swarm/otto-intel-mcp",
|
|
@@ -96,7 +96,9 @@
|
|
|
96
96
|
"dist/execution-delegation-admin-definition.js",
|
|
97
97
|
"dist/execution-delegation-admin-definition.d.ts",
|
|
98
98
|
"dist/boot-redaction.js",
|
|
99
|
-
"dist/boot-redaction.d.ts"
|
|
99
|
+
"dist/boot-redaction.d.ts",
|
|
100
|
+
"dist/package-version.js",
|
|
101
|
+
"dist/package-version.d.ts"
|
|
100
102
|
],
|
|
101
103
|
"scripts": {
|
|
102
104
|
"build": "tsc -p tsconfig.build.json",
|