@chartobserver/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/CHANGELOG.md +25 -0
- package/README.md +2 -4
- package/SECURITY.md +1 -1
- package/dist/config.d.ts +2 -1
- package/dist/config.js +7 -3
- package/dist/index.js +2 -1
- package/dist/instructions.d.ts +7 -0
- package/dist/instructions.js +20 -0
- package/dist/tools/account.js +1 -1
- package/dist/tools/trading.js +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.2 — 2026-06-12
|
|
4
|
+
|
|
5
|
+
The self-serve credentials page is now live in production.
|
|
6
|
+
|
|
7
|
+
- README, SECURITY.md, server instructions, and config error hints now point
|
|
8
|
+
to the real credentials page: https://chart.observer/integrations/mcp
|
|
9
|
+
(Integrations → AI Agent (MCP)) — masked webhook ID with reveal, copy
|
|
10
|
+
buttons, and a pre-filled MCP config snippet.
|
|
11
|
+
- Removed the interim "ask Brian" fallback; the package is now fully
|
|
12
|
+
self-serve: sign up at https://chart.observer, copy credentials, connect.
|
|
13
|
+
|
|
14
|
+
## 0.2.1 — 2026-06-12
|
|
15
|
+
|
|
16
|
+
Agent-facing signup guidance. No behavior changes to tools or transport.
|
|
17
|
+
|
|
18
|
+
- **MCP server `instructions`**: the server now tells the connected AI agent,
|
|
19
|
+
at initialization, that an existing chart.observer account is required,
|
|
20
|
+
that accounts cannot be created through this server, and to direct the
|
|
21
|
+
user to sign up in a browser at https://chart.observer. Previously this
|
|
22
|
+
fact lived only in the README, which agents never see.
|
|
23
|
+
- Missing/invalid configuration errors now include the same guidance (where
|
|
24
|
+
credentials come from, where to create an account).
|
|
25
|
+
- `get_profile` and `place_trade` descriptions carry a one-line fallback of
|
|
26
|
+
the guidance for MCP clients that don't surface server instructions.
|
|
27
|
+
|
|
3
28
|
## 0.2.0 — 2026-06-12
|
|
4
29
|
|
|
5
30
|
Hardening & trust release. No breaking changes for users — configuration and
|
package/README.md
CHANGED
|
@@ -45,9 +45,7 @@ Restart Claude Desktop. The tools become available in any conversation.
|
|
|
45
45
|
|
|
46
46
|
### Where to find your credentials
|
|
47
47
|
|
|
48
|
-
Sign in at https://chart.observer and open **
|
|
49
|
-
|
|
50
|
-
(Until that settings page ships, ask Brian for your three values.)
|
|
48
|
+
Sign in at https://chart.observer and open **Integrations → AI Agent (MCP)** — or go directly to https://chart.observer/integrations/mcp. The page shows your webhook ID, UID, and username with copy buttons and a pre-filled config snippet you can paste straight into your MCP client.
|
|
51
49
|
|
|
52
50
|
## Environment variables
|
|
53
51
|
|
|
@@ -97,7 +95,7 @@ Sign in at https://chart.observer and open **Settings → API & Integrations**.
|
|
|
97
95
|
- **`place_trade` defaults to dry-run.** The AI agent must explicitly pass `dry_run: false` to execute. You should be asked for confirmation before that happens.
|
|
98
96
|
- **Live trades are validated.** Execution runs the same checks as the dry run (sufficient funds, position size, well-formed quantities) and refuses trades that would fail, without calling the API.
|
|
99
97
|
- **Secret redaction.** Error text returned to the agent is sanitized; the webhook credential is redacted as defense-in-depth so it cannot leak into transcripts.
|
|
100
|
-
- **Bearer-secret auth.** The webhook ID acts as a bearer token. If it leaks, anyone can act on your account. Don't paste it into screenshots, logs, or chat messages. If you suspect compromise, regenerate it from
|
|
98
|
+
- **Bearer-secret auth.** The webhook ID acts as a bearer token. If it leaks, anyone can act on your account. Don't paste it into screenshots, logs, or chat messages. If you suspect compromise, regenerate it from https://chart.observer/integrations/mcp.
|
|
101
99
|
- **No account creation.** Sign up at https://chart.observer in a browser. Web signup requires a CAPTCHA, which a headless MCP server can't solve.
|
|
102
100
|
|
|
103
101
|
## What's not in v1
|
package/SECURITY.md
CHANGED
|
@@ -37,7 +37,7 @@ standing and visible portfolio, not real funds). Treat it like a password:
|
|
|
37
37
|
- This server sanitizes its error output and redacts the credential from any
|
|
38
38
|
text returned to the AI agent, as defense-in-depth.
|
|
39
39
|
- If you suspect it leaked, regenerate it from your ChartObserver account
|
|
40
|
-
settings (
|
|
40
|
+
settings (https://chart.observer/integrations/mcp) — the old value stops working
|
|
41
41
|
immediately.
|
|
42
42
|
|
|
43
43
|
## Reporting a vulnerability
|
package/dist/config.d.ts
CHANGED
|
@@ -8,5 +8,6 @@ export interface Config {
|
|
|
8
8
|
}
|
|
9
9
|
export declare const DEFAULT_API_BASE = "https://g2uyqqluc4.execute-api.us-east-2.amazonaws.com/dev";
|
|
10
10
|
export declare const DEFAULT_TIMEOUT_MS = 15000;
|
|
11
|
-
export declare const PACKAGE_VERSION = "0.2.
|
|
11
|
+
export declare const PACKAGE_VERSION = "0.2.2";
|
|
12
|
+
export declare const CREDENTIALS_HINT: string;
|
|
12
13
|
export declare function loadConfig(env?: NodeJS.ProcessEnv): Config;
|
package/dist/config.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
export const DEFAULT_API_BASE = "https://g2uyqqluc4.execute-api.us-east-2.amazonaws.com/dev";
|
|
3
3
|
export const DEFAULT_TIMEOUT_MS = 15_000;
|
|
4
|
-
export const PACKAGE_VERSION = "0.2.
|
|
4
|
+
export const PACKAGE_VERSION = "0.2.2";
|
|
5
|
+
export const CREDENTIALS_HINT = "These values come from your chart.observer account: create one in a " +
|
|
6
|
+
"browser at https://chart.observer (accounts cannot be created via this " +
|
|
7
|
+
"server), then copy your webhook ID, UID, and username from " +
|
|
8
|
+
"https://chart.observer/integrations/mcp (Integrations → AI Agent (MCP)).";
|
|
5
9
|
// Validation messages must never echo the webhook value — they can end up in
|
|
6
10
|
// MCP client logs.
|
|
7
11
|
const configSchema = z.object({
|
|
@@ -35,7 +39,7 @@ export function loadConfig(env = process.env) {
|
|
|
35
39
|
if (!username)
|
|
36
40
|
missing.push("CHARTOBSERVER_USERNAME");
|
|
37
41
|
if (missing.length > 0) {
|
|
38
|
-
throw new Error(`Missing required environment variable(s): ${missing.join(", ")}. Configure them in your MCP client's mcpServers entry.
|
|
42
|
+
throw new Error(`Missing required environment variable(s): ${missing.join(", ")}. Configure them in your MCP client's mcpServers entry. ${CREDENTIALS_HINT}`);
|
|
39
43
|
}
|
|
40
44
|
const rawTimeout = env.CHARTOBSERVER_TIMEOUT_MS?.trim();
|
|
41
45
|
const timeoutMs = rawTimeout ? Number(rawTimeout) : DEFAULT_TIMEOUT_MS;
|
|
@@ -56,7 +60,7 @@ export function loadConfig(env = process.env) {
|
|
|
56
60
|
? "CHARTOBSERVER_TIMEOUT_MS must be a positive integer ≤ 120000."
|
|
57
61
|
: i.message)
|
|
58
62
|
.join(" ");
|
|
59
|
-
throw new Error(`Invalid configuration: ${reasons}`);
|
|
63
|
+
throw new Error(`Invalid configuration: ${reasons} ${CREDENTIALS_HINT}`);
|
|
60
64
|
}
|
|
61
65
|
return {
|
|
62
66
|
...parsed.data,
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
|
3
3
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
4
|
import { loadConfig, PACKAGE_VERSION } from "./config.js";
|
|
5
5
|
import { ChartObserverClient } from "./api-client.js";
|
|
6
|
+
import { SERVER_INSTRUCTIONS } from "./instructions.js";
|
|
6
7
|
import { registerSecret, redactSecrets } from "./redact.js";
|
|
7
8
|
import { registerAccountTools } from "./tools/account.js";
|
|
8
9
|
import { registerTradingTools } from "./tools/trading.js";
|
|
@@ -15,7 +16,7 @@ async function main() {
|
|
|
15
16
|
const server = new McpServer({
|
|
16
17
|
name: "chartobserver",
|
|
17
18
|
version: PACKAGE_VERSION,
|
|
18
|
-
});
|
|
19
|
+
}, { instructions: SERVER_INSTRUCTIONS });
|
|
19
20
|
registerAccountTools(server, client);
|
|
20
21
|
registerTradingTools(server, client);
|
|
21
22
|
registerMarketTools(server, client);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server-level instructions surfaced to the AI agent at MCP initialization.
|
|
3
|
+
* This is the agent-visible counterpart of the README: it must carry any fact
|
|
4
|
+
* the model needs to relay to the user, because the agent never sees npm or
|
|
5
|
+
* website documentation.
|
|
6
|
+
*/
|
|
7
|
+
export declare const SERVER_INSTRUCTIONS: string;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server-level instructions surfaced to the AI agent at MCP initialization.
|
|
3
|
+
* This is the agent-visible counterpart of the README: it must carry any fact
|
|
4
|
+
* the model needs to relay to the user, because the agent never sees npm or
|
|
5
|
+
* website documentation.
|
|
6
|
+
*/
|
|
7
|
+
export const SERVER_INSTRUCTIONS = [
|
|
8
|
+
"ChartObserver is a crypto paper-trading platform (https://chart.observer).",
|
|
9
|
+
"This server requires an EXISTING chart.observer account — accounts cannot",
|
|
10
|
+
"be created through this server or by any agent (signup is CAPTCHA-protected",
|
|
11
|
+
"and must be done by the user in a browser at https://chart.observer).",
|
|
12
|
+
"If the configured credentials are missing or invalid, tell the user to:",
|
|
13
|
+
"(1) create an account at https://chart.observer in their browser, then",
|
|
14
|
+
"(2) copy their webhook ID, UID, and username from",
|
|
15
|
+
"https://chart.observer/integrations/mcp into this server's environment",
|
|
16
|
+
"variables (see the package",
|
|
17
|
+
"README). All trading is simulated paper trading — no real funds move — but",
|
|
18
|
+
"trades do affect the user's public leaderboard standing, so always confirm",
|
|
19
|
+
"with the user before executing a trade (place_trade defaults to dry_run).",
|
|
20
|
+
].join(" ");
|
package/dist/tools/account.js
CHANGED
|
@@ -2,7 +2,7 @@ import { ok, fail, READ_TOOL_ANNOTATIONS } from "./util.js";
|
|
|
2
2
|
export function registerAccountTools(server, client) {
|
|
3
3
|
server.registerTool("get_profile", {
|
|
4
4
|
title: "Get profile",
|
|
5
|
-
description: "Fetch the currently configured user's public profile (description, social links, follower counts) along with their USD paper-trading balance. Read-only.",
|
|
5
|
+
description: "Fetch the currently configured user's public profile (description, social links, follower counts) along with their USD paper-trading balance. Read-only. Requires an existing chart.observer account — if credentials are missing or rejected, direct the user to sign up in a browser at https://chart.observer (accounts cannot be created via this server).",
|
|
6
6
|
annotations: { ...READ_TOOL_ANNOTATIONS },
|
|
7
7
|
inputSchema: {},
|
|
8
8
|
}, async () => {
|
package/dist/tools/trading.js
CHANGED
|
@@ -135,6 +135,7 @@ export function registerTradingTools(server, client) {
|
|
|
135
135
|
"- Sell `count` may be a percentage string like '50%' or '100%'. Buy `count` must be a numeric quantity.",
|
|
136
136
|
"- Buys require sufficient USD balance. Sells cannot exceed currently held tokens.",
|
|
137
137
|
"- Live execution runs the same validation as the dry run and refuses trades that would fail.",
|
|
138
|
+
"- Requires an existing chart.observer account. If credentials are rejected, direct the user to https://chart.observer to sign up in a browser (accounts cannot be created via this server).",
|
|
138
139
|
].join("\n"),
|
|
139
140
|
annotations: {
|
|
140
141
|
readOnlyHint: false,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chartobserver/mcp-server",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "MCP server for the ChartObserver paper-trading platform. Lets an AI agent (Claude Desktop, etc.) read portfolio state, place trades, and check the leaderboard on behalf of the configured user.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "ChartObserver Corp",
|