@getpalmos/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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 PalmOS
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,103 @@
1
+ # @getpalmos/mcp
2
+
3
+ Model Context Protocol (MCP) server for PalmOS. It gives Claude Code, Codex, and
4
+ any other MCP-capable agent a set of **governed payment tools** — the agent can
5
+ discover paid services, check policy, and request payments, while PalmOS enforces
6
+ budget, allowlist, approval, settlement, and audit rules server-side. The agent
7
+ never holds a wallet key.
8
+
9
+ ## Tools
10
+
11
+ | Tool | Purpose |
12
+ | --- | --- |
13
+ | `palmos_list_services` | List the paid services this agent is allowed to call. |
14
+ | `palmos_check_policy` | Preview whether a payment would be allowed / approval-gated / denied (no spend). |
15
+ | `palmos_get_agent_status` | Report the agent's PalmOS identity, trust tier, and settlement mode. |
16
+ | `palmos_pay` | Execute a governed paid-service call. |
17
+
18
+ `palmos_pay` is the only tool that can move money, and every call is still
19
+ gated by PalmOS policy: small allowed payments execute, higher-value ones become
20
+ approval-pending for an operator, and disallowed services are blocked.
21
+
22
+ ## Prerequisites
23
+
24
+ 1. A running PalmOS backend (defaults to the hosted API `https://api.getpalmos.xyz`).
25
+ 2. An agent created in the PalmOS dashboard with an issued SDK credential
26
+ (`palmos_...` token).
27
+
28
+ ## Configure
29
+
30
+ The server reads two environment variables:
31
+
32
+ - `PALMOS_AGENT_TOKEN` (required) — the issued `palmos_...` SDK credential.
33
+ - `PALMOS_API_URL` (optional) — defaults to the hosted API; set it only for a
34
+ self-hosted backend.
35
+
36
+ ### Claude Code
37
+
38
+ ```bash
39
+ claude mcp add palmos --env PALMOS_AGENT_TOKEN=palmos_YOUR_TOKEN -- npx -y @getpalmos/mcp
40
+ ```
41
+
42
+ or add it to `.mcp.json` / your Claude Code MCP config directly:
43
+
44
+ ```json
45
+ {
46
+ "mcpServers": {
47
+ "palmos": {
48
+ "command": "npx",
49
+ "args": ["-y", "@getpalmos/mcp"],
50
+ "env": {
51
+ "PALMOS_AGENT_TOKEN": "palmos_YOUR_TOKEN"
52
+ }
53
+ }
54
+ }
55
+ }
56
+ ```
57
+
58
+ ### Codex
59
+
60
+ In `~/.codex/config.toml`:
61
+
62
+ ```toml
63
+ [mcp_servers.palmos]
64
+ command = "npx"
65
+ args = ["-y", "@getpalmos/mcp"]
66
+ env = { PALMOS_AGENT_TOKEN = "palmos_YOUR_TOKEN" }
67
+ ```
68
+
69
+ ### Local (before publishing / for development)
70
+
71
+ Point the runner at the built file in this repo instead of `npx`:
72
+
73
+ ```json
74
+ {
75
+ "mcpServers": {
76
+ "palmos": {
77
+ "command": "node",
78
+ "args": ["/absolute/path/to/palmos/packages/mcp/dist/index.js"],
79
+ "env": { "PALMOS_AGENT_TOKEN": "palmos_YOUR_TOKEN" }
80
+ }
81
+ }
82
+ }
83
+ ```
84
+
85
+ Build it first with `npm run build` (from `packages/mcp`) or
86
+ `npm run package:mcp:build` from the repo root.
87
+
88
+ ## Use
89
+
90
+ Once configured, ask the agent naturally, e.g.:
91
+
92
+ > "List my PalmOS services, check the policy for `local.pusd.spot_price`, then
93
+ > pay for a BTC/USD spot price."
94
+
95
+ The agent will call `palmos_list_services` → `palmos_check_policy` → `palmos_pay`.
96
+ PalmOS records every outcome (executed, approval-pending, blocked) with an audit
97
+ trail in the dashboard.
98
+
99
+ ## Token storage
100
+
101
+ Treat `PALMOS_AGENT_TOKEN` like a payment credential: keep it in your MCP client's
102
+ secret/env config, not in source control, use a separate credential per runtime,
103
+ and rotate or revoke it from the PalmOS dashboard if it may have been exposed.
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,123 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
+ import { z } from 'zod';
5
+ import { PalmosAgentClient, PalmosAgentClientError } from '@getpalmos/agent';
6
+ // Lazily build the client so the server can start and advertise its tools even
7
+ // when no credential is set yet. Tool *calls* still require PALMOS_AGENT_TOKEN.
8
+ let client;
9
+ function getClient() {
10
+ if (client) {
11
+ return client;
12
+ }
13
+ const token = process.env.PALMOS_AGENT_TOKEN?.trim();
14
+ if (!token) {
15
+ throw new Error('Set PALMOS_AGENT_TOKEN to an issued palmos_... SDK credential (from the PalmOS dashboard).');
16
+ }
17
+ client = new PalmosAgentClient({
18
+ baseUrl: process.env.PALMOS_API_URL?.trim(),
19
+ token,
20
+ });
21
+ return client;
22
+ }
23
+ function ok(data) {
24
+ return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
25
+ }
26
+ function fail(error) {
27
+ const message = error instanceof PalmosAgentClientError
28
+ ? `PalmOS API error ${error.status}: ${error.message}`
29
+ : error instanceof Error
30
+ ? error.message
31
+ : String(error);
32
+ return { isError: true, content: [{ type: 'text', text: message }] };
33
+ }
34
+ const server = new McpServer({ name: 'palmos', version: '0.1.0' });
35
+ server.registerTool('palmos_list_services', {
36
+ title: 'List PalmOS paid services',
37
+ description: 'List the paid services this PalmOS agent is allowed to call, with vendor, settlement asset, expected amount, payment rail, and whether each is currently allowed by policy. Call this first to discover valid serviceId values.',
38
+ inputSchema: {},
39
+ }, async () => {
40
+ try {
41
+ return ok(await getClient().listServices());
42
+ }
43
+ catch (error) {
44
+ return fail(error);
45
+ }
46
+ });
47
+ server.registerTool('palmos_get_agent_status', {
48
+ title: 'Get PalmOS agent status',
49
+ description: "Return this agent's PalmOS identity and posture: agent and credential status, trust tier, settlement mode, and wallet state.",
50
+ inputSchema: {},
51
+ }, async () => {
52
+ try {
53
+ return ok(await getClient().getAgentStatus());
54
+ }
55
+ catch (error) {
56
+ return fail(error);
57
+ }
58
+ });
59
+ server.registerTool('palmos_check_policy', {
60
+ title: 'Check PalmOS payment policy',
61
+ description: 'Preview whether a payment for a service (and optional amount) would be allowed, approval-gated, or denied — WITHOUT spending anything. Use this before palmos_pay to avoid surprises.',
62
+ inputSchema: {
63
+ serviceId: z
64
+ .string()
65
+ .describe('PalmOS service id, e.g. local.pusd.spot_price'),
66
+ amount: z
67
+ .string()
68
+ .optional()
69
+ .describe('Optional amount override as a decimal string, e.g. "0.25".'),
70
+ },
71
+ }, async ({ serviceId, amount }) => {
72
+ try {
73
+ return ok(await getClient().checkPolicy({ serviceId, amount }));
74
+ }
75
+ catch (error) {
76
+ return fail(error);
77
+ }
78
+ });
79
+ server.registerTool('palmos_pay', {
80
+ title: 'Execute a governed PalmOS payment',
81
+ description: 'Request a governed paid-service call. PalmOS enforces policy, session budget, vendor allowlist, and approval gates server-side: small allowed payments execute immediately, higher-value ones become approval-pending for an operator, and disallowed services/vendors are blocked. The agent never holds wallet keys. Returns the execution record; check result.kind (executed | approval_pending | waiting_for_execution | blocked | execution_failed). Pass a stable idempotencyKey derived from a job/run id so retries do not double-pay.',
82
+ inputSchema: {
83
+ serviceId: z.string().describe('PalmOS service id to pay for.'),
84
+ request: z
85
+ .record(z.string(), z.unknown())
86
+ .optional()
87
+ .describe('Service request payload, e.g. { "base": "BTC", "quote": "USD" }.'),
88
+ amount: z
89
+ .string()
90
+ .optional()
91
+ .describe('Optional amount override as a decimal string.'),
92
+ note: z
93
+ .string()
94
+ .optional()
95
+ .describe('Optional human-readable note stored on the paid-call record.'),
96
+ idempotencyKey: z
97
+ .string()
98
+ .optional()
99
+ .describe('Stable key from a job/run id so retries are not double-charged.'),
100
+ privacy: z
101
+ .enum(['default', 'required'])
102
+ .optional()
103
+ .describe('Set "required" to force private (Umbra) settlement; fails closed if no private route is configured.'),
104
+ },
105
+ }, async (input) => {
106
+ try {
107
+ return ok(await getClient().pay(input));
108
+ }
109
+ catch (error) {
110
+ return fail(error);
111
+ }
112
+ });
113
+ async function main() {
114
+ const transport = new StdioServerTransport();
115
+ await server.connect(transport);
116
+ // stdout is the JSON-RPC channel; log to stderr only.
117
+ console.error('[palmos-mcp] PalmOS MCP server ready on stdio.');
118
+ }
119
+ main().catch((error) => {
120
+ console.error('[palmos-mcp] fatal:', error instanceof Error ? error.message : error);
121
+ process.exit(1);
122
+ });
123
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@getpalmos/mcp",
3
+ "version": "0.1.0",
4
+ "description": "Model Context Protocol server for PalmOS. Gives Claude Code, Codex, and other MCP agents governed PUSD payment tools.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "author": "PalmOS",
8
+ "homepage": "https://www.getpalmos.xyz",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/Pavilion-devs/palmos.git",
12
+ "directory": "packages/mcp"
13
+ },
14
+ "bugs": {
15
+ "url": "https://github.com/Pavilion-devs/palmos/issues"
16
+ },
17
+ "bin": {
18
+ "palmos-mcp": "dist/index.js"
19
+ },
20
+ "files": [
21
+ "dist",
22
+ "README.md"
23
+ ],
24
+ "exports": {
25
+ ".": {
26
+ "types": "./dist/index.d.ts",
27
+ "import": "./dist/index.js"
28
+ }
29
+ },
30
+ "types": "./dist/index.d.ts",
31
+ "main": "./dist/index.js",
32
+ "scripts": {
33
+ "build": "tsc -p tsconfig.json",
34
+ "prepublishOnly": "npm run build"
35
+ },
36
+ "publishConfig": {
37
+ "access": "public"
38
+ },
39
+ "engines": {
40
+ "node": ">=22"
41
+ },
42
+ "keywords": [
43
+ "palmos",
44
+ "mcp",
45
+ "model-context-protocol",
46
+ "agent",
47
+ "pusd",
48
+ "solana",
49
+ "payments",
50
+ "claude",
51
+ "codex"
52
+ ],
53
+ "dependencies": {
54
+ "@getpalmos/agent": "^0.1.0",
55
+ "@modelcontextprotocol/sdk": "^1.29.0",
56
+ "zod": "3.25.76"
57
+ },
58
+ "devDependencies": {
59
+ "@types/node": "^25.5.2"
60
+ }
61
+ }