jev-decision-mcp 0.1.0 → 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 +89 -42
- package/dist/schema.js +10 -3
- package/dist/server.js +1 -1
- package/package.json +1 -1
- package/server.json +2 -2
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Jev Decision MCP
|
|
2
2
|
|
|
3
|
+
[](https://glama.ai/mcp/servers/amidabuddha/jev-decision-mcp)
|
|
4
|
+
|
|
3
5
|
A local stdio MCP server exposing one tool, **`jev_decide`**, for typed decisions through the official TypeSafe API. Written in TypeScript with the official MCP and TypeSafe SDKs.
|
|
4
6
|
|
|
5
7
|
Independent community project; not affiliated with TypeSafe. Licensed under [MIT](LICENSE).
|
|
@@ -12,7 +14,56 @@ Independent community project; not affiliated with TypeSafe. Licensed under [MIT
|
|
|
12
14
|
|
|
13
15
|
Batch independent questions over the same context in one call. Answers retain their question IDs. The MCP returns judgments and token usage; the caller owns thresholds, escalation, and action execution.
|
|
14
16
|
|
|
15
|
-
##
|
|
17
|
+
## Install from npm
|
|
18
|
+
|
|
19
|
+
Requires Node.js 22 or newer. The published package runs without cloning or building:
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
npx -y jev-decision-mcp@0.1.2
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Set `TYPESAFE_API_KEY` in your MCP host's environment. For hosts that use
|
|
26
|
+
`mcpServers` JSON configuration:
|
|
27
|
+
|
|
28
|
+
```json
|
|
29
|
+
{
|
|
30
|
+
"mcpServers": {
|
|
31
|
+
"jev": {
|
|
32
|
+
"command": "npx",
|
|
33
|
+
"args": ["-y", "jev-decision-mcp@0.1.2"]
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Node.js and npm must be installed and available on the host's `PATH`. If the
|
|
40
|
+
host cannot resolve `npx`, use its platform-specific launcher or absolute path
|
|
41
|
+
as documented by that host. GUI applications may have a different `PATH` from
|
|
42
|
+
your terminal.
|
|
43
|
+
|
|
44
|
+
The server communicates over stdio; starting it in a terminal waits for an MCP
|
|
45
|
+
client rather than opening a web page. The npm installation does not read a
|
|
46
|
+
`.env` from the caller's working directory.
|
|
47
|
+
|
|
48
|
+
Package: [jev-decision-mcp on npm](https://www.npmjs.com/package/jev-decision-mcp).
|
|
49
|
+
|
|
50
|
+
## Connect to Codex
|
|
51
|
+
|
|
52
|
+
For the npm package, merge this into your Codex `config.toml`:
|
|
53
|
+
|
|
54
|
+
```toml
|
|
55
|
+
[mcp_servers.jev]
|
|
56
|
+
command = "npx"
|
|
57
|
+
args = ["-y", "jev-decision-mcp@0.1.2"]
|
|
58
|
+
env_vars = ["TYPESAFE_API_KEY"]
|
|
59
|
+
tool_timeout_sec = 45
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Set `TYPESAFE_API_KEY` in the environment that launches Codex; `env_vars` forwards
|
|
63
|
+
its existing value to the server. Keep the host tool timeout above
|
|
64
|
+
`JEV_TIMEOUT_MS / 1000`. See [official Codex MCP configuration](https://developers.openai.com/codex/mcp).
|
|
65
|
+
|
|
66
|
+
## Setup from source
|
|
16
67
|
|
|
17
68
|
Requires Node.js 22 or newer.
|
|
18
69
|
|
|
@@ -20,8 +71,7 @@ Requires Node.js 22 or newer.
|
|
|
20
71
|
git clone https://github.com/amidabuddha/jev-decision-mcp.git
|
|
21
72
|
cd jev-decision-mcp
|
|
22
73
|
npm ci
|
|
23
|
-
|
|
24
|
-
# Edit .env and set TYPESAFE_API_KEY.
|
|
74
|
+
# Copy .env.example to .env and set TYPESAFE_API_KEY.
|
|
25
75
|
npm run build
|
|
26
76
|
```
|
|
27
77
|
|
|
@@ -37,41 +87,18 @@ Obtain the key from [TypeSafe Console](https://console.typesafe.ai). Use an offi
|
|
|
37
87
|
|
|
38
88
|
The server starts without a key so a host can discover the tool. Calls then return `MISSING_API_KEY`. API traffic is fixed to `https://api.typesafe.ai/v1/systemone`; `TYPESAFE_BASE_URL` does not override it. State and questions are sent to TypeSafe and may incur API charges. The server does not persist inputs or decisions and disables SDK logging. Upstream error bodies are not exposed because they may echo submitted data.
|
|
39
89
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
After building, run:
|
|
43
|
-
|
|
44
|
-
```sh
|
|
45
|
-
codex mcp add jev -- "$(command -v node)" "$PWD/dist/index.js"
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
Run this command from the repository root. It registers the absolute paths to your Node executable and built server.
|
|
90
|
+
### Connect a local source build
|
|
49
91
|
|
|
50
|
-
|
|
92
|
+
After building, configure your host to run `node` with the absolute path to
|
|
93
|
+
`dist/index.js` as its argument. For Codex, replace the npm example's `command`
|
|
94
|
+
with `"node"` and `args` with `["/absolute/path/to/jev-decision-mcp/dist/index.js"]`.
|
|
95
|
+
That path is a placeholder: use your own checkout path. In TOML or JSON, Windows
|
|
96
|
+
paths can use forward slashes, for example `"C:/projects/jev-decision-mcp/dist/index.js"`.
|
|
97
|
+
If `node` is not on the host's `PATH`, use the absolute path to your Node executable.
|
|
51
98
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
args = ["/absolute/path/to/jev-decision-mcp/dist/index.js"]
|
|
56
|
-
tool_timeout_sec = 45
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
Keep the host tool timeout above `JEV_TIMEOUT_MS / 1000`. The key stays in `.env`; it need not appear in the command or MCP configuration. See [official Codex MCP configuration](https://developers.openai.com/codex/mcp).
|
|
60
|
-
|
|
61
|
-
For other stdio MCP hosts, configure your absolute paths similarly:
|
|
62
|
-
|
|
63
|
-
```json
|
|
64
|
-
{
|
|
65
|
-
"mcpServers": {
|
|
66
|
-
"jev": {
|
|
67
|
-
"command": "/opt/homebrew/bin/node",
|
|
68
|
-
"args": ["/absolute/path/to/jev-decision-mcp/dist/index.js"]
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
The host starts the process and communicates over stdin/stdout. For interactive local development use `npm run dev`; this is not an HTTP server. No host configuration is modified by setup or tests.
|
|
99
|
+
The source build reads the repository's `.env`, so `env_vars` is only needed if
|
|
100
|
+
you supply the key through Codex's environment instead. For interactive local
|
|
101
|
+
development use `npm run dev`. No host configuration is modified by setup or tests.
|
|
75
102
|
|
|
76
103
|
## Call the tool
|
|
77
104
|
|
|
@@ -94,7 +121,7 @@ Call `jev_decide` with the JSON in [examples/decision.json](examples/decision.js
|
|
|
94
121
|
}
|
|
95
122
|
```
|
|
96
123
|
|
|
97
|
-
The response contains `model`, `answers`, and `usage`, both as MCP structured content and JSON text. Choice supports 1–255 named options. Instructions and descriptions may be strings, JSON objects, or arrays; choice descriptions may also be null. Noul accepts optional `criteria.true` and `criteria.false` descriptions.
|
|
124
|
+
The response contains `model`, `answers`, and `usage`, both as MCP structured content and JSON text. Jev may round probabilities to two decimal places, so their sum can differ slightly from 1. The server allows the corresponding rounding margin (up to 0.005 per option) and preserves the returned values without normalization. Choice supports 1–255 named options. Instructions and descriptions may be strings, JSON objects, or arrays; choice descriptions may also be null. Noul accepts optional `criteria.true` and `criteria.false` descriptions.
|
|
98
125
|
|
|
99
126
|
Supply relevant facts, source text, and policies explicitly: Jev cannot see the caller's conversation or local files. Write complete judgments in `instructions`; IDs are only response keys. Include a no-match option when appropriate. Questions in one batch cannot see one another's answers. A noul near 0.5 is uncertainty about yes/no, not medium intensity. Confidence does not authorize actions or guarantee correctness; evaluate thresholds on representative data.
|
|
100
127
|
|
|
@@ -131,16 +158,36 @@ Built using the `typesafe-ai` skill and official documentation, checked Septembe
|
|
|
131
158
|
|
|
132
159
|
## Releases and package publishing
|
|
133
160
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
161
|
+
Publishing a stable GitHub release triggers `.github/workflows/publish-npm.yml`.
|
|
162
|
+
The workflow checks that the release tag (`v` plus the package version) matches
|
|
163
|
+
`package.json` and `server.json`, runs the checks, and publishes to npm using
|
|
164
|
+
GitHub OIDC. It requires an npm trusted publisher configured for user
|
|
165
|
+
`amidabuddha`, repository `jev-decision-mcp`, workflow filename `publish-npm.yml`,
|
|
166
|
+
no environment name, and permission for direct `npm publish`. No npm token is needed.
|
|
167
|
+
|
|
168
|
+
For a new release, update `package.json`, `package-lock.json`, and all version
|
|
169
|
+
fields in `server.json` together, then publish a matching GitHub release from
|
|
170
|
+
that commit. Confirm the **Publish npm** workflow succeeds. Existing versions
|
|
171
|
+
cannot be published again; prereleases are not published by this workflow.
|
|
172
|
+
|
|
173
|
+
The official MCP Registry uses the separate, manually triggered **Publish MCP
|
|
174
|
+
Registry** workflow. Run it from `main` after the corresponding npm version is
|
|
175
|
+
available. GitHub release creation alone does not confirm either publication.
|
|
137
176
|
|
|
138
177
|
To verify the publishable artifact locally, run `npm pack --dry-run`. The package
|
|
139
178
|
contains the compiled server, license, README, example input, and registry metadata.
|
|
140
179
|
Local `.env` files, tests, and development dependencies are not bundled.
|
|
141
180
|
|
|
142
|
-
|
|
143
|
-
`npx -y jev-decision-mcp@0.1.
|
|
181
|
+
Clients can launch the published npm package with
|
|
182
|
+
`npx -y jev-decision-mcp@0.1.2`. For that installation method, provide
|
|
144
183
|
`TYPESAFE_API_KEY` in the MCP host's environment; the package does not read a `.env`
|
|
145
184
|
from the caller's working directory. The clone-and-build setup above remains
|
|
146
185
|
available independently of npm publication.
|
|
186
|
+
|
|
187
|
+
## Glama inspection
|
|
188
|
+
|
|
189
|
+
Glama's build configuration is managed in the listing's Dockerfile admin page.
|
|
190
|
+
Use build steps `npm ci` and `npm run build`, with CMD arguments
|
|
191
|
+
`["node", "dist/index.js"]`. No repository Dockerfile or TypeSafe key is needed
|
|
192
|
+
for inspection: the server starts without credentials and supports MCP
|
|
193
|
+
initialization and `tools/list`. Decision calls still require `TYPESAFE_API_KEY`.
|
package/dist/schema.js
CHANGED
|
@@ -56,9 +56,16 @@ export function validateResponse(raw, input) {
|
|
|
56
56
|
: question.type === "score" ? question.criteria.map((_, index) => String(index)) : [];
|
|
57
57
|
if (!sameKeys(answer.probabilities, levels))
|
|
58
58
|
throw new Error("Probability labels do not match criteria");
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
59
|
+
const values = Object.values(answer.probabilities);
|
|
60
|
+
const sum = values.reduce((a, b) => a + b, 0);
|
|
61
|
+
// Jev can return probabilities rounded to two decimals (observed totals
|
|
62
|
+
// include 0.99). Each rounded entry can contribute at most 0.005 error.
|
|
63
|
+
// Keep the tighter check for higher-precision responses, and never
|
|
64
|
+
// normalize the upstream values or accept a distribution with no mass.
|
|
65
|
+
const roundedToCents = values.every((p) => Math.abs(p * 100 - Math.round(p * 100)) < 1e-9);
|
|
66
|
+
const tolerance = roundedToCents ? values.length * 0.005 : 0.001;
|
|
67
|
+
if (sum <= 0 || Math.abs(sum - 1) > tolerance + 1e-12)
|
|
68
|
+
throw new Error("Probabilities do not sum to one within rounding tolerance");
|
|
62
69
|
if (answer.type === "choice" && !levels.includes(answer.choice))
|
|
63
70
|
throw new Error("Unknown choice");
|
|
64
71
|
if (answer.type === "score" && (answer.score < 0 || answer.score > levels.length - 1 || !sameKeys(answer.legend, levels))) {
|
package/dist/server.js
CHANGED
|
@@ -2,7 +2,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
|
2
2
|
import { DecisionError } from "./decision.js";
|
|
3
3
|
import { decisionInput, decisionOutput } from "./schema.js";
|
|
4
4
|
export function createServer(decide) {
|
|
5
|
-
const server = new McpServer({ name: "jev-decision-mcp", version: "0.1.
|
|
5
|
+
const server = new McpServer({ name: "jev-decision-mcp", version: "0.1.2" });
|
|
6
6
|
server.registerTool("jev_decide", {
|
|
7
7
|
title: "Ask Jev for typed decisions",
|
|
8
8
|
description: "Evaluate supplied context using TypeSafe Jev. Batch independent, narrow questions in one call: choice selects a provided label; score returns a position on 2–10 ordered levels (0-based); noul returns probability of yes, not intensity. Supply relevant evidence and full instructions; question IDs are not sent to the model. Include an other/none choice when appropriate. Questions cannot use each other's answers. Returns raw judgments, probabilities, confidence for choice/score, and token usage. Use caller-defined policies for uncertainty. This sends the supplied state and questions to TypeSafe and may incur API charges. It does not execute selected actions.",
|
package/package.json
CHANGED
package/server.json
CHANGED
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
"url": "https://github.com/amidabuddha/jev-decision-mcp",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "0.1.
|
|
9
|
+
"version": "0.1.2",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"identifier": "jev-decision-mcp",
|
|
14
|
-
"version": "0.1.
|
|
14
|
+
"version": "0.1.2",
|
|
15
15
|
"transport": {
|
|
16
16
|
"type": "stdio"
|
|
17
17
|
},
|