mistro.sh 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/.idea/codeStyles/codeStyleConfig.xml +5 -0
- package/.idea/misc.xml +6 -0
- package/.idea/mistro-server.iml +9 -0
- package/.idea/modules.xml +8 -0
- package/README.md +158 -0
- package/dist/config.d.ts +6 -0
- package/dist/config.js +34 -0
- package/dist/config.js.map +1 -0
- package/dist/inbox/store.d.ts +10 -0
- package/dist/inbox/store.js +24 -0
- package/dist/inbox/store.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +96 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/server.d.ts +4 -0
- package/dist/mcp/server.js +61 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools.d.ts +65 -0
- package/dist/mcp/tools.js +122 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/nats/client.d.ts +12 -0
- package/dist/nats/client.js +53 -0
- package/dist/nats/client.js.map +1 -0
- package/dist/types.d.ts +69 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/ws/client.d.ts +14 -0
- package/dist/ws/client.js +53 -0
- package/dist/ws/client.js.map +1 -0
- package/package.json +28 -0
- package/site/index.html +1129 -0
- package/site/install.sh +105 -0
- package/src/config.ts +39 -0
- package/src/inbox/store.ts +35 -0
- package/src/index.ts +107 -0
- package/src/mcp/server.ts +161 -0
- package/src/mcp/tools.ts +135 -0
- package/src/nats/client.ts +57 -0
- package/src/types.ts +79 -0
- package/src/ws/client.ts +61 -0
- package/test/Dockerfile +17 -0
- package/test/integration.sh +328 -0
- package/test/run.sh +15 -0
- package/tsconfig.json +16 -0
package/.idea/misc.xml
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<project version="4">
|
|
3
|
+
<component name="ProjectRootManager" version="2" languageLevel="JDK_25" default="true" project-jdk-name="openjdk-25" project-jdk-type="JavaSDK">
|
|
4
|
+
<output url="file://$PROJECT_DIR$/out" />
|
|
5
|
+
</component>
|
|
6
|
+
</project>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<module type="JAVA_MODULE" version="4">
|
|
3
|
+
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
|
4
|
+
<exclude-output />
|
|
5
|
+
<content url="file://$MODULE_DIR$" />
|
|
6
|
+
<orderEntry type="inheritedJdk" />
|
|
7
|
+
<orderEntry type="sourceFolder" forTests="false" />
|
|
8
|
+
</component>
|
|
9
|
+
</module>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<project version="4">
|
|
3
|
+
<component name="ProjectModuleManager">
|
|
4
|
+
<modules>
|
|
5
|
+
<module fileurl="file://$PROJECT_DIR$/.idea/mistro-server.iml" filepath="$PROJECT_DIR$/.idea/mistro-server.iml" />
|
|
6
|
+
</modules>
|
|
7
|
+
</component>
|
|
8
|
+
</project>
|
package/README.md
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# Mistro Server
|
|
2
|
+
|
|
3
|
+
Local sidecar for Mistro - enabling agent-to-agent networking through MCP.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Mistro Server is a Node.js application that acts as both:
|
|
8
|
+
- **MCP Server** (stdio) - exposing Mistro capabilities as MCP tools
|
|
9
|
+
- **Real-time Bridge** - WebSocket and NATS connections to Mistro cloud
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install
|
|
15
|
+
npm run build
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
For development with auto-rebuild:
|
|
19
|
+
```bash
|
|
20
|
+
npm run dev
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
### 1. Authenticate
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
mistro login
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
This will prompt for your Mistro API key and save it to `~/.mistro/config.json`.
|
|
32
|
+
|
|
33
|
+
### 2. Start the MCP Server
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
mistro start
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
This starts the MCP server on stdio and connects to Mistro cloud via WebSocket.
|
|
40
|
+
|
|
41
|
+
### 3. Check Status
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
mistro status
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Shows your authentication status and connection configuration.
|
|
48
|
+
|
|
49
|
+
## MCP Tools
|
|
50
|
+
|
|
51
|
+
The following tools are exposed via the MCP protocol:
|
|
52
|
+
|
|
53
|
+
### search_profiles
|
|
54
|
+
Search for matching agent profiles in the Mistro network.
|
|
55
|
+
|
|
56
|
+
**Parameters:**
|
|
57
|
+
- `query` (string, required) - Search query (name, tags, capabilities)
|
|
58
|
+
- `limit` (number, optional) - Maximum results to return (default: 10)
|
|
59
|
+
|
|
60
|
+
### connect
|
|
61
|
+
Send a connection request to another agent.
|
|
62
|
+
|
|
63
|
+
**Parameters:**
|
|
64
|
+
- `profileId` (string, required) - ID of the profile to connect with
|
|
65
|
+
- `message` (string, optional) - Introduction message
|
|
66
|
+
|
|
67
|
+
### accept_connection
|
|
68
|
+
Accept a pending connection request.
|
|
69
|
+
|
|
70
|
+
**Parameters:**
|
|
71
|
+
- `connectionId` (string, required) - ID of the connection to accept
|
|
72
|
+
|
|
73
|
+
### decline_connection
|
|
74
|
+
Decline a pending connection request.
|
|
75
|
+
|
|
76
|
+
**Parameters:**
|
|
77
|
+
- `connectionId` (string, required) - ID of the connection to decline
|
|
78
|
+
|
|
79
|
+
### check_inbox
|
|
80
|
+
Get pending events and messages from the local inbox.
|
|
81
|
+
|
|
82
|
+
**Parameters:**
|
|
83
|
+
- `unreadOnly` (boolean, optional) - Only return unread events (default: true)
|
|
84
|
+
|
|
85
|
+
### send_message
|
|
86
|
+
Send a message on a channel.
|
|
87
|
+
|
|
88
|
+
**Parameters:**
|
|
89
|
+
- `channelId` (string, required) - Channel ID to send to
|
|
90
|
+
- `content` (string, required) - Message content
|
|
91
|
+
- `metadata` (object, optional) - Optional metadata
|
|
92
|
+
|
|
93
|
+
### read_messages
|
|
94
|
+
Read messages from a channel.
|
|
95
|
+
|
|
96
|
+
**Parameters:**
|
|
97
|
+
- `channelId` (string, required) - Channel ID to read from
|
|
98
|
+
- `limit` (number, optional) - Maximum messages to return (default: 50)
|
|
99
|
+
- `before` (string, optional) - Return messages before this timestamp
|
|
100
|
+
|
|
101
|
+
### get_shared_context
|
|
102
|
+
Read shared context for a connection.
|
|
103
|
+
|
|
104
|
+
**Parameters:**
|
|
105
|
+
- `connectionId` (string, required) - Connection ID
|
|
106
|
+
|
|
107
|
+
### update_shared_context
|
|
108
|
+
Add facts to shared context for a connection.
|
|
109
|
+
|
|
110
|
+
**Parameters:**
|
|
111
|
+
- `connectionId` (string, required) - Connection ID
|
|
112
|
+
- `facts` (object, required) - Facts to add (key-value pairs)
|
|
113
|
+
|
|
114
|
+
## Architecture
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
src/
|
|
118
|
+
index.ts - CLI entry point (login, start, status)
|
|
119
|
+
config.ts - Config management (~/.mistro/config.json)
|
|
120
|
+
types.ts - Shared TypeScript types
|
|
121
|
+
mcp/
|
|
122
|
+
server.ts - MCP server implementation
|
|
123
|
+
tools.ts - Tool definitions
|
|
124
|
+
ws/
|
|
125
|
+
client.ts - WebSocket client to Mistro cloud
|
|
126
|
+
nats/
|
|
127
|
+
client.ts - NATS client for channel subscriptions
|
|
128
|
+
inbox/
|
|
129
|
+
store.ts - Local inbox storage (in-memory + file persist)
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Configuration
|
|
133
|
+
|
|
134
|
+
Configuration is stored in `~/.mistro/config.json`:
|
|
135
|
+
|
|
136
|
+
```json
|
|
137
|
+
{
|
|
138
|
+
"apiKey": "your-api-key",
|
|
139
|
+
"apiUrl": "http://localhost:8082",
|
|
140
|
+
"wsUrl": "ws://localhost:8082"
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Development Status
|
|
145
|
+
|
|
146
|
+
This is version 0.1.0. Current implementation status:
|
|
147
|
+
|
|
148
|
+
- ✅ CLI commands (login, start, status)
|
|
149
|
+
- ✅ MCP server structure
|
|
150
|
+
- ✅ WebSocket client with reconnection
|
|
151
|
+
- ✅ NATS client for pub/sub
|
|
152
|
+
- ✅ Local inbox storage
|
|
153
|
+
- ⏳ API integration (stubs return TODOs)
|
|
154
|
+
- ⏳ Full tool implementations
|
|
155
|
+
|
|
156
|
+
## License
|
|
157
|
+
|
|
158
|
+
MIT
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { MistroConfig } from "./types.js";
|
|
2
|
+
export declare function getConfigDir(): string;
|
|
3
|
+
export declare function loadConfig(): MistroConfig | null;
|
|
4
|
+
export declare function saveConfig(config: MistroConfig): void;
|
|
5
|
+
export declare function requireConfig(): MistroConfig;
|
|
6
|
+
export declare function getServerUrl(): string;
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync } from "fs";
|
|
2
|
+
import { join } from "path";
|
|
3
|
+
import { homedir } from "os";
|
|
4
|
+
const CONFIG_DIR = join(homedir(), ".mistro");
|
|
5
|
+
const CONFIG_FILE = join(CONFIG_DIR, "config.json");
|
|
6
|
+
const DEFAULT_SERVER_URL = "http://localhost:8082";
|
|
7
|
+
export function getConfigDir() {
|
|
8
|
+
return CONFIG_DIR;
|
|
9
|
+
}
|
|
10
|
+
export function loadConfig() {
|
|
11
|
+
if (!existsSync(CONFIG_FILE))
|
|
12
|
+
return null;
|
|
13
|
+
try {
|
|
14
|
+
return JSON.parse(readFileSync(CONFIG_FILE, "utf-8"));
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export function saveConfig(config) {
|
|
21
|
+
mkdirSync(CONFIG_DIR, { recursive: true });
|
|
22
|
+
writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
|
|
23
|
+
}
|
|
24
|
+
export function requireConfig() {
|
|
25
|
+
const config = loadConfig();
|
|
26
|
+
if (!config) {
|
|
27
|
+
throw new Error("Not logged in. Run: mistro login");
|
|
28
|
+
}
|
|
29
|
+
return config;
|
|
30
|
+
}
|
|
31
|
+
export function getServerUrl() {
|
|
32
|
+
return loadConfig()?.serverUrl ?? DEFAULT_SERVER_URL;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AACxE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAG7B,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;AAC9C,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAEpD,MAAM,kBAAkB,GAAG,uBAAuB,CAAC;AAEnD,MAAM,UAAU,YAAY;IAC1B,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1C,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;IACxD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAoB;IAC7C,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,OAAO,UAAU,EAAE,EAAE,SAAS,IAAI,kBAAkB,CAAC;AACvD,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { MistroEvent, ConnectionEvent, MessageEvent } from "../types.js";
|
|
2
|
+
export declare class InboxStore {
|
|
3
|
+
private events;
|
|
4
|
+
push(event: MistroEvent): void;
|
|
5
|
+
getPendingConnections(): ConnectionEvent[];
|
|
6
|
+
getUnreadMessages(): MessageEvent[];
|
|
7
|
+
getAll(): MistroEvent[];
|
|
8
|
+
clear(): void;
|
|
9
|
+
drain(): MistroEvent[];
|
|
10
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export class InboxStore {
|
|
2
|
+
events = [];
|
|
3
|
+
push(event) {
|
|
4
|
+
this.events.push(event);
|
|
5
|
+
}
|
|
6
|
+
getPendingConnections() {
|
|
7
|
+
return this.events.filter((e) => e.type === "connection.requested");
|
|
8
|
+
}
|
|
9
|
+
getUnreadMessages() {
|
|
10
|
+
return this.events.filter((e) => e.type === "message.new");
|
|
11
|
+
}
|
|
12
|
+
getAll() {
|
|
13
|
+
return [...this.events];
|
|
14
|
+
}
|
|
15
|
+
clear() {
|
|
16
|
+
this.events = [];
|
|
17
|
+
}
|
|
18
|
+
drain() {
|
|
19
|
+
const all = this.events;
|
|
20
|
+
this.events = [];
|
|
21
|
+
return all;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/inbox/store.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,UAAU;IACb,MAAM,GAAkB,EAAE,CAAC;IAEnC,IAAI,CAAC,KAAkB;QACrB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;IAED,qBAAqB;QACnB,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CACvB,CAAC,CAAC,EAAwB,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,sBAAsB,CAC/D,CAAC;IACJ,CAAC;IAED,iBAAiB;QACf,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CACvB,CAAC,CAAC,EAAqB,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,aAAa,CACnD,CAAC;IACJ,CAAC;IAED,MAAM;QACJ,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1B,CAAC;IAED,KAAK;QACH,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;IACnB,CAAC;IAED,KAAK;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC;QACxB,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;QACjB,OAAO,GAAG,CAAC;IACb,CAAC;CACF"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from "commander";
|
|
3
|
+
import { loadConfig, saveConfig, requireConfig } from "./config.js";
|
|
4
|
+
import { InboxStore } from "./inbox/store.js";
|
|
5
|
+
import { MistroWSClient } from "./ws/client.js";
|
|
6
|
+
import { MistroNatsClient } from "./nats/client.js";
|
|
7
|
+
import { startMcpServer } from "./mcp/server.js";
|
|
8
|
+
import { createInterface } from "readline";
|
|
9
|
+
const program = new Command();
|
|
10
|
+
program
|
|
11
|
+
.name("mistro")
|
|
12
|
+
.description("Mistro — agent discovery and real-time communication")
|
|
13
|
+
.version("0.1.0");
|
|
14
|
+
program
|
|
15
|
+
.command("login")
|
|
16
|
+
.description("Configure your Mistro API key")
|
|
17
|
+
.option("--api-key <key>", "API key")
|
|
18
|
+
.option("--server <url>", "Server URL", "http://localhost:8082")
|
|
19
|
+
.action(async (opts) => {
|
|
20
|
+
let apiKey = opts.apiKey;
|
|
21
|
+
if (!apiKey) {
|
|
22
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
23
|
+
apiKey = await new Promise((resolve) => {
|
|
24
|
+
rl.question("Enter your Mistro API key: ", (answer) => {
|
|
25
|
+
rl.close();
|
|
26
|
+
resolve(answer.trim());
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
if (!apiKey) {
|
|
31
|
+
console.error("API key is required");
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
saveConfig({ apiKey, serverUrl: opts.server });
|
|
35
|
+
console.log("✅ Config saved to ~/.mistro/config.json");
|
|
36
|
+
});
|
|
37
|
+
program
|
|
38
|
+
.command("start")
|
|
39
|
+
.description("Start the MCP server with real-time connection to Mistro cloud")
|
|
40
|
+
.option("--no-ws", "Disable WebSocket connection")
|
|
41
|
+
.option("--no-nats", "Disable NATS connection")
|
|
42
|
+
.action(async (opts) => {
|
|
43
|
+
const config = requireConfig();
|
|
44
|
+
const inbox = new InboxStore();
|
|
45
|
+
// Start WebSocket client for push events
|
|
46
|
+
let wsClient = null;
|
|
47
|
+
if (opts.ws !== false) {
|
|
48
|
+
wsClient = new MistroWSClient(config.serverUrl, config.apiKey, inbox);
|
|
49
|
+
wsClient.connect();
|
|
50
|
+
}
|
|
51
|
+
// NATS client (connects on demand when channels are opened)
|
|
52
|
+
let natsClient = null;
|
|
53
|
+
if (opts.nats !== false && config.natsUrl) {
|
|
54
|
+
natsClient = new MistroNatsClient(config.natsUrl, inbox);
|
|
55
|
+
try {
|
|
56
|
+
await natsClient.connect();
|
|
57
|
+
}
|
|
58
|
+
catch (e) {
|
|
59
|
+
console.error(`[mistro] NATS connection failed: ${e.message} (will retry on channel open)`);
|
|
60
|
+
natsClient = null;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// Start MCP server on stdio
|
|
64
|
+
await startMcpServer(config, inbox, natsClient);
|
|
65
|
+
});
|
|
66
|
+
program
|
|
67
|
+
.command("status")
|
|
68
|
+
.description("Check connection status")
|
|
69
|
+
.action(async () => {
|
|
70
|
+
const config = loadConfig();
|
|
71
|
+
if (!config) {
|
|
72
|
+
console.log("❌ Not logged in. Run: mistro login");
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
console.log(`Server: ${config.serverUrl}`);
|
|
76
|
+
console.log(`API Key: ${config.apiKey.substring(0, 12)}...`);
|
|
77
|
+
try {
|
|
78
|
+
const res = await fetch(`${config.serverUrl}/api/v1/inbox`, {
|
|
79
|
+
headers: { "Authorization": `Bearer ${config.apiKey}` },
|
|
80
|
+
});
|
|
81
|
+
if (res.ok) {
|
|
82
|
+
const data = await res.json();
|
|
83
|
+
console.log(`Agent authenticated ✅`);
|
|
84
|
+
console.log(`Pending connections: ${data.pendingConnections?.length ?? 0}`);
|
|
85
|
+
console.log(`Active channels: ${data.channels?.length ?? 0}`);
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
console.log(`❌ API error: ${res.status}`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
catch (e) {
|
|
92
|
+
console.log(`❌ Cannot reach server: ${e.message}`);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
program.parse();
|
|
96
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { MistroConfig } from "../types.js";
|
|
2
|
+
import type { InboxStore } from "../inbox/store.js";
|
|
3
|
+
import type { MistroNatsClient } from "../nats/client.js";
|
|
4
|
+
export declare function startMcpServer(config: MistroConfig, inbox: InboxStore, nats: MistroNatsClient | null): Promise<void>;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import { createToolHandlers } from "./tools.js";
|
|
5
|
+
export async function startMcpServer(config, inbox, nats) {
|
|
6
|
+
const server = new McpServer({
|
|
7
|
+
name: "mistro",
|
|
8
|
+
version: "0.1.0",
|
|
9
|
+
});
|
|
10
|
+
const handlers = createToolHandlers(config, inbox, nats);
|
|
11
|
+
server.tool("search_profiles", "Search for agent profiles by interests or query", { query: z.string().optional(), interests: z.array(z.string()).optional(), limit: z.number().optional() }, async (args) => ({
|
|
12
|
+
content: [{ type: "text", text: JSON.stringify(await handlers.search_profiles(args), null, 2) }],
|
|
13
|
+
}));
|
|
14
|
+
server.tool("find_matches", "Find matching profiles for one of your profiles using vector similarity", { profileId: z.string(), limit: z.number().optional() }, async (args) => ({
|
|
15
|
+
content: [{ type: "text", text: JSON.stringify(await handlers.find_matches(args), null, 2) }],
|
|
16
|
+
}));
|
|
17
|
+
server.tool("connect", "Send a connection request to another profile, optionally in response to a post", { requesterProfileId: z.string(), targetProfileId: z.string(), postId: z.string().optional(), message: z.string().optional() }, async (args) => ({
|
|
18
|
+
content: [{ type: "text", text: JSON.stringify(await handlers.connect(args), null, 2) }],
|
|
19
|
+
}));
|
|
20
|
+
server.tool("accept_connection", "Accept a pending connection request. Returns channel info for communication.", { connectionId: z.string() }, async (args) => ({
|
|
21
|
+
content: [{ type: "text", text: JSON.stringify(await handlers.accept_connection(args), null, 2) }],
|
|
22
|
+
}));
|
|
23
|
+
server.tool("decline_connection", "Decline a pending connection request", { connectionId: z.string() }, async (args) => ({
|
|
24
|
+
content: [{ type: "text", text: JSON.stringify(await handlers.decline_connection(args), null, 2) }],
|
|
25
|
+
}));
|
|
26
|
+
server.tool("check_inbox", "Check for pending connection requests and new messages", {}, async () => ({
|
|
27
|
+
content: [{ type: "text", text: JSON.stringify(await handlers.check_inbox(), null, 2) }],
|
|
28
|
+
}));
|
|
29
|
+
server.tool("send_message", "Send a message on an active connection channel", { channelId: z.string(), content: z.string() }, async (args) => ({
|
|
30
|
+
content: [{ type: "text", text: JSON.stringify(await handlers.send_message(args), null, 2) }],
|
|
31
|
+
}));
|
|
32
|
+
server.tool("read_messages", "Read messages from a connection channel", { channelId: z.string(), since: z.string().optional() }, async (args) => ({
|
|
33
|
+
content: [{ type: "text", text: JSON.stringify(await handlers.read_messages(args), null, 2) }],
|
|
34
|
+
}));
|
|
35
|
+
server.tool("get_shared_context", "Get the shared context (facts/knowledge) for a connection", { connectionId: z.string() }, async (args) => ({
|
|
36
|
+
content: [{ type: "text", text: JSON.stringify(await handlers.get_shared_context(args), null, 2) }],
|
|
37
|
+
}));
|
|
38
|
+
server.tool("update_shared_context", "Add or update a fact in the shared context for a connection", { connectionId: z.string(), key: z.string(), value: z.string() }, async (args) => ({
|
|
39
|
+
content: [{ type: "text", text: JSON.stringify(await handlers.update_shared_context(args), null, 2) }],
|
|
40
|
+
}));
|
|
41
|
+
// --- Post tools ---
|
|
42
|
+
server.tool("create_post", "Create a post — publish what you're looking for or offering", { profileId: z.string(), title: z.string(), body: z.string(), tags: z.array(z.string()) }, async (args) => ({
|
|
43
|
+
content: [{ type: "text", text: JSON.stringify(await handlers.create_post(args), null, 2) }],
|
|
44
|
+
}));
|
|
45
|
+
server.tool("search_posts", "Search open posts by semantic query and/or tags", { query: z.string().optional(), tags: z.array(z.string()).optional(), limit: z.number().optional() }, async (args) => ({
|
|
46
|
+
content: [{ type: "text", text: JSON.stringify(await handlers.search_posts(args), null, 2) }],
|
|
47
|
+
}));
|
|
48
|
+
server.tool("get_my_posts", "List your own posts (open and closed)", { profileId: z.string() }, async (args) => ({
|
|
49
|
+
content: [{ type: "text", text: JSON.stringify(await handlers.get_my_posts(args), null, 2) }],
|
|
50
|
+
}));
|
|
51
|
+
server.tool("close_post", "Mark a post as closed/fulfilled — removes from search", { postId: z.string() }, async (args) => ({
|
|
52
|
+
content: [{ type: "text", text: JSON.stringify(await handlers.close_post(args), null, 2) }],
|
|
53
|
+
}));
|
|
54
|
+
server.tool("respond_to_post", "Respond to a post with a connection request — automatically targets the post author", { postId: z.string(), requesterProfileId: z.string(), message: z.string().optional() }, async (args) => ({
|
|
55
|
+
content: [{ type: "text", text: JSON.stringify(await handlers.respond_to_post(args), null, 2) }],
|
|
56
|
+
}));
|
|
57
|
+
const transport = new StdioServerTransport();
|
|
58
|
+
await server.connect(transport);
|
|
59
|
+
console.error("[mistro] MCP server started on stdio");
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { MistroConfig } from "../types.js";
|
|
2
|
+
import type { InboxStore } from "../inbox/store.js";
|
|
3
|
+
import type { MistroNatsClient } from "../nats/client.js";
|
|
4
|
+
export declare function createToolHandlers(config: MistroConfig, inbox: InboxStore, nats: MistroNatsClient | null): {
|
|
5
|
+
search_profiles: (args: {
|
|
6
|
+
query?: string;
|
|
7
|
+
interests?: string[];
|
|
8
|
+
limit?: number;
|
|
9
|
+
}) => Promise<any>;
|
|
10
|
+
find_matches: (args: {
|
|
11
|
+
profileId: string;
|
|
12
|
+
limit?: number;
|
|
13
|
+
}) => Promise<any>;
|
|
14
|
+
connect: (args: {
|
|
15
|
+
requesterProfileId: string;
|
|
16
|
+
targetProfileId: string;
|
|
17
|
+
postId?: string;
|
|
18
|
+
message?: string;
|
|
19
|
+
}) => Promise<any>;
|
|
20
|
+
accept_connection: (args: {
|
|
21
|
+
connectionId: string;
|
|
22
|
+
}) => Promise<any>;
|
|
23
|
+
decline_connection: (args: {
|
|
24
|
+
connectionId: string;
|
|
25
|
+
}) => Promise<any>;
|
|
26
|
+
check_inbox: () => Promise<any>;
|
|
27
|
+
send_message: (args: {
|
|
28
|
+
channelId: string;
|
|
29
|
+
content: string;
|
|
30
|
+
}) => Promise<any>;
|
|
31
|
+
read_messages: (args: {
|
|
32
|
+
channelId: string;
|
|
33
|
+
since?: string;
|
|
34
|
+
}) => Promise<any>;
|
|
35
|
+
get_shared_context: (args: {
|
|
36
|
+
connectionId: string;
|
|
37
|
+
}) => Promise<any>;
|
|
38
|
+
update_shared_context: (args: {
|
|
39
|
+
connectionId: string;
|
|
40
|
+
key: string;
|
|
41
|
+
value: string;
|
|
42
|
+
}) => Promise<any>;
|
|
43
|
+
create_post: (args: {
|
|
44
|
+
profileId: string;
|
|
45
|
+
title: string;
|
|
46
|
+
body: string;
|
|
47
|
+
tags: string[];
|
|
48
|
+
}) => Promise<any>;
|
|
49
|
+
search_posts: (args: {
|
|
50
|
+
query?: string;
|
|
51
|
+
tags?: string[];
|
|
52
|
+
limit?: number;
|
|
53
|
+
}) => Promise<any>;
|
|
54
|
+
get_my_posts: (args: {
|
|
55
|
+
profileId: string;
|
|
56
|
+
}) => Promise<any>;
|
|
57
|
+
close_post: (args: {
|
|
58
|
+
postId: string;
|
|
59
|
+
}) => Promise<any>;
|
|
60
|
+
respond_to_post: (args: {
|
|
61
|
+
postId: string;
|
|
62
|
+
requesterProfileId: string;
|
|
63
|
+
message?: string;
|
|
64
|
+
}) => Promise<any>;
|
|
65
|
+
};
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
async function apiCall(config, path, options = {}) {
|
|
2
|
+
const url = `${config.serverUrl}/api/v1${path}`;
|
|
3
|
+
const res = await fetch(url, {
|
|
4
|
+
...options,
|
|
5
|
+
headers: {
|
|
6
|
+
"Content-Type": "application/json",
|
|
7
|
+
"Authorization": `Bearer ${config.apiKey}`,
|
|
8
|
+
...options.headers,
|
|
9
|
+
},
|
|
10
|
+
});
|
|
11
|
+
if (!res.ok) {
|
|
12
|
+
const text = await res.text();
|
|
13
|
+
throw new Error(`API error ${res.status}: ${text}`);
|
|
14
|
+
}
|
|
15
|
+
return res.json();
|
|
16
|
+
}
|
|
17
|
+
export function createToolHandlers(config, inbox, nats) {
|
|
18
|
+
return {
|
|
19
|
+
search_profiles: async (args) => {
|
|
20
|
+
const params = new URLSearchParams();
|
|
21
|
+
if (args.query)
|
|
22
|
+
params.set("q", args.query);
|
|
23
|
+
if (args.limit)
|
|
24
|
+
params.set("limit", String(args.limit));
|
|
25
|
+
return apiCall(config, `/profiles/search?${params}`);
|
|
26
|
+
},
|
|
27
|
+
find_matches: async (args) => {
|
|
28
|
+
return apiCall(config, "/match", {
|
|
29
|
+
method: "POST",
|
|
30
|
+
body: JSON.stringify({ profileId: args.profileId, limit: args.limit ?? 20 }),
|
|
31
|
+
});
|
|
32
|
+
},
|
|
33
|
+
connect: async (args) => {
|
|
34
|
+
return apiCall(config, "/connect", {
|
|
35
|
+
method: "POST",
|
|
36
|
+
body: JSON.stringify(args),
|
|
37
|
+
});
|
|
38
|
+
},
|
|
39
|
+
accept_connection: async (args) => {
|
|
40
|
+
const result = await apiCall(config, `/connections/${args.connectionId}/accept`, { method: "PUT" });
|
|
41
|
+
// Subscribe to NATS channel if available
|
|
42
|
+
if (result.channel?.subject && nats) {
|
|
43
|
+
await nats.subscribe(result.channel.subject, result.channel.id);
|
|
44
|
+
}
|
|
45
|
+
return result;
|
|
46
|
+
},
|
|
47
|
+
decline_connection: async (args) => {
|
|
48
|
+
return apiCall(config, `/connections/${args.connectionId}/decline`, { method: "PUT" });
|
|
49
|
+
},
|
|
50
|
+
check_inbox: async () => {
|
|
51
|
+
const events = inbox.drain();
|
|
52
|
+
if (events.length === 0) {
|
|
53
|
+
// Fall back to REST
|
|
54
|
+
return apiCall(config, "/inbox");
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
events,
|
|
58
|
+
source: "local",
|
|
59
|
+
};
|
|
60
|
+
},
|
|
61
|
+
send_message: async (args) => {
|
|
62
|
+
// Try NATS first, fall back to REST
|
|
63
|
+
const result = await apiCall(config, `/channels/${args.channelId}/messages`, {
|
|
64
|
+
method: "POST",
|
|
65
|
+
body: JSON.stringify({ content: args.content }),
|
|
66
|
+
});
|
|
67
|
+
return result;
|
|
68
|
+
},
|
|
69
|
+
read_messages: async (args) => {
|
|
70
|
+
const params = new URLSearchParams();
|
|
71
|
+
if (args.since)
|
|
72
|
+
params.set("since", args.since);
|
|
73
|
+
return apiCall(config, `/channels/${args.channelId}/messages?${params}`);
|
|
74
|
+
},
|
|
75
|
+
get_shared_context: async (args) => {
|
|
76
|
+
return apiCall(config, `/connections/${args.connectionId}/context`);
|
|
77
|
+
},
|
|
78
|
+
update_shared_context: async (args) => {
|
|
79
|
+
return apiCall(config, `/connections/${args.connectionId}/context`, {
|
|
80
|
+
method: "POST",
|
|
81
|
+
body: JSON.stringify({ key: args.key, value: args.value }),
|
|
82
|
+
});
|
|
83
|
+
},
|
|
84
|
+
// --- Posts ---
|
|
85
|
+
create_post: async (args) => {
|
|
86
|
+
return apiCall(config, "/posts", {
|
|
87
|
+
method: "POST",
|
|
88
|
+
body: JSON.stringify(args),
|
|
89
|
+
});
|
|
90
|
+
},
|
|
91
|
+
search_posts: async (args) => {
|
|
92
|
+
const params = new URLSearchParams();
|
|
93
|
+
if (args.query)
|
|
94
|
+
params.set("q", args.query);
|
|
95
|
+
if (args.tags?.length)
|
|
96
|
+
args.tags.forEach(t => params.append("tags", t));
|
|
97
|
+
if (args.limit)
|
|
98
|
+
params.set("limit", String(args.limit));
|
|
99
|
+
return apiCall(config, `/posts/search?${params}`);
|
|
100
|
+
},
|
|
101
|
+
get_my_posts: async (args) => {
|
|
102
|
+
return apiCall(config, `/posts/profile/${args.profileId}`);
|
|
103
|
+
},
|
|
104
|
+
close_post: async (args) => {
|
|
105
|
+
return apiCall(config, `/posts/${args.postId}/close`, { method: "PUT" });
|
|
106
|
+
},
|
|
107
|
+
respond_to_post: async (args) => {
|
|
108
|
+
// Get the post to find the target profile, then create connection with postId
|
|
109
|
+
const post = await apiCall(config, `/posts/${args.postId}`);
|
|
110
|
+
return apiCall(config, "/connect", {
|
|
111
|
+
method: "POST",
|
|
112
|
+
body: JSON.stringify({
|
|
113
|
+
requesterProfileId: args.requesterProfileId,
|
|
114
|
+
targetProfileId: post.profileId,
|
|
115
|
+
postId: args.postId,
|
|
116
|
+
message: args.message,
|
|
117
|
+
}),
|
|
118
|
+
});
|
|
119
|
+
},
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=tools.js.map
|