@spences10/pi-mcp 0.0.1
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 +21 -0
- package/README.md +97 -0
- package/dist/client.d.ts +27 -0
- package/dist/client.js +227 -0
- package/dist/client.js.map +1 -0
- package/dist/config.d.ts +2 -0
- package/dist/config.js +73 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +301 -0
- package/dist/index.js.map +1 -0
- package/package.json +55 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Scott Spence
|
|
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,97 @@
|
|
|
1
|
+
# @spences10/pi-mcp
|
|
2
|
+
|
|
3
|
+
[](https://viteplus.dev)
|
|
4
|
+
[](https://vitest.dev)
|
|
5
|
+
|
|
6
|
+
Pi extension for connecting MCP servers and exposing their tools
|
|
7
|
+
inside Pi.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pi install npm:@spences10/pi-mcp
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Local development from this monorepo:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pnpm --filter @spences10/pi-mcp run build
|
|
19
|
+
pi install ./packages/pi-mcp
|
|
20
|
+
# or for one run only
|
|
21
|
+
pi -e ./packages/pi-mcp
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Configuration
|
|
25
|
+
|
|
26
|
+
The extension loads MCP server definitions from `mcp.json` files in
|
|
27
|
+
global and project locations.
|
|
28
|
+
|
|
29
|
+
A typical project `mcp.json` looks like:
|
|
30
|
+
|
|
31
|
+
```json
|
|
32
|
+
{
|
|
33
|
+
"mcpServers": {
|
|
34
|
+
"sqlite": {
|
|
35
|
+
"command": "npx",
|
|
36
|
+
"args": ["-y", "mcp-sqlite-tools", "./data.db"]
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Server tools are registered as Pi tools using this naming format:
|
|
43
|
+
|
|
44
|
+
```text
|
|
45
|
+
mcp__<server>__<tool>
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
For example, a `sqlite` server tool named `execute_read_query`
|
|
49
|
+
becomes:
|
|
50
|
+
|
|
51
|
+
```text
|
|
52
|
+
mcp__sqlite__execute_read_query
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Commands
|
|
56
|
+
|
|
57
|
+
```text
|
|
58
|
+
/mcp list
|
|
59
|
+
/mcp enable <server>
|
|
60
|
+
/mcp disable <server>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Use `/mcp list` to inspect connection state and `/mcp enable` or
|
|
64
|
+
`/mcp disable` to toggle a server's registered tools during a session.
|
|
65
|
+
|
|
66
|
+
## What it does
|
|
67
|
+
|
|
68
|
+
- reads MCP server config
|
|
69
|
+
- connects to stdio or HTTP MCP servers
|
|
70
|
+
- performs the MCP `initialize` handshake
|
|
71
|
+
- discovers tools via `tools/list`
|
|
72
|
+
- registers each discovered MCP tool with Pi
|
|
73
|
+
- forwards model tool calls to the MCP server
|
|
74
|
+
- cleans up server processes on session shutdown
|
|
75
|
+
|
|
76
|
+
## Using from a custom harness
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
import mcp from '@spences10/pi-mcp';
|
|
80
|
+
|
|
81
|
+
// pass `mcp` as an ExtensionFactory to your Pi runtime
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
`my-pi` imports this package directly and enables it as the built-in
|
|
85
|
+
MCP extension.
|
|
86
|
+
|
|
87
|
+
## Development
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
pnpm --filter @spences10/pi-mcp run check
|
|
91
|
+
pnpm --filter @spences10/pi-mcp run test
|
|
92
|
+
pnpm --filter @spences10/pi-mcp run build
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## License
|
|
96
|
+
|
|
97
|
+
MIT
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface McpStdioServerConfig {
|
|
2
|
+
name: string;
|
|
3
|
+
transport: 'stdio';
|
|
4
|
+
command: string;
|
|
5
|
+
args?: string[];
|
|
6
|
+
env?: Record<string, string>;
|
|
7
|
+
}
|
|
8
|
+
export interface McpHttpServerConfig {
|
|
9
|
+
name: string;
|
|
10
|
+
transport: 'http';
|
|
11
|
+
url: string;
|
|
12
|
+
headers?: Record<string, string>;
|
|
13
|
+
}
|
|
14
|
+
export type McpServerConfig = McpStdioServerConfig | McpHttpServerConfig;
|
|
15
|
+
export interface McpToolInfo {
|
|
16
|
+
name: string;
|
|
17
|
+
description?: string;
|
|
18
|
+
inputSchema?: Record<string, unknown>;
|
|
19
|
+
}
|
|
20
|
+
export declare class McpClient {
|
|
21
|
+
#private;
|
|
22
|
+
constructor(config: McpServerConfig);
|
|
23
|
+
connect(): Promise<void>;
|
|
24
|
+
listTools(): Promise<McpToolInfo[]>;
|
|
25
|
+
callTool(name: string, args: Record<string, unknown>): Promise<unknown>;
|
|
26
|
+
disconnect(): Promise<void>;
|
|
27
|
+
}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
export class McpClient {
|
|
3
|
+
#proc = null;
|
|
4
|
+
#config;
|
|
5
|
+
#nextId = 1;
|
|
6
|
+
#pending = new Map();
|
|
7
|
+
#buffer = '';
|
|
8
|
+
#sessionId;
|
|
9
|
+
constructor(config) {
|
|
10
|
+
this.#config = config;
|
|
11
|
+
}
|
|
12
|
+
async connect() {
|
|
13
|
+
if (this.#config.transport === 'stdio') {
|
|
14
|
+
await this.#connect_stdio();
|
|
15
|
+
}
|
|
16
|
+
await this.#request('initialize', {
|
|
17
|
+
protocolVersion: '2024-11-05',
|
|
18
|
+
capabilities: {},
|
|
19
|
+
clientInfo: { name: 'my-pi', version: '0.0.1' },
|
|
20
|
+
});
|
|
21
|
+
await this.#send({
|
|
22
|
+
jsonrpc: '2.0',
|
|
23
|
+
method: 'notifications/initialized',
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
async listTools() {
|
|
27
|
+
const result = (await this.#request('tools/list', {}));
|
|
28
|
+
return result.tools;
|
|
29
|
+
}
|
|
30
|
+
async callTool(name, args) {
|
|
31
|
+
return this.#request('tools/call', {
|
|
32
|
+
name,
|
|
33
|
+
arguments: args,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
async disconnect() {
|
|
37
|
+
if (this.#config.transport === 'http') {
|
|
38
|
+
await this.#disconnect_http();
|
|
39
|
+
}
|
|
40
|
+
if (this.#proc) {
|
|
41
|
+
this.#proc.kill();
|
|
42
|
+
this.#proc = null;
|
|
43
|
+
}
|
|
44
|
+
this.#pending.clear();
|
|
45
|
+
}
|
|
46
|
+
async #connect_stdio() {
|
|
47
|
+
const { command, args = [], env, } = this.#config;
|
|
48
|
+
this.#proc = spawn(command, args, {
|
|
49
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
50
|
+
env: { ...process.env, ...env },
|
|
51
|
+
});
|
|
52
|
+
this.#proc.stdout.setEncoding('utf8');
|
|
53
|
+
this.#proc.stdout.on('data', (chunk) => {
|
|
54
|
+
this.#buffer += chunk;
|
|
55
|
+
const lines = this.#buffer.split('\n');
|
|
56
|
+
this.#buffer = lines.pop() || '';
|
|
57
|
+
for (const line of lines) {
|
|
58
|
+
if (!line.trim())
|
|
59
|
+
continue;
|
|
60
|
+
try {
|
|
61
|
+
this.#handle_message(JSON.parse(line));
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
// ignore non-JSON lines
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
#request(method, params) {
|
|
70
|
+
return new Promise((resolve, reject) => {
|
|
71
|
+
const id = this.#nextId++;
|
|
72
|
+
this.#pending.set(id, { resolve, reject });
|
|
73
|
+
this.#send({ jsonrpc: '2.0', id, method, params }).catch((error) => {
|
|
74
|
+
if (this.#pending.has(id)) {
|
|
75
|
+
this.#pending.delete(id);
|
|
76
|
+
reject(error);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
setTimeout(() => {
|
|
80
|
+
if (this.#pending.has(id)) {
|
|
81
|
+
this.#pending.delete(id);
|
|
82
|
+
reject(new Error(`MCP request ${method} timed out`));
|
|
83
|
+
}
|
|
84
|
+
}, 30_000);
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
async #send(msg) {
|
|
88
|
+
if (this.#config.transport === 'http') {
|
|
89
|
+
await this.#send_http(msg);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
if (!this.#proc?.stdin?.writable) {
|
|
93
|
+
throw new Error('MCP server not connected');
|
|
94
|
+
}
|
|
95
|
+
this.#proc.stdin.write(JSON.stringify(msg) + '\n');
|
|
96
|
+
}
|
|
97
|
+
async #send_http(msg) {
|
|
98
|
+
const config = this.#config;
|
|
99
|
+
const headers = new Headers(config.headers ?? {});
|
|
100
|
+
headers.set('content-type', 'application/json');
|
|
101
|
+
headers.set('accept', 'application/json, text/event-stream');
|
|
102
|
+
if (this.#sessionId) {
|
|
103
|
+
headers.set('mcp-session-id', this.#sessionId);
|
|
104
|
+
}
|
|
105
|
+
const response = await fetch(config.url, {
|
|
106
|
+
method: 'POST',
|
|
107
|
+
headers,
|
|
108
|
+
body: JSON.stringify(msg),
|
|
109
|
+
});
|
|
110
|
+
const sessionId = response.headers.get('mcp-session-id');
|
|
111
|
+
if (sessionId) {
|
|
112
|
+
this.#sessionId = sessionId;
|
|
113
|
+
}
|
|
114
|
+
if (!response.ok) {
|
|
115
|
+
const body = await response.text().catch(() => '');
|
|
116
|
+
throw new Error(`MCP HTTP ${response.status}${body ? `: ${body}` : ''}`);
|
|
117
|
+
}
|
|
118
|
+
if (response.status === 204)
|
|
119
|
+
return;
|
|
120
|
+
const contentType = response.headers.get('content-type') ?? '';
|
|
121
|
+
if (contentType.includes('text/event-stream')) {
|
|
122
|
+
await this.#consume_sse_response(response, config.name);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
const body = await response.text();
|
|
126
|
+
if (!body.trim())
|
|
127
|
+
return;
|
|
128
|
+
let parsed;
|
|
129
|
+
try {
|
|
130
|
+
parsed = JSON.parse(body);
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
throw new Error(`Invalid MCP HTTP response from ${config.name}: ${body.slice(0, 200)}`);
|
|
134
|
+
}
|
|
135
|
+
this.#dispatch_message(parsed);
|
|
136
|
+
}
|
|
137
|
+
async #disconnect_http() {
|
|
138
|
+
const config = this.#config;
|
|
139
|
+
if (!this.#sessionId)
|
|
140
|
+
return;
|
|
141
|
+
const headers = new Headers(config.headers ?? {});
|
|
142
|
+
headers.set('mcp-session-id', this.#sessionId);
|
|
143
|
+
const response = await fetch(config.url, {
|
|
144
|
+
method: 'DELETE',
|
|
145
|
+
headers,
|
|
146
|
+
});
|
|
147
|
+
if (response.status !== 405 && !response.ok) {
|
|
148
|
+
const body = await response.text().catch(() => '');
|
|
149
|
+
throw new Error(`MCP HTTP disconnect ${response.status}${body ? `: ${body}` : ''}`);
|
|
150
|
+
}
|
|
151
|
+
this.#sessionId = undefined;
|
|
152
|
+
}
|
|
153
|
+
async #consume_sse_response(response, server_name) {
|
|
154
|
+
if (!response.body)
|
|
155
|
+
return;
|
|
156
|
+
const reader = response.body.getReader();
|
|
157
|
+
const decoder = new TextDecoder();
|
|
158
|
+
let buffer = '';
|
|
159
|
+
let event_lines = [];
|
|
160
|
+
const flush_event = () => {
|
|
161
|
+
if (event_lines.length === 0)
|
|
162
|
+
return;
|
|
163
|
+
const data_lines = event_lines
|
|
164
|
+
.filter((line) => line.startsWith('data:'))
|
|
165
|
+
.map((line) => line.slice(5).trimStart());
|
|
166
|
+
event_lines = [];
|
|
167
|
+
if (data_lines.length === 0)
|
|
168
|
+
return;
|
|
169
|
+
const payload = data_lines.join('\n').trim();
|
|
170
|
+
if (!payload)
|
|
171
|
+
return;
|
|
172
|
+
try {
|
|
173
|
+
this.#dispatch_message(JSON.parse(payload));
|
|
174
|
+
}
|
|
175
|
+
catch {
|
|
176
|
+
throw new Error(`Invalid MCP SSE payload from ${server_name}: ${payload.slice(0, 200)}`);
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
while (true) {
|
|
180
|
+
const { done, value } = await reader.read();
|
|
181
|
+
buffer += decoder.decode(value ?? new Uint8Array(), {
|
|
182
|
+
stream: !done,
|
|
183
|
+
});
|
|
184
|
+
const normalized = buffer.replace(/\r\n/g, '\n');
|
|
185
|
+
const lines = normalized.split('\n');
|
|
186
|
+
buffer = lines.pop() ?? '';
|
|
187
|
+
for (const line of lines) {
|
|
188
|
+
if (line === '') {
|
|
189
|
+
flush_event();
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
if (line.startsWith(':'))
|
|
193
|
+
continue;
|
|
194
|
+
event_lines.push(line);
|
|
195
|
+
}
|
|
196
|
+
if (done)
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
199
|
+
if (buffer.trim()) {
|
|
200
|
+
event_lines.push(buffer.trim());
|
|
201
|
+
}
|
|
202
|
+
flush_event();
|
|
203
|
+
}
|
|
204
|
+
#dispatch_message(message) {
|
|
205
|
+
if (Array.isArray(message)) {
|
|
206
|
+
for (const item of message) {
|
|
207
|
+
this.#dispatch_message(item);
|
|
208
|
+
}
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
if (!message || typeof message !== 'object')
|
|
212
|
+
return;
|
|
213
|
+
this.#handle_message(message);
|
|
214
|
+
}
|
|
215
|
+
#handle_message(msg) {
|
|
216
|
+
if (msg.id == null || !this.#pending.has(msg.id))
|
|
217
|
+
return;
|
|
218
|
+
const pending = this.#pending.get(msg.id);
|
|
219
|
+
this.#pending.delete(msg.id);
|
|
220
|
+
if (msg.error) {
|
|
221
|
+
pending.reject(new Error(`MCP error ${msg.error.code}: ${msg.error.message}`));
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
pending.resolve(msg.result);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
package/dist/config.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
function is_string_record(value, label, name) {
|
|
5
|
+
if (value === undefined)
|
|
6
|
+
return true;
|
|
7
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
8
|
+
throw new Error(`Invalid MCP server "${name}": ${label} must be an object of string values`);
|
|
9
|
+
}
|
|
10
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
11
|
+
if (typeof entry !== 'string') {
|
|
12
|
+
throw new Error(`Invalid MCP server "${name}": ${label}.${key} must be a string`);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
function parse_server(name, entry) {
|
|
18
|
+
const type = typeof entry.type === 'string'
|
|
19
|
+
? entry.type.trim().toLowerCase()
|
|
20
|
+
: '';
|
|
21
|
+
if (type && !['stdio', 'http', 'streamable-http'].includes(type)) {
|
|
22
|
+
throw new Error(`Invalid MCP server "${name}": unsupported transport type "${type}"`);
|
|
23
|
+
}
|
|
24
|
+
if (type === 'http' ||
|
|
25
|
+
type === 'streamable-http' ||
|
|
26
|
+
entry.url !== undefined) {
|
|
27
|
+
if (typeof entry.url !== 'string' || !entry.url.trim()) {
|
|
28
|
+
throw new Error(`Invalid MCP server "${name}": http transport requires a url`);
|
|
29
|
+
}
|
|
30
|
+
is_string_record(entry.headers, 'headers', name);
|
|
31
|
+
const headers = entry.headers;
|
|
32
|
+
const config = {
|
|
33
|
+
name,
|
|
34
|
+
transport: 'http',
|
|
35
|
+
url: entry.url.trim(),
|
|
36
|
+
...(headers ? { headers } : {}),
|
|
37
|
+
};
|
|
38
|
+
return config;
|
|
39
|
+
}
|
|
40
|
+
if (typeof entry.command !== 'string' || !entry.command.trim()) {
|
|
41
|
+
throw new Error(`Invalid MCP server "${name}": stdio transport requires a command`);
|
|
42
|
+
}
|
|
43
|
+
if (entry.args !== undefined &&
|
|
44
|
+
(!Array.isArray(entry.args) ||
|
|
45
|
+
entry.args.some((value) => typeof value !== 'string'))) {
|
|
46
|
+
throw new Error(`Invalid MCP server "${name}": args must be an array of strings`);
|
|
47
|
+
}
|
|
48
|
+
is_string_record(entry.env, 'env', name);
|
|
49
|
+
const args = entry.args;
|
|
50
|
+
const env = entry.env;
|
|
51
|
+
const config = {
|
|
52
|
+
name,
|
|
53
|
+
transport: 'stdio',
|
|
54
|
+
command: entry.command.trim(),
|
|
55
|
+
...(args ? { args } : {}),
|
|
56
|
+
...(env ? { env } : {}),
|
|
57
|
+
};
|
|
58
|
+
return config;
|
|
59
|
+
}
|
|
60
|
+
function read_config(path) {
|
|
61
|
+
if (!existsSync(path))
|
|
62
|
+
return {};
|
|
63
|
+
const raw = readFileSync(path, 'utf-8');
|
|
64
|
+
const config = JSON.parse(raw);
|
|
65
|
+
return config.mcpServers || {};
|
|
66
|
+
}
|
|
67
|
+
export function load_mcp_config(cwd) {
|
|
68
|
+
const global_servers = read_config(join(homedir(), '.pi', 'agent', 'mcp.json'));
|
|
69
|
+
const project_servers = read_config(join(cwd, 'mcp.json'));
|
|
70
|
+
const merged = { ...global_servers, ...project_servers };
|
|
71
|
+
return Object.entries(merged).map(([name, server]) => parse_server(name, server));
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAoBjC,SAAS,gBAAgB,CACxB,KAAc,EACd,KAAa,EACb,IAAY;IAEZ,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACrC,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACjE,MAAM,IAAI,KAAK,CACd,uBAAuB,IAAI,MAAM,KAAK,qCAAqC,CAC3E,CAAC;IACH,CAAC;IAED,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAClD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CACd,uBAAuB,IAAI,MAAM,KAAK,IAAI,GAAG,mBAAmB,CAChE,CAAC;QACH,CAAC;IACF,CAAC;IAED,OAAO,IAAI,CAAC;AACb,CAAC;AAED,SAAS,YAAY,CACpB,IAAY,EACZ,KAAwB;IAExB,MAAM,IAAI,GACT,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;QAC7B,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE;QACjC,CAAC,CAAC,EAAE,CAAC;IAEP,IAAI,IAAI,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,iBAAiB,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAClE,MAAM,IAAI,KAAK,CACd,uBAAuB,IAAI,kCAAkC,IAAI,GAAG,CACpE,CAAC;IACH,CAAC;IAED,IACC,IAAI,KAAK,MAAM;QACf,IAAI,KAAK,iBAAiB;QAC1B,KAAK,CAAC,GAAG,KAAK,SAAS,EACtB,CAAC;QACF,IAAI,OAAO,KAAK,CAAC,GAAG,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;YACxD,MAAM,IAAI,KAAK,CACd,uBAAuB,IAAI,kCAAkC,CAC7D,CAAC;QACH,CAAC;QACD,gBAAgB,CAAC,KAAK,CAAC,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;QACjD,MAAM,OAAO,GAAG,KAAK,CAAC,OAEV,CAAC;QACb,MAAM,MAAM,GAAwB;YACnC,IAAI;YACJ,SAAS,EAAE,MAAM;YACjB,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE;YACrB,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC/B,CAAC;QACF,OAAO,MAAM,CAAC;IACf,CAAC;IAED,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;QAChE,MAAM,IAAI,KAAK,CACd,uBAAuB,IAAI,uCAAuC,CAClE,CAAC;IACH,CAAC;IACD,IACC,KAAK,CAAC,IAAI,KAAK,SAAS;QACxB,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC;YAC1B,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,EACtD,CAAC;QACF,MAAM,IAAI,KAAK,CACd,uBAAuB,IAAI,qCAAqC,CAChE,CAAC;IACH,CAAC;IACD,gBAAgB,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IACzC,MAAM,IAAI,GAAG,KAAK,CAAC,IAA4B,CAAC;IAChD,MAAM,GAAG,GAAG,KAAK,CAAC,GAAyC,CAAC;IAE5D,MAAM,MAAM,GAAyB;QACpC,IAAI;QACJ,SAAS,EAAE,OAAO;QAClB,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE;QAC7B,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzB,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACvB,CAAC;IACF,OAAO,MAAM,CAAC;AACf,CAAC;AAED,SAAS,WAAW,CAAC,IAAY;IAChC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IACjC,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAqB,CAAC;IACnD,OAAO,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,GAAW;IAC1C,MAAM,cAAc,GAAG,WAAW,CACjC,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,CAAC,CAC3C,CAAC;IACF,MAAM,eAAe,GAAG,WAAW,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC;IAC3D,MAAM,MAAM,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,eAAe,EAAE,CAAC;IAEzD,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE,CACpD,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAC1B,CAAC;AACH,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { type BeforeAgentStartEvent, type ExtensionAPI } from '@mariozechner/pi-coding-agent';
|
|
2
|
+
export declare function should_wait_for_mcp_connections(event: Pick<BeforeAgentStartEvent, 'systemPromptOptions'>): boolean;
|
|
3
|
+
export default function mcp(pi: ExtensionAPI): Promise<void>;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
import { defineTool, } from '@mariozechner/pi-coding-agent';
|
|
2
|
+
import { McpClient } from './client.js';
|
|
3
|
+
import { load_mcp_config } from './config.js';
|
|
4
|
+
function create_server_states(configs) {
|
|
5
|
+
return new Map(configs.map((config) => [
|
|
6
|
+
config.name,
|
|
7
|
+
{
|
|
8
|
+
config,
|
|
9
|
+
tool_names: [],
|
|
10
|
+
enabled: true,
|
|
11
|
+
status: 'disconnected',
|
|
12
|
+
},
|
|
13
|
+
]));
|
|
14
|
+
}
|
|
15
|
+
function remove_server_tools_from_active(pi, tool_names) {
|
|
16
|
+
const tool_set = new Set(tool_names);
|
|
17
|
+
pi.setActiveTools(pi.getActiveTools().filter((tool) => !tool_set.has(tool)));
|
|
18
|
+
}
|
|
19
|
+
function format_server_status(state) {
|
|
20
|
+
switch (state.status) {
|
|
21
|
+
case 'connected':
|
|
22
|
+
return state.enabled ? 'enabled' : 'disabled';
|
|
23
|
+
case 'connecting':
|
|
24
|
+
return state.enabled ? 'connecting' : 'connecting, disabled';
|
|
25
|
+
case 'failed':
|
|
26
|
+
return state.enabled ? 'failed' : 'failed, disabled';
|
|
27
|
+
default:
|
|
28
|
+
return state.enabled ? 'not connected yet' : 'disabled';
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function count_pending_enabled_servers(servers) {
|
|
32
|
+
return Array.from(servers.values()).filter((state) => state.enabled && state.status !== 'connected').length;
|
|
33
|
+
}
|
|
34
|
+
function report_mcp_failure(state, ctx) {
|
|
35
|
+
const message = `MCP server failed (${state.config.name}): ${state.error}`;
|
|
36
|
+
if (ctx?.hasUI) {
|
|
37
|
+
ctx.ui.notify(message, 'warning');
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
console.error(message);
|
|
41
|
+
}
|
|
42
|
+
function update_mcp_status(ctx, servers) {
|
|
43
|
+
if (!ctx.hasUI)
|
|
44
|
+
return;
|
|
45
|
+
if (servers.size === 0) {
|
|
46
|
+
ctx.ui.setStatus('mcp', undefined);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const states = Array.from(servers.values());
|
|
50
|
+
const enabled = states.filter((state) => state.enabled).length;
|
|
51
|
+
const connected = states.filter((state) => state.enabled && state.status === 'connected').length;
|
|
52
|
+
const connecting = states.filter((state) => state.enabled && state.status === 'connecting').length;
|
|
53
|
+
const failed = states.filter((state) => state.enabled && state.status === 'failed').length;
|
|
54
|
+
const fragments = [`MCP ${connected}/${enabled} connected`];
|
|
55
|
+
if (connecting > 0)
|
|
56
|
+
fragments.push(`${connecting} connecting`);
|
|
57
|
+
if (failed > 0)
|
|
58
|
+
fragments.push(`${failed} failed`);
|
|
59
|
+
ctx.ui.setStatus('mcp', ctx.ui.theme.fg('dim', fragments.join(' · ')));
|
|
60
|
+
}
|
|
61
|
+
function set_connect_feedback(ctx, pending_server_count) {
|
|
62
|
+
if (!ctx.hasUI) {
|
|
63
|
+
return () => { };
|
|
64
|
+
}
|
|
65
|
+
const label = pending_server_count === 1
|
|
66
|
+
? 'Connecting 1 MCP server...'
|
|
67
|
+
: `Connecting ${pending_server_count} MCP servers...`;
|
|
68
|
+
ctx.ui.setWorkingMessage(label);
|
|
69
|
+
ctx.ui.setWorkingIndicator({
|
|
70
|
+
frames: [
|
|
71
|
+
ctx.ui.theme.fg('dim', '·'),
|
|
72
|
+
ctx.ui.theme.fg('muted', '•'),
|
|
73
|
+
ctx.ui.theme.fg('accent', '●'),
|
|
74
|
+
ctx.ui.theme.fg('muted', '•'),
|
|
75
|
+
],
|
|
76
|
+
intervalMs: 120,
|
|
77
|
+
});
|
|
78
|
+
ctx.ui.setStatus('mcp', ctx.ui.theme.fg('dim', label));
|
|
79
|
+
return () => {
|
|
80
|
+
ctx.ui.setWorkingMessage();
|
|
81
|
+
ctx.ui.setWorkingIndicator();
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
export function should_wait_for_mcp_connections(event) {
|
|
85
|
+
const selected_tools = event.systemPromptOptions?.selectedTools;
|
|
86
|
+
return (!selected_tools ||
|
|
87
|
+
selected_tools.some((tool) => tool.startsWith('mcp__')));
|
|
88
|
+
}
|
|
89
|
+
// Default export for Pi Package / additionalExtensionPaths loading
|
|
90
|
+
export default async function mcp(pi) {
|
|
91
|
+
let initialized_cwd = null;
|
|
92
|
+
let servers = new Map();
|
|
93
|
+
const registered_tool_names = new Set();
|
|
94
|
+
const ensure_servers = (cwd) => {
|
|
95
|
+
if (initialized_cwd !== null)
|
|
96
|
+
return;
|
|
97
|
+
servers = create_server_states(load_mcp_config(cwd));
|
|
98
|
+
initialized_cwd = cwd;
|
|
99
|
+
};
|
|
100
|
+
const connect_server = async (state, ctx) => {
|
|
101
|
+
if (state.status === 'connected')
|
|
102
|
+
return;
|
|
103
|
+
if (state.connect_promise) {
|
|
104
|
+
await state.connect_promise;
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
state.connect_promise = (async () => {
|
|
108
|
+
state.status = 'connecting';
|
|
109
|
+
state.error = undefined;
|
|
110
|
+
if (ctx)
|
|
111
|
+
update_mcp_status(ctx, servers);
|
|
112
|
+
const client = new McpClient(state.config);
|
|
113
|
+
try {
|
|
114
|
+
await client.connect();
|
|
115
|
+
state.client = client;
|
|
116
|
+
const mcp_tools = await client.listTools();
|
|
117
|
+
const tool_names = [];
|
|
118
|
+
for (const mcp_tool of mcp_tools) {
|
|
119
|
+
const tool_name = `mcp__${state.config.name}__${mcp_tool.name}`;
|
|
120
|
+
tool_names.push(tool_name);
|
|
121
|
+
if (registered_tool_names.has(tool_name))
|
|
122
|
+
continue;
|
|
123
|
+
registered_tool_names.add(tool_name);
|
|
124
|
+
pi.registerTool(defineTool({
|
|
125
|
+
name: tool_name,
|
|
126
|
+
label: `${state.config.name}: ${mcp_tool.name}`,
|
|
127
|
+
description: mcp_tool.description || mcp_tool.name,
|
|
128
|
+
parameters: (mcp_tool.inputSchema || {
|
|
129
|
+
type: 'object',
|
|
130
|
+
properties: {},
|
|
131
|
+
}),
|
|
132
|
+
execute: async (_id, params) => {
|
|
133
|
+
const result = (await state.client.callTool(mcp_tool.name, params));
|
|
134
|
+
const text = result?.content
|
|
135
|
+
?.map((c) => c.text || '')
|
|
136
|
+
.join('\n') || JSON.stringify(result);
|
|
137
|
+
return {
|
|
138
|
+
content: [{ type: 'text', text }],
|
|
139
|
+
details: {},
|
|
140
|
+
};
|
|
141
|
+
},
|
|
142
|
+
}));
|
|
143
|
+
}
|
|
144
|
+
state.tool_names = tool_names;
|
|
145
|
+
state.status = 'connected';
|
|
146
|
+
if (!state.enabled) {
|
|
147
|
+
remove_server_tools_from_active(pi, state.tool_names);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
catch (error) {
|
|
151
|
+
state.status = 'failed';
|
|
152
|
+
state.error =
|
|
153
|
+
error instanceof Error ? error.message : String(error);
|
|
154
|
+
state.client = undefined;
|
|
155
|
+
await client.disconnect().catch(() => { });
|
|
156
|
+
report_mcp_failure(state, ctx);
|
|
157
|
+
throw error;
|
|
158
|
+
}
|
|
159
|
+
finally {
|
|
160
|
+
state.connect_promise = undefined;
|
|
161
|
+
if (ctx)
|
|
162
|
+
update_mcp_status(ctx, servers);
|
|
163
|
+
}
|
|
164
|
+
})();
|
|
165
|
+
await state.connect_promise;
|
|
166
|
+
};
|
|
167
|
+
const connect_all_servers = async (options = {}) => {
|
|
168
|
+
await Promise.allSettled(Array.from(servers.values())
|
|
169
|
+
.filter((state) => state.enabled)
|
|
170
|
+
.filter((state) => options.include_failed || state.status !== 'failed')
|
|
171
|
+
.map((state) => connect_server(state, options.ctx)));
|
|
172
|
+
if (options.ctx)
|
|
173
|
+
update_mcp_status(options.ctx, servers);
|
|
174
|
+
};
|
|
175
|
+
pi.on('session_start', async (_event, ctx) => {
|
|
176
|
+
ensure_servers(ctx.cwd);
|
|
177
|
+
update_mcp_status(ctx, servers);
|
|
178
|
+
void connect_all_servers({ ctx });
|
|
179
|
+
});
|
|
180
|
+
pi.on('before_agent_start', async (event, ctx) => {
|
|
181
|
+
ensure_servers(ctx.cwd);
|
|
182
|
+
if (!should_wait_for_mcp_connections(event)) {
|
|
183
|
+
void connect_all_servers({ ctx });
|
|
184
|
+
return event;
|
|
185
|
+
}
|
|
186
|
+
const pending_server_count = count_pending_enabled_servers(servers);
|
|
187
|
+
if (pending_server_count === 0) {
|
|
188
|
+
update_mcp_status(ctx, servers);
|
|
189
|
+
return event;
|
|
190
|
+
}
|
|
191
|
+
const restore_feedback = set_connect_feedback(ctx, pending_server_count);
|
|
192
|
+
try {
|
|
193
|
+
await connect_all_servers({ ctx });
|
|
194
|
+
return event;
|
|
195
|
+
}
|
|
196
|
+
finally {
|
|
197
|
+
restore_feedback();
|
|
198
|
+
update_mcp_status(ctx, servers);
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
pi.registerCommand('mcp', {
|
|
202
|
+
description: 'Manage MCP servers (list, enable, disable)',
|
|
203
|
+
getArgumentCompletions: (prefix) => {
|
|
204
|
+
const parts = prefix.split(' ');
|
|
205
|
+
if (parts.length <= 1) {
|
|
206
|
+
return ['list', 'enable', 'disable']
|
|
207
|
+
.filter((s) => s.startsWith(prefix))
|
|
208
|
+
.map((s) => ({ value: s, label: s }));
|
|
209
|
+
}
|
|
210
|
+
if (parts[0] === 'enable' || parts[0] === 'disable') {
|
|
211
|
+
const name_prefix = parts[1] || '';
|
|
212
|
+
return Array.from(servers.keys())
|
|
213
|
+
.filter((n) => n.startsWith(name_prefix))
|
|
214
|
+
.map((n) => ({
|
|
215
|
+
value: `${parts[0]} ${n}`,
|
|
216
|
+
label: n,
|
|
217
|
+
}));
|
|
218
|
+
}
|
|
219
|
+
return null;
|
|
220
|
+
},
|
|
221
|
+
handler: async (args, ctx) => {
|
|
222
|
+
ensure_servers(ctx.cwd);
|
|
223
|
+
const [sub, ...rest] = args.trim().split(/\s+/);
|
|
224
|
+
const name = rest.join(' ');
|
|
225
|
+
switch (sub || 'list') {
|
|
226
|
+
case 'list': {
|
|
227
|
+
if (servers.size === 0) {
|
|
228
|
+
ctx.ui.notify('No MCP servers configured');
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
const lines = [];
|
|
232
|
+
for (const [sname, state] of servers.entries()) {
|
|
233
|
+
lines.push(`${sname} (${format_server_status(state)}) — ${state.tool_names.length} tools${state.error ? ` — ${state.error}` : ''}`);
|
|
234
|
+
}
|
|
235
|
+
update_mcp_status(ctx, servers);
|
|
236
|
+
ctx.ui.notify(lines.join('\n'));
|
|
237
|
+
break;
|
|
238
|
+
}
|
|
239
|
+
case 'enable': {
|
|
240
|
+
const server = servers.get(name);
|
|
241
|
+
if (!server) {
|
|
242
|
+
ctx.ui.notify(`Unknown server: ${name}`, 'warning');
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
if (server.enabled && server.status !== 'failed') {
|
|
246
|
+
ctx.ui.notify(`${name} already enabled`);
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
server.enabled = true;
|
|
250
|
+
if (server.status === 'connected') {
|
|
251
|
+
const active = pi.getActiveTools();
|
|
252
|
+
pi.setActiveTools([
|
|
253
|
+
...new Set([...active, ...server.tool_names]),
|
|
254
|
+
]);
|
|
255
|
+
update_mcp_status(ctx, servers);
|
|
256
|
+
ctx.ui.notify(`Enabled ${name}`);
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
if (server.status === 'failed') {
|
|
260
|
+
server.status = 'disconnected';
|
|
261
|
+
server.error = undefined;
|
|
262
|
+
}
|
|
263
|
+
update_mcp_status(ctx, servers);
|
|
264
|
+
void connect_server(server, ctx);
|
|
265
|
+
ctx.ui.notify(`Enabling ${name} and connecting in background`);
|
|
266
|
+
break;
|
|
267
|
+
}
|
|
268
|
+
case 'disable': {
|
|
269
|
+
const server = servers.get(name);
|
|
270
|
+
if (!server) {
|
|
271
|
+
ctx.ui.notify(`Unknown server: ${name}`, 'warning');
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
if (!server.enabled) {
|
|
275
|
+
ctx.ui.notify(`${name} already disabled`);
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
server.enabled = false;
|
|
279
|
+
remove_server_tools_from_active(pi, server.tool_names);
|
|
280
|
+
update_mcp_status(ctx, servers);
|
|
281
|
+
ctx.ui.notify(`Disabled ${name}`);
|
|
282
|
+
break;
|
|
283
|
+
}
|
|
284
|
+
default:
|
|
285
|
+
ctx.ui.notify(`Unknown subcommand: ${sub}. Use list, enable, or disable.`, 'warning');
|
|
286
|
+
}
|
|
287
|
+
},
|
|
288
|
+
});
|
|
289
|
+
pi.on('session_shutdown', async (_event, ctx) => {
|
|
290
|
+
await Promise.allSettled(Array.from(servers.values()).map(async (server) => {
|
|
291
|
+
await server.connect_promise?.catch(() => { });
|
|
292
|
+
await server.client?.disconnect();
|
|
293
|
+
server.client = undefined;
|
|
294
|
+
if (server.status !== 'failed') {
|
|
295
|
+
server.status = 'disconnected';
|
|
296
|
+
}
|
|
297
|
+
}));
|
|
298
|
+
ctx.ui.setStatus('mcp', undefined);
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
//# 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,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@spences10/pi-mcp",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Pi extension for connecting MCP servers and exposing their tools",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"mcp",
|
|
7
|
+
"model-context-protocol",
|
|
8
|
+
"pi",
|
|
9
|
+
"pi-package"
|
|
10
|
+
],
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"author": "Scott Spence <me@scottspence.com>",
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "git+https://github.com/spences10/my-pi.git",
|
|
16
|
+
"directory": "packages/pi-mcp"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist",
|
|
20
|
+
"README.md"
|
|
21
|
+
],
|
|
22
|
+
"type": "module",
|
|
23
|
+
"main": "./dist/index.js",
|
|
24
|
+
"types": "./dist/index.d.ts",
|
|
25
|
+
"exports": {
|
|
26
|
+
".": {
|
|
27
|
+
"types": "./dist/index.d.ts",
|
|
28
|
+
"default": "./dist/index.js"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"publishConfig": {
|
|
32
|
+
"access": "public"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@mariozechner/pi-coding-agent": "^0.70.2"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@types/node": "^25.6.0",
|
|
39
|
+
"typescript": "^5.9.3",
|
|
40
|
+
"vitest": "^4.1.5"
|
|
41
|
+
},
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=22.0.0"
|
|
44
|
+
},
|
|
45
|
+
"pi": {
|
|
46
|
+
"extensions": [
|
|
47
|
+
"./dist/index.js"
|
|
48
|
+
]
|
|
49
|
+
},
|
|
50
|
+
"scripts": {
|
|
51
|
+
"build": "tsc -p tsconfig.build.json",
|
|
52
|
+
"check": "tsc --noEmit -p tsconfig.json",
|
|
53
|
+
"test": "vitest run"
|
|
54
|
+
}
|
|
55
|
+
}
|