@odatano/core-mcp 0.2.0 → 0.3.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/CHANGELOG.md +39 -0
- package/README.md +66 -41
- package/dist/client.d.ts +17 -3
- package/dist/client.js +38 -8
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +12 -8
- package/dist/config.js +4 -4
- package/dist/config.js.map +1 -1
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.js +4 -4
- package/dist/server.js.map +1 -1
- package/dist/tools/index.d.ts +3 -1
- package/dist/tools/shared.js +1 -1
- package/dist/tools/shared.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,45 @@ All notable changes to `@odatano/core-mcp` are documented in this file.
|
|
|
4
4
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
5
5
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [0.3.0] - 2026-09-20
|
|
8
|
+
|
|
9
|
+
### Changed (breaking)
|
|
10
|
+
|
|
11
|
+
- **One connection env for both ODATANO MCP servers.** `ODATANO_ACCESS_URL`
|
|
12
|
+
(default `https://api.odatano.dev`, the gateway), `ODATANO_ACCESS_KEY`
|
|
13
|
+
(the `oda_…` key, or an `odat_…` grant / other bearer against a direct
|
|
14
|
+
instance) and `ODATANO_ACCESS_USER` / `ODATANO_ACCESS_PASSWORD` (basic
|
|
15
|
+
auth for a direct instance) replace `ODATANO_BASE_URL`, `ODATANO_TOKEN`,
|
|
16
|
+
`ODATANO_USERNAME` and `ODATANO_PASSWORD`; the old names are not read
|
|
17
|
+
any more. `@odatano/nightgate-mcp` 0.7.0 reads the same four, so an
|
|
18
|
+
`.mcp.json` needs one key for both chains and no URL.
|
|
19
|
+
- **Gateway error bodies reach the agent.** The ODATANO ACCESS gateway
|
|
20
|
+
answers with `{ error: "<text>", ...detail }`; the client now keeps the
|
|
21
|
+
text as the message and hands the detail (`unitsLeft`, `price`, the
|
|
22
|
+
`topup` hint, `products`, `validUntil`, `retryAfterSeconds` from
|
|
23
|
+
`Retry-After`) through to the tool error, so a 402 says how to top up
|
|
24
|
+
instead of "request failed with HTTP 402".
|
|
25
|
+
- **The hosted API is the documented default.** README: quick start with a
|
|
26
|
+
key from api.odatano.dev first, own instance second; the startup line
|
|
27
|
+
tells "operator services are closed on the gateway" (403 on the probe,
|
|
28
|
+
`serviceStatus()`) from "core < 2.0 or unreachable", and warns when the
|
|
29
|
+
gateway is the target and no key is set. Server version constant follows
|
|
30
|
+
the package.
|
|
31
|
+
|
|
32
|
+
## [0.2.1] - 2026-09-19
|
|
33
|
+
|
|
34
|
+
### Changed
|
|
35
|
+
|
|
36
|
+
- **The ODATANO ACCESS key (`oda_…`) is the documented credential.** Set
|
|
37
|
+
`ODATANO_BASE_URL=https://api.odatano.dev` and `ODATANO_TOKEN=oda_…`; the
|
|
38
|
+
key goes as a plain `Authorization: Bearer` and the gateway swaps in the
|
|
39
|
+
agent grant, meters the key in units and fronts both ODATANO and
|
|
40
|
+
NIGHTGATE. Get one at `POST https://api.odatano.dev/keys` (x402), from a
|
|
41
|
+
giveaway code, or by signing in at the console. An `odat_…` grant
|
|
42
|
+
(`x-agent-token`) still works against a direct ODATANO instance. No code
|
|
43
|
+
change: the client already sent a prefix-less token as a bearer; a test
|
|
44
|
+
now pins that header shape.
|
|
45
|
+
|
|
7
46
|
## [0.2.0] - 2026-08-16
|
|
8
47
|
|
|
9
48
|
### Changed
|
package/README.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<picture>
|
|
3
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://cdn.jsdelivr.net/npm/@odatano/brand@1/logos/odatano-mcp-logo-on-dark.svg">
|
|
4
|
+
<img src="https://cdn.jsdelivr.net/npm/@odatano/brand@1/logos/odatano-mcp-logo.svg" alt="ODATANO MCP" height="84">
|
|
5
|
+
</picture>
|
|
6
|
+
</p>
|
|
7
|
+
|
|
1
8
|
# @odatano/core-mcp
|
|
2
9
|
|
|
3
10
|
[](https://www.npmjs.com/package/@odatano/core-mcp)
|
|
@@ -20,16 +27,55 @@ HSM signing (`SignWithHsm*`) and every Admin operation (crawler / worker
|
|
|
20
27
|
pause & resume) are deliberately not exposed. Wallet-worker jobs (ODATANO
|
|
21
28
|
2.0, server-managed wallets) are opt-in.
|
|
22
29
|
|
|
30
|
+
## Quick start: the hosted API
|
|
31
|
+
|
|
32
|
+
The usual way to run this server is against the hosted ODATANO ACCESS
|
|
33
|
+
gateway at [api.odatano.dev](https://api.odatano.dev): no node, no plugin,
|
|
34
|
+
no wallet of your own. One `oda_…` key covers Cardano (this server) and
|
|
35
|
+
Midnight (`@odatano/nightgate-mcp`).
|
|
36
|
+
|
|
37
|
+
1. Get a key at [api.odatano.dev](https://api.odatano.dev): sign in with a
|
|
38
|
+
Cardano wallet (the first key comes with free calls), redeem a giveaway
|
|
39
|
+
code, or buy a pack with tADA over x402 (`POST /keys`). The console shows
|
|
40
|
+
the key once, together with a ready `.mcp.json`.
|
|
41
|
+
2. Put the key in your MCP client's config:
|
|
42
|
+
|
|
43
|
+
```json
|
|
44
|
+
{
|
|
45
|
+
"mcpServers": {
|
|
46
|
+
"odatano": {
|
|
47
|
+
"command": "npx",
|
|
48
|
+
"args": ["-y", "@odatano/core-mcp"],
|
|
49
|
+
"env": { "ODATANO_ACCESS_KEY": "oda_..." }
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
or, with Claude Code: `claude mcp add odatano --env ODATANO_ACCESS_KEY=oda_... -- npx -y @odatano/core-mcp`
|
|
56
|
+
|
|
57
|
+
3. That is all: the gateway is the default URL. It sends the key as
|
|
58
|
+
`Authorization: Bearer`, swaps in the agent grant underneath and meters
|
|
59
|
+
the key per call (metadata and lookups of the service documents are free).
|
|
60
|
+
The hosted ODATANO runs on Cardano **preprod** today.
|
|
61
|
+
|
|
62
|
+
What the gateway does not offer, this server does not register: the
|
|
63
|
+
operator services (`cardano-worker`, `cardano-indexer`, agent grants) and
|
|
64
|
+
HSM signing answer 403 there, so the catalogue is the 36 core tools. A 402
|
|
65
|
+
from the gateway (units exhausted) reaches the agent with the top-up hint.
|
|
66
|
+
|
|
23
67
|
## Requirements
|
|
24
68
|
|
|
25
|
-
- Node.js >= 20
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
recommended** — earlier versions drop `$expand` / `$select` on keyed reads
|
|
29
|
-
(rc.2) and can answer a keyed read with a row the query excludes (rc.3);
|
|
30
|
-
`get_transaction` works around the former, the latter has no workaround.
|
|
69
|
+
- Node.js >= 20 (`npx` fetches the server, nothing to install)
|
|
70
|
+
|
|
71
|
+
## Run your own instance (optional)
|
|
31
72
|
|
|
32
|
-
|
|
73
|
+
Point `ODATANO_ACCESS_URL` at any ODATANO host app instead of the gateway:
|
|
74
|
+
`@odatano/core` >= 1.11.0; the worker / indexer tools appear automatically
|
|
75
|
+
on >= 2.0.0-rc.1, and **2.0.0-rc.3 or newer is recommended** (earlier
|
|
76
|
+
versions drop `$expand` / `$select` on keyed reads (rc.2) and can answer a
|
|
77
|
+
keyed read with a row the query excludes (rc.3); `get_transaction` works
|
|
78
|
+
around the former, the latter has no workaround).
|
|
33
79
|
|
|
34
80
|
The fastest way is the official Docker image (published from the ODATANO
|
|
35
81
|
repo on every release; details in its `docs/guides/DOCKER_DEPLOYMENT.md`):
|
|
@@ -44,22 +90,27 @@ docker run -d --name odatano -p 4004:4004 \
|
|
|
44
90
|
|
|
45
91
|
Alternatively any CAP app using the `@odatano/core` plugin works
|
|
46
92
|
(`npm i @odatano/core @cap-js/sqlite`, add `cds.requires.odatano-core`,
|
|
47
|
-
`cds watch`), e.g. the ODATANO repo itself.
|
|
93
|
+
`cds watch`), e.g. the ODATANO repo itself. Then:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
ODATANO_ACCESS_URL=http://localhost:4004
|
|
97
|
+
ODATANO_ACCESS_USER=alice # CAP mocked auth, or an odat_… agent grant as ODATANO_ACCESS_KEY
|
|
98
|
+
```
|
|
48
99
|
|
|
49
|
-
##
|
|
100
|
+
## Development setup
|
|
50
101
|
|
|
51
102
|
```bash
|
|
52
103
|
npm install
|
|
53
104
|
npm run build
|
|
54
105
|
```
|
|
55
106
|
|
|
56
|
-
Configuration is environment-driven:
|
|
107
|
+
Configuration is environment-driven (the same variables in an MCP client's `env` block):
|
|
57
108
|
|
|
58
109
|
| Variable | Default | Purpose |
|
|
59
110
|
|---|---|---|
|
|
60
|
-
| `
|
|
61
|
-
| `
|
|
62
|
-
| `
|
|
111
|
+
| `ODATANO_ACCESS_URL` | `https://api.odatano.dev` | The ODATANO ACCESS gateway, or a direct ODATANO host app (`http://localhost:4004` for `cds watch`) |
|
|
112
|
+
| `ODATANO_ACCESS_KEY` | unset | **The credential: an ODATANO ACCESS key `oda_…`** (sent as `Authorization: Bearer`; buy one at `POST https://api.odatano.dev/keys`, redeem a code, or sign in at the console). The same variable configures `@odatano/nightgate-mcp`. Against a direct ODATANO instance an `odat_…` agent-grant token (sent as `x-agent-token`) or any other bearer (XSUAA / `auth: jwt`) goes here too |
|
|
113
|
+
| `ODATANO_ACCESS_USER` / `ODATANO_ACCESS_PASSWORD` | unset | Basic auth against a direct instance, operator or CAP mocked/dev auth (e.g. `alice`); not for agents |
|
|
63
114
|
| `ODATANO_SERVICE_PREFIX` | `/odata/v4` | Prefix before `cardano-odata`, `cardano-transaction`, `cardano-sign`, `cardano-worker`, `cardano-indexer` |
|
|
64
115
|
| `ODATANO_TIMEOUT_MS` | `30000` | Per-request timeout |
|
|
65
116
|
| `ODATANO_MCP_MAX_ROWS` | `50` | Default `$top` for `query_entity` and cap on arrays in tool output |
|
|
@@ -69,32 +120,6 @@ At startup the server probes `<prefix>/cardano-worker/$metadata` and
|
|
|
69
120
|
`<prefix>/cardano-indexer/$metadata`; the 2.0 tools are registered only when
|
|
70
121
|
those services exist, so a 1.x host gets a clean 36-tool catalogue.
|
|
71
122
|
|
|
72
|
-
## Use with Claude Code
|
|
73
|
-
|
|
74
|
-
```bash
|
|
75
|
-
claude mcp add odatano \
|
|
76
|
-
--env ODATANO_BASE_URL=http://localhost:4004 \
|
|
77
|
-
--env ODATANO_USERNAME=alice \
|
|
78
|
-
-- npx -y @odatano/core-mcp
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
Or in a project `.mcp.json`:
|
|
82
|
-
|
|
83
|
-
```json
|
|
84
|
-
{
|
|
85
|
-
"mcpServers": {
|
|
86
|
-
"odatano": {
|
|
87
|
-
"command": "npx",
|
|
88
|
-
"args": ["-y", "@odatano/core-mcp"],
|
|
89
|
-
"env": {
|
|
90
|
-
"ODATANO_BASE_URL": "http://localhost:4004",
|
|
91
|
-
"ODATANO_USERNAME": "alice"
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
```
|
|
97
|
-
|
|
98
123
|
## Tools
|
|
99
124
|
|
|
100
125
|
### Read (`CardanoODataService`)
|
|
@@ -142,7 +167,7 @@ Every build returns `{ id, unsignedTxCbor, fee, … }` — **nothing is signed o
|
|
|
142
167
|
| `submit_verified_transaction` | Verify + submit for a signing request (`deferSubmit` supported) |
|
|
143
168
|
| `get_submission_status` | Submission state, optionally re-checking the chain |
|
|
144
169
|
|
|
145
|
-
### ODATANO 2.0 (registered when the
|
|
170
|
+
### ODATANO 2.0 (registered when the target serves them; closed on the gateway)
|
|
146
171
|
|
|
147
172
|
| Tool | What it does |
|
|
148
173
|
|---|---|
|
|
@@ -172,7 +197,7 @@ call. Optional live round-trip on preview (reads only; add
|
|
|
172
197
|
`ODATANO_TEST_BUILD=1` for one unsigned build that is parsed, never submitted):
|
|
173
198
|
|
|
174
199
|
```bash
|
|
175
|
-
ODATANO_LIVE=1
|
|
200
|
+
ODATANO_LIVE=1 ODATANO_ACCESS_URL=http://localhost:4004 ODATANO_ACCESS_USER=alice \
|
|
176
201
|
npm run integration
|
|
177
202
|
```
|
|
178
203
|
|
package/dist/client.d.ts
CHANGED
|
@@ -3,8 +3,19 @@ import { type OdatanoMcpConfig, type ServiceKey } from './config.js';
|
|
|
3
3
|
export declare class OdatanoApiError extends Error {
|
|
4
4
|
readonly status: number;
|
|
5
5
|
readonly code: string | undefined;
|
|
6
|
-
|
|
6
|
+
/** Extra fields of a gateway error body (unitsLeft, price, topup, products, validUntil, retryAfterSeconds). */
|
|
7
|
+
readonly detail?: Record<string, unknown> | undefined;
|
|
8
|
+
constructor(status: number, code: string | undefined, message: string,
|
|
9
|
+
/** Extra fields of a gateway error body (unitsLeft, price, topup, products, validUntil, retryAfterSeconds). */
|
|
10
|
+
detail?: Record<string, unknown> | undefined);
|
|
7
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* Two error shapes reach the client: CAP's `{ error: { code, message } }`
|
|
14
|
+
* from ODATANO itself, and the ODATANO ACCESS gateway's `{ error: "<text>",
|
|
15
|
+
* ...detail }` (401 key problems, 402 units exhausted with a top-up hint,
|
|
16
|
+
* 403 closed service or product not on the key, 429 with Retry-After).
|
|
17
|
+
*/
|
|
18
|
+
export declare function apiError(status: number, payload: unknown, headers: Headers, fallback: string): OdatanoApiError;
|
|
8
19
|
/** OData system query options accepted by {@link OdatanoClient.queryEntity}. */
|
|
9
20
|
export interface EntityQuery {
|
|
10
21
|
filter?: string;
|
|
@@ -38,9 +49,12 @@ export declare class OdatanoClient {
|
|
|
38
49
|
readEntity(service: ServiceKey, entity: string, key: string, expand?: string): Promise<unknown>;
|
|
39
50
|
/**
|
|
40
51
|
* Cheap capability probe: does `<service>/$metadata` answer 200? Used at
|
|
41
|
-
* startup to register the v2.0 worker/indexer tools only when
|
|
42
|
-
*
|
|
52
|
+
* startup to register the v2.0 worker/indexer tools only when they are
|
|
53
|
+
* reachable. `closed` = the ODATANO ACCESS gateway answers 403 (operator
|
|
54
|
+
* services are not offered through the key), `absent` = 404 or no answer
|
|
55
|
+
* (core < 2.0, unreachable).
|
|
43
56
|
*/
|
|
57
|
+
serviceStatus(service: ServiceKey): Promise<'served' | 'closed' | 'absent'>;
|
|
44
58
|
serviceExists(service: ServiceKey): Promise<boolean>;
|
|
45
59
|
private headers;
|
|
46
60
|
private request;
|
package/dist/client.js
CHANGED
|
@@ -3,13 +3,37 @@ import { SERVICES } from './config.js';
|
|
|
3
3
|
export class OdatanoApiError extends Error {
|
|
4
4
|
status;
|
|
5
5
|
code;
|
|
6
|
-
|
|
6
|
+
detail;
|
|
7
|
+
constructor(status, code, message,
|
|
8
|
+
/** Extra fields of a gateway error body (unitsLeft, price, topup, products, validUntil, retryAfterSeconds). */
|
|
9
|
+
detail) {
|
|
7
10
|
super(message);
|
|
8
11
|
this.status = status;
|
|
9
12
|
this.code = code;
|
|
13
|
+
this.detail = detail;
|
|
10
14
|
this.name = 'OdatanoApiError';
|
|
11
15
|
}
|
|
12
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* Two error shapes reach the client: CAP's `{ error: { code, message } }`
|
|
19
|
+
* from ODATANO itself, and the ODATANO ACCESS gateway's `{ error: "<text>",
|
|
20
|
+
* ...detail }` (401 key problems, 402 units exhausted with a top-up hint,
|
|
21
|
+
* 403 closed service or product not on the key, 429 with Retry-After).
|
|
22
|
+
*/
|
|
23
|
+
export function apiError(status, payload, headers, fallback) {
|
|
24
|
+
const body = (payload && typeof payload === 'object' ? payload : {});
|
|
25
|
+
const err = body.error;
|
|
26
|
+
if (typeof err === 'string') {
|
|
27
|
+
const { error: _e, ...rest } = body;
|
|
28
|
+
const detail = { ...rest };
|
|
29
|
+
const retry = headers.get('retry-after');
|
|
30
|
+
if (retry)
|
|
31
|
+
detail.retryAfterSeconds = Number(retry);
|
|
32
|
+
return new OdatanoApiError(status, undefined, err, Object.keys(detail).length ? detail : undefined);
|
|
33
|
+
}
|
|
34
|
+
const e = (err ?? {});
|
|
35
|
+
return new OdatanoApiError(status, e.code, e.message ?? fallback);
|
|
36
|
+
}
|
|
13
37
|
/**
|
|
14
38
|
* Minimal OData V4 client for the ODATANO services. Three verbs:
|
|
15
39
|
* - unbound actions (POST, JSON body) — all ODATANO read/build/sign operations
|
|
@@ -62,10 +86,12 @@ export class OdatanoClient {
|
|
|
62
86
|
}
|
|
63
87
|
/**
|
|
64
88
|
* Cheap capability probe: does `<service>/$metadata` answer 200? Used at
|
|
65
|
-
* startup to register the v2.0 worker/indexer tools only when
|
|
66
|
-
*
|
|
89
|
+
* startup to register the v2.0 worker/indexer tools only when they are
|
|
90
|
+
* reachable. `closed` = the ODATANO ACCESS gateway answers 403 (operator
|
|
91
|
+
* services are not offered through the key), `absent` = 404 or no answer
|
|
92
|
+
* (core < 2.0, unreachable).
|
|
67
93
|
*/
|
|
68
|
-
async
|
|
94
|
+
async serviceStatus(service) {
|
|
69
95
|
try {
|
|
70
96
|
const response = await fetch(`${this.serviceUrl(service)}/$metadata`, {
|
|
71
97
|
method: 'GET',
|
|
@@ -74,12 +100,17 @@ export class OdatanoClient {
|
|
|
74
100
|
});
|
|
75
101
|
// Consume the body so the socket is released.
|
|
76
102
|
await response.arrayBuffer().catch(() => undefined);
|
|
77
|
-
|
|
103
|
+
if (response.ok)
|
|
104
|
+
return 'served';
|
|
105
|
+
return response.status === 403 ? 'closed' : 'absent';
|
|
78
106
|
}
|
|
79
107
|
catch {
|
|
80
|
-
return
|
|
108
|
+
return 'absent';
|
|
81
109
|
}
|
|
82
110
|
}
|
|
111
|
+
async serviceExists(service) {
|
|
112
|
+
return (await this.serviceStatus(service)) === 'served';
|
|
113
|
+
}
|
|
83
114
|
headers(hasBody = false) {
|
|
84
115
|
const headers = { Accept: 'application/json' };
|
|
85
116
|
const basic = this.config.username
|
|
@@ -118,8 +149,7 @@ export class OdatanoClient {
|
|
|
118
149
|
payload = { raw: text };
|
|
119
150
|
}
|
|
120
151
|
if (!response.ok) {
|
|
121
|
-
|
|
122
|
-
throw new OdatanoApiError(response.status, err?.code, err?.message ?? `ODATANO request failed with HTTP ${response.status}`);
|
|
152
|
+
throw apiError(response.status, payload, response.headers, `ODATANO request failed with HTTP ${response.status}`);
|
|
123
153
|
}
|
|
124
154
|
return stripODataNoise(payload);
|
|
125
155
|
}
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAA0C,MAAM,aAAa,CAAC;AAE/E,oEAAoE;AACpE,MAAM,OAAO,eAAgB,SAAQ,KAAK;IAEtB;IACA;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
CHANGED
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Server configuration, environment-driven
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Server configuration, environment-driven. The connection variables are the
|
|
3
|
+
* same for every ODATANO MCP server (ODATANO_ACCESS_*): one key from
|
|
4
|
+
* https://api.odatano.dev configures the Cardano and the Midnight server alike.
|
|
5
|
+
* A direct ODATANO instance (local `cds watch`, an own deployment) is reached
|
|
6
|
+
* by pointing ODATANO_ACCESS_URL at it.
|
|
5
7
|
*/
|
|
6
8
|
export interface OdatanoMcpConfig {
|
|
7
|
-
/** Base URL
|
|
9
|
+
/** Base URL: the ODATANO ACCESS gateway (default https://api.odatano.dev) or a direct ODATANO host app. */
|
|
8
10
|
baseUrl: string;
|
|
9
11
|
/**
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
12
|
+
* ODATANO_ACCESS_KEY. The usual value is an ODATANO ACCESS key (`oda_...`),
|
|
13
|
+
* sent as `Authorization: Bearer`; the gateway swaps in the agent grant.
|
|
14
|
+
* Against a direct ODATANO instance an `odat_...` agent-grant token goes as
|
|
15
|
+
* `x-agent-token` (optionally alongside basic transport auth); anything
|
|
16
|
+
* else is a plain bearer (XSUAA / `auth: jwt`).
|
|
13
17
|
*/
|
|
14
18
|
token?: string;
|
|
15
|
-
/**
|
|
19
|
+
/** ODATANO_ACCESS_USER / _PASSWORD: basic auth for a direct instance (CAP mocked/dev auth, e.g. `alice`); never for agents. */
|
|
16
20
|
username?: string;
|
|
17
21
|
password?: string;
|
|
18
22
|
/** Prefix in front of the service names, default `/odata/v4`. */
|
package/dist/config.js
CHANGED
|
@@ -21,16 +21,16 @@ function bool(raw) {
|
|
|
21
21
|
return ['1', 'true', 'yes', 'on'].includes(raw.trim().toLowerCase());
|
|
22
22
|
}
|
|
23
23
|
export function loadConfig(env = process.env) {
|
|
24
|
-
const baseUrl = (env.
|
|
24
|
+
const baseUrl = (env.ODATANO_ACCESS_URL || 'https://api.odatano.dev').replace(/\/+$/, '');
|
|
25
25
|
let servicePrefix = env.ODATANO_SERVICE_PREFIX ?? '/odata/v4';
|
|
26
26
|
if (!servicePrefix.startsWith('/'))
|
|
27
27
|
servicePrefix = `/${servicePrefix}`;
|
|
28
28
|
servicePrefix = servicePrefix.replace(/\/+$/, '');
|
|
29
29
|
return {
|
|
30
30
|
baseUrl,
|
|
31
|
-
token: env.
|
|
32
|
-
username: env.
|
|
33
|
-
password: env.
|
|
31
|
+
token: env.ODATANO_ACCESS_KEY || undefined,
|
|
32
|
+
username: env.ODATANO_ACCESS_USER || undefined,
|
|
33
|
+
password: env.ODATANO_ACCESS_PASSWORD || undefined,
|
|
34
34
|
servicePrefix,
|
|
35
35
|
timeoutMs: positiveInt('ODATANO_TIMEOUT_MS', env.ODATANO_TIMEOUT_MS, 30000),
|
|
36
36
|
maxRows: positiveInt('ODATANO_MCP_MAX_ROWS', env.ODATANO_MCP_MAX_ROWS, 50),
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AA+BA,8DAA8D;AAC9D,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,KAAK,EAAE,eAAe;IACtB,WAAW,EAAE,qBAAqB;IAClC,IAAI,EAAE,cAAc;IACpB,MAAM,EAAE,gBAAgB;IACxB,OAAO,EAAE,iBAAiB;CAClB,CAAC;AAIX,SAAS,WAAW,CAAC,IAAY,EAAE,GAAuB,EAAE,QAAgB;IAC1E,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,EAAE;QAAE,OAAO,QAAQ,CAAC;IACrD,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IACtB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1D,MAAM,IAAI,KAAK,CAAC,WAAW,IAAI,KAAK,GAAG,EAAE,CAAC,CAAC;IAC7C,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAS,IAAI,CAAC,GAAuB;IACnC,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACpC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAyB,OAAO,CAAC,GAAG;IAC7D,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,kBAAkB,IAAI,yBAAyB,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC1F,IAAI,aAAa,GAAG,GAAG,CAAC,sBAAsB,IAAI,WAAW,CAAC;IAC9D,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,aAAa,GAAG,IAAI,aAAa,EAAE,CAAC;IACxE,aAAa,GAAG,aAAa,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAClD,OAAO;QACL,OAAO;QACP,KAAK,EAAE,GAAG,CAAC,kBAAkB,IAAI,SAAS;QAC1C,QAAQ,EAAE,GAAG,CAAC,mBAAmB,IAAI,SAAS;QAC9C,QAAQ,EAAE,GAAG,CAAC,uBAAuB,IAAI,SAAS;QAClD,aAAa;QACb,SAAS,EAAE,WAAW,CAAC,oBAAoB,EAAE,GAAG,CAAC,kBAAkB,EAAE,KAAK,CAAC;QAC3E,OAAO,EAAE,WAAW,CAAC,sBAAsB,EAAE,GAAG,CAAC,oBAAoB,EAAE,EAAE,CAAC;QAC1E,gBAAgB,EAAE,IAAI,CAAC,GAAG,CAAC,8BAA8B,CAAC;KAC3D,CAAC;AACJ,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -6,10 +6,14 @@ import { buildServer, detectCapabilities } from './server.js';
|
|
|
6
6
|
async function main() {
|
|
7
7
|
const config = loadConfig();
|
|
8
8
|
const client = new OdatanoClient(config);
|
|
9
|
+
// stdio transport: stdout is the protocol channel, diagnostics go to stderr
|
|
10
|
+
if (!config.token && !config.username && /api.odatano.dev$/.test(config.baseUrl)) {
|
|
11
|
+
console.error('odatano-mcp: ODATANO_ACCESS_KEY is not set; api.odatano.dev answers 401 without a key (sign in, redeem a code or buy a pack at https://api.odatano.dev)');
|
|
12
|
+
}
|
|
9
13
|
const caps = await detectCapabilities(client);
|
|
10
14
|
const server = buildServer(config, caps);
|
|
11
|
-
|
|
12
|
-
|
|
15
|
+
const optional = [caps.worker && 'worker', caps.indexer && 'indexer'].filter(Boolean).join(', ')
|
|
16
|
+
|| (caps.closed ? 'none (operator services are closed on the gateway)' : 'none (core < 2.0 or unreachable)');
|
|
13
17
|
console.error(`odatano-mcp: connecting tools to ${config.baseUrl}${config.servicePrefix} (v2.0 services: ${optional}` +
|
|
14
18
|
`${caps.worker && config.enableWalletJobs ? '; wallet jobs ENABLED' : ''})`);
|
|
15
19
|
await server.connect(new StdioServerTransport());
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAE9D,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,MAAM,CAAC,CAAC;IACzC,MAAM,IAAI,GAAG,MAAM,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACzC,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAE9D,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,MAAM,CAAC,CAAC;IACzC,4EAA4E;IAC5E,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QACjF,OAAO,CAAC,KAAK,CAAC,yJAAyJ,CAAC,CAAC;IAC3K,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACzC,MAAM,QAAQ,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,QAAQ,EAAE,IAAI,CAAC,OAAO,IAAI,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;WAC3F,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,oDAAoD,CAAC,CAAC,CAAC,kCAAkC,CAAC,CAAC;IAC/G,OAAO,CAAC,KAAK,CAAC,oCAAoC,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,aAAa,oBAAoB,QAAQ,EAAE;QACnH,GAAG,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC/E,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,oBAAoB,EAAE,CAAC,CAAC;AACnD,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,GAAG,CAAC,CAAC;IACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
package/dist/server.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
|
2
2
|
import { OdatanoClient } from './client.js';
|
|
3
3
|
import type { OdatanoMcpConfig } from './config.js';
|
|
4
4
|
import { type Capabilities } from './tools/index.js';
|
|
5
|
-
export declare const SERVER_VERSION = "0.
|
|
5
|
+
export declare const SERVER_VERSION = "0.3.0";
|
|
6
6
|
/**
|
|
7
7
|
* Probe which optional (v2.0) services the host serves. Both probes run in
|
|
8
8
|
* parallel and never throw; an unreachable host simply yields no v2.0 tools
|
package/dist/server.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
2
|
import { OdatanoClient } from './client.js';
|
|
3
3
|
import { registerTools } from './tools/index.js';
|
|
4
|
-
export const SERVER_VERSION = '0.
|
|
4
|
+
export const SERVER_VERSION = '0.3.0';
|
|
5
5
|
/**
|
|
6
6
|
* Probe which optional (v2.0) services the host serves. Both probes run in
|
|
7
7
|
* parallel and never throw; an unreachable host simply yields no v2.0 tools
|
|
@@ -9,10 +9,10 @@ export const SERVER_VERSION = '0.1.0';
|
|
|
9
9
|
*/
|
|
10
10
|
export async function detectCapabilities(client) {
|
|
11
11
|
const [worker, indexer] = await Promise.all([
|
|
12
|
-
client.
|
|
13
|
-
client.
|
|
12
|
+
client.serviceStatus('worker'),
|
|
13
|
+
client.serviceStatus('indexer'),
|
|
14
14
|
]);
|
|
15
|
-
return { worker, indexer };
|
|
15
|
+
return { worker: worker === 'served', indexer: indexer === 'served', closed: worker === 'closed' || indexer === 'closed' };
|
|
16
16
|
}
|
|
17
17
|
/**
|
|
18
18
|
* Build the MCP server with all tools registered; transport is the caller's
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAE,aAAa,EAAqB,MAAM,kBAAkB,CAAC;AAEpE,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC;AAEtC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,MAAqB;IAC5D,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC1C,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC;QAC9B,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC;KAChC,CAAC,CAAC;IACH,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAE,aAAa,EAAqB,MAAM,kBAAkB,CAAC;AAEpE,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC;AAEtC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,MAAqB;IAC5D,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC1C,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC;QAC9B,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC;KAChC,CAAC,CAAC;IACH,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,QAAQ,EAAE,OAAO,EAAE,OAAO,KAAK,QAAQ,EAAE,MAAM,EAAE,MAAM,KAAK,QAAQ,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;AAC7H,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,MAAwB,EAAE,OAAqB,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE;IAC1G,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,CAAC;IAC3E,aAAa,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,IAAI,aAAa,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,CAAC;IAC3E,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/dist/tools/index.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
2
|
import { type QueryCapabilities } from './query.js';
|
|
3
3
|
import type { ToolContext } from './shared.js';
|
|
4
|
-
export type Capabilities = QueryCapabilities
|
|
4
|
+
export type Capabilities = QueryCapabilities & {
|
|
5
|
+
closed?: boolean;
|
|
6
|
+
};
|
|
5
7
|
/**
|
|
6
8
|
* Register the tool catalogue. Reads, generic query, unsigned builds and the
|
|
7
9
|
* signing handoff are always present; the v2.0 worker / indexer tools only
|
package/dist/tools/shared.js
CHANGED
|
@@ -30,7 +30,7 @@ export function makeRunner(ctx) {
|
|
|
30
30
|
const body = { alreadySubmitted: true, httpStatus: 409, code: err.code, message: err.message };
|
|
31
31
|
return { content: [{ type: 'text', text: JSON.stringify(body, null, 2) }] };
|
|
32
32
|
}
|
|
33
|
-
const detail = { httpStatus: err.status, code: err.code ?? null, message: err.message };
|
|
33
|
+
const detail = { httpStatus: err.status, code: err.code ?? null, message: err.message, ...(err.detail ?? {}) };
|
|
34
34
|
return { content: [{ type: 'text', text: JSON.stringify(detail, null, 2) }], isError: true };
|
|
35
35
|
}
|
|
36
36
|
const message = err instanceof Error ? err.message : String(err);
|
package/dist/tools/shared.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/tools/shared.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAsB,MAAM,cAAc,CAAC;AAEnE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAmBpD,+DAA+D;AAC/D,MAAM,CAAC,MAAM,aAAa,GACxB,2FAA2F;IAC3F,0GAA0G,CAAC;AAE7G,MAAM,CAAC,MAAM,SAAS,GAAG,4EAA4E,CAAC;AAEtG;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CAAC,GAAgB;IACzC,OAAO,SAAS,GAAG,CAAI,EAAiC,EAAE,OAAsB,EAAE;QAChF,OAAO,KAAK,EAAE,IAAO,EAAuB,EAAE;YAC5C,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC;gBAC3B,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;gBACzF,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;YAChF,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,GAAG,YAAY,eAAe,EAAE,CAAC;oBACnC,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;wBAC1C,MAAM,IAAI,GAAG,QAAQ,CAAC,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;wBAC1E,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;oBAC9E,CAAC;oBACD,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,IAAI,KAAK,8BAA8B,EAAE,CAAC;wBACtE,MAAM,IAAI,GAAG,EAAE,gBAAgB,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC;wBAC/F,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;oBAC9E,CAAC;oBACD,MAAM,MAAM,GAAG,EAAE,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/tools/shared.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@odatano/core-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "MCP server exposing ODATANO (Cardano OData bridge, SAP CAP) to AI agents: reads, unsigned tx builds, signing handoff, submit",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"publishConfig": {
|