@panoptic-eng/mcp 0.1.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 +86 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +20 -0
- package/dist/index.d.ts +94 -0
- package/dist/index.js +3 -0
- package/dist/server--YF2LHqv.js +1140 -0
- package/package.json +54 -0
package/README.md
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# @panoptic-eng/mcp
|
|
2
|
+
|
|
3
|
+
A local [Model Context Protocol](https://modelcontextprotocol.io) server that
|
|
4
|
+
exposes the Panoptic SDK to AI agents as read-only analytics tools. It runs
|
|
5
|
+
as a stdio process against **your own RPC endpoint** — zero infra, zero auth, no
|
|
6
|
+
private keys. The server only reads on-chain state; it never signs or sends
|
|
7
|
+
transactions. Build/simulate tools that return **unsigned transaction
|
|
8
|
+
envelopes** are planned for a future release (see the spec).
|
|
9
|
+
|
|
10
|
+
See `packages/sdk/mcp-spec.md` for the full specification and roadmap.
|
|
11
|
+
|
|
12
|
+
## Quickstart
|
|
13
|
+
|
|
14
|
+
Every MCP client accepts the same `command` / `args` / `env` shape; only the
|
|
15
|
+
config file location differs (Claude Code/Desktop use `.mcp.json`, Cursor uses
|
|
16
|
+
its MCP settings, etc.).
|
|
17
|
+
|
|
18
|
+
```jsonc
|
|
19
|
+
{
|
|
20
|
+
"mcpServers": {
|
|
21
|
+
"panoptic": {
|
|
22
|
+
"command": "npx",
|
|
23
|
+
"args": ["-y", "@panoptic-eng/mcp"],
|
|
24
|
+
"env": {
|
|
25
|
+
"PANOPTIC_RPC_URL": "https://mainnet.base.org",
|
|
26
|
+
"PANOPTIC_CHAIN_ID": "8453",
|
|
27
|
+
// optional — enables enhanced analytics tools
|
|
28
|
+
"PANOPTIC_SUBGRAPH_URL": ""
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Configuration may also be passed as CLI flags, which override the env vars:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npx @panoptic-eng/mcp --rpc-url https://mainnet.base.org --chain-id 8453
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Supported chains: Ethereum mainnet (`1`), Base (`8453`), Sepolia (`11155111`).
|
|
42
|
+
|
|
43
|
+
## v0 tools (read-only, pure RPC)
|
|
44
|
+
|
|
45
|
+
| Tool | What it does |
|
|
46
|
+
| --- | --- |
|
|
47
|
+
| `list_pools` | Known pool deployment + live pool state (tokens, tick, trackers, health). |
|
|
48
|
+
| `explain_position` | Decode a TokenId into readable legs + a strategy label (no RPC). |
|
|
49
|
+
| `identify_address` | Map an address to its role in a Panoptic deployment. |
|
|
50
|
+
| `get_portfolio` | An account's open positions, collateral, and net greeks. |
|
|
51
|
+
| `account_health` | Buying power, margin buffer, and liquidation status. |
|
|
52
|
+
| `liquidity_map` | Tick liquidity distribution around the current tick. |
|
|
53
|
+
| `chunk_spread` | Per-chunk spread multiplier (via `scanChunks`): ~1.0x chunks are cheapest to BUY (lowest IV), high-multiplier chunks are most profitable to SELL. Width defaults to a standard timescale (`STANDARD_TICK_WIDTHS`). |
|
|
54
|
+
| `suggest_delta_hedge` | Net delta (positions + collateral) and a width=0 loan/credit leg sized to neutralize it. |
|
|
55
|
+
| `advise_position` | Live facts + management advice for a position (ITM/OTM, streamia, closeable-now, liquidation risk). |
|
|
56
|
+
| `preview_position` | Pre-trade quote (dry-run `eth_call`): collateral required, post-mint balances, solvency, for a given tokenId + size. |
|
|
57
|
+
| `position_scenario` | Payoff / NLV curve — net liquidation value across a band of hypothetical prices. |
|
|
58
|
+
| `hedge_params` | SDK-native delta-hedge parameters (`getDeltaHedgeParams`) to reach a target delta; whole-portfolio or single-position. |
|
|
59
|
+
| `trade_history` | Chronological mints/burns from on-chain events (event-level only — no realized P&L). |
|
|
60
|
+
|
|
61
|
+
`get_portfolio`, `account_health`, `suggest_delta_hedge`, `advise_position`,
|
|
62
|
+
`preview_position`, `position_scenario`, and `hedge_params` discover positions
|
|
63
|
+
via an on-chain event scan (the SDK's `syncPositions`) — no subgraph required.
|
|
64
|
+
Pass `fromBlock` to bound the scan on chains with a distant deployment block.
|
|
65
|
+
These account tools need an RPC that permits `eth_getLogs`; many free public
|
|
66
|
+
endpoints throttle or block large log scans, so a private RPC is recommended.
|
|
67
|
+
|
|
68
|
+
Build + simulate tools (`build_position`, `build_strategy`, `simulate_tx`, …)
|
|
69
|
+
that return unsigned transaction envelopes are planned for a future release and
|
|
70
|
+
are **not** shipped yet. All numeric on-chain quantities are serialized as
|
|
71
|
+
**decimal strings**.
|
|
72
|
+
|
|
73
|
+
## Development
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
pnpm --filter @panoptic-eng/mcp build # tsdown → dist/
|
|
77
|
+
pnpm --filter @panoptic-eng/mcp test # vitest
|
|
78
|
+
pnpm --filter @panoptic-eng/mcp typecheck # tsc --noEmit
|
|
79
|
+
pnpm --filter @panoptic-eng/mcp lint
|
|
80
|
+
|
|
81
|
+
# Inspect locally against a real RPC:
|
|
82
|
+
PANOPTIC_RPC_URL=https://mainnet.base.org PANOPTIC_CHAIN_ID=8453 \
|
|
83
|
+
npx @modelcontextprotocol/inspector node dist/cli.js
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
The server depends on `@panoptic-eng/sdk`; the SDK never depends on it.
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { SERVER_VERSION, createContext, createServer, resolveConfig } from "./server--YF2LHqv.js";
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
|
|
5
|
+
//#region src/cli.ts
|
|
6
|
+
async function main() {
|
|
7
|
+
const config = resolveConfig(process.argv.slice(2), process.env);
|
|
8
|
+
const ctx = await createContext(config);
|
|
9
|
+
const server = createServer(ctx);
|
|
10
|
+
const transport = new StdioServerTransport();
|
|
11
|
+
await server.connect(transport);
|
|
12
|
+
console.error(`panoptic-mcp v${SERVER_VERSION} ready (chain ${config.chainId})`);
|
|
13
|
+
}
|
|
14
|
+
main().catch((err) => {
|
|
15
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
16
|
+
console.error(`panoptic-mcp failed to start: ${message}`);
|
|
17
|
+
process.exit(1);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
//#endregion
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { ChainDeployment } from "@panoptic-eng/sdk/v2";
|
|
3
|
+
import { Address, Hex, PublicClient } from "viem";
|
|
4
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
5
|
+
|
|
6
|
+
//#region src/config.d.ts
|
|
7
|
+
/** Chain ids Panoptic has deployments for (mainnet, Base, Sepolia). */
|
|
8
|
+
/** Chain ids Panoptic has deployments for (mainnet, Base, Sepolia). */
|
|
9
|
+
declare const KNOWN_CHAIN_IDS: readonly [1, 8453, 11155111];
|
|
10
|
+
/**
|
|
11
|
+
* Resolve an optional user-supplied chain-id string to a trusted known-chain
|
|
12
|
+
* constant, falling back to `fallback` when omitted/blank. Matches on canonical
|
|
13
|
+
* decimal form only (never Number(), so "1e0" is rejected) and throws on
|
|
14
|
+
* unsupported ids.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
interface ServerConfig {
|
|
18
|
+
rpcUrl: string;
|
|
19
|
+
chainId: number;
|
|
20
|
+
/** Optional indexer URL; enables enhanced analytics tools. */
|
|
21
|
+
subgraphUrl?: string;
|
|
22
|
+
}
|
|
23
|
+
interface PanopticContext {
|
|
24
|
+
config: ServerConfig;
|
|
25
|
+
client: PublicClient;
|
|
26
|
+
deployment: ChainDeployment;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Resolve server config from CLI flags (`--rpc-url`, `--chain-id`,
|
|
30
|
+
* `--subgraph-url`) layered over env (`PANOPTIC_RPC_URL`, `PANOPTIC_CHAIN_ID`,
|
|
31
|
+
* `PANOPTIC_SUBGRAPH_URL`). CLI flags win. Throws a readable error when RPC URL
|
|
32
|
+
* or chain id is missing or unsupported.
|
|
33
|
+
*/
|
|
34
|
+
declare function resolveConfig(argv: string[], env: NodeJS.ProcessEnv): ServerConfig;
|
|
35
|
+
/** Create the shared context (viem client + resolved deployment) for tools. */
|
|
36
|
+
declare function createContext(config: ServerConfig): Promise<PanopticContext>;
|
|
37
|
+
|
|
38
|
+
//#endregion
|
|
39
|
+
//#region src/serialize.d.ts
|
|
40
|
+
/**
|
|
41
|
+
* Recursively convert a value into a JSON-safe form. The only Panoptic-specific
|
|
42
|
+
* invariant here: **bigints become decimal strings** (never JS numbers), so
|
|
43
|
+
* on-chain quantities survive serialization without precision loss. Functions
|
|
44
|
+
* are dropped; everything else passes through. `_meta` blocks are ordinary
|
|
45
|
+
* nested objects and are handled by the recursion.
|
|
46
|
+
*/
|
|
47
|
+
declare function toJsonSafe(value: unknown): unknown;
|
|
48
|
+
/** MCP tool result wrapping a serialized value as pretty JSON text. */
|
|
49
|
+
declare function jsonResult(value: unknown): {
|
|
50
|
+
content: {
|
|
51
|
+
type: 'text';
|
|
52
|
+
text: string;
|
|
53
|
+
}[];
|
|
54
|
+
};
|
|
55
|
+
type EnvelopeRisk = 'defined' | 'undefined' | 'info';
|
|
56
|
+
interface UnsignedTxEnvelopeInput {
|
|
57
|
+
summary: string;
|
|
58
|
+
risk: EnvelopeRisk;
|
|
59
|
+
chainId: number | bigint;
|
|
60
|
+
to: Address;
|
|
61
|
+
value: bigint;
|
|
62
|
+
data: Hex;
|
|
63
|
+
simulation?: unknown;
|
|
64
|
+
}
|
|
65
|
+
interface UnsignedTxEnvelope {
|
|
66
|
+
summary: string;
|
|
67
|
+
risk: EnvelopeRisk;
|
|
68
|
+
chainId: string;
|
|
69
|
+
to: Address;
|
|
70
|
+
value: string;
|
|
71
|
+
data: Hex;
|
|
72
|
+
simulation?: unknown;
|
|
73
|
+
envelopeHash: Hex;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Build the unsigned transaction envelope every build/write-like tool returns.
|
|
77
|
+
* The server never signs; it hands back this object plus `envelopeHash` so a
|
|
78
|
+
* downstream signer can verify it signs exactly what was simulated and shown.
|
|
79
|
+
*/
|
|
80
|
+
declare function buildEnvelope(input: UnsignedTxEnvelopeInput): UnsignedTxEnvelope;
|
|
81
|
+
|
|
82
|
+
//#endregion
|
|
83
|
+
//#region src/server.d.ts
|
|
84
|
+
declare const SERVER_NAME = "panoptic-mcp";
|
|
85
|
+
declare const SERVER_VERSION: string;
|
|
86
|
+
/**
|
|
87
|
+
* Build the Panoptic MCP server and register the v0 read-only tool catalog.
|
|
88
|
+
* The transport (stdio locally; HTTP for a future hosted server) is wired by
|
|
89
|
+
* the caller, so this factory is reusable across surfaces.
|
|
90
|
+
*/
|
|
91
|
+
declare function createServer(ctx: PanopticContext): McpServer;
|
|
92
|
+
|
|
93
|
+
//#endregion
|
|
94
|
+
export { KNOWN_CHAIN_IDS, PanopticContext, SERVER_NAME, SERVER_VERSION, ServerConfig, UnsignedTxEnvelope, buildEnvelope, createContext, createServer, jsonResult, resolveConfig, toJsonSafe };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { KNOWN_CHAIN_IDS, SERVER_NAME, SERVER_VERSION, buildEnvelope, createContext, createServer, jsonResult, resolveConfig, toJsonSafe } from "./server--YF2LHqv.js";
|
|
2
|
+
|
|
3
|
+
export { KNOWN_CHAIN_IDS, SERVER_NAME, SERVER_VERSION, buildEnvelope, createContext, createServer, jsonResult, resolveConfig, toJsonSafe };
|