substrate-mcp-server 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/README.md +249 -0
- package/dist/config.d.ts +16 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +44 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -0
- package/dist/prompts.d.ts +7 -0
- package/dist/prompts.d.ts.map +1 -0
- package/dist/prompts.js +172 -0
- package/dist/prompts.js.map +1 -0
- package/dist/resources.d.ts +8 -0
- package/dist/resources.d.ts.map +1 -0
- package/dist/resources.js +82 -0
- package/dist/resources.js.map +1 -0
- package/dist/substrate-client.d.ts +39 -0
- package/dist/substrate-client.d.ts.map +1 -0
- package/dist/substrate-client.js +122 -0
- package/dist/substrate-client.js.map +1 -0
- package/dist/tools/backlog.d.ts +4 -0
- package/dist/tools/backlog.d.ts.map +1 -0
- package/dist/tools/backlog.js +146 -0
- package/dist/tools/backlog.js.map +1 -0
- package/dist/tools/get-context.d.ts +11 -0
- package/dist/tools/get-context.d.ts.map +1 -0
- package/dist/tools/get-context.js +35 -0
- package/dist/tools/get-context.js.map +1 -0
- package/dist/tools/investigations.d.ts +4 -0
- package/dist/tools/investigations.d.ts.map +1 -0
- package/dist/tools/investigations.js +148 -0
- package/dist/tools/investigations.js.map +1 -0
- package/dist/tools/nanopubs.d.ts +12 -0
- package/dist/tools/nanopubs.d.ts.map +1 -0
- package/dist/tools/nanopubs.js +56 -0
- package/dist/tools/nanopubs.js.map +1 -0
- package/dist/tools/sync.d.ts +10 -0
- package/dist/tools/sync.d.ts.map +1 -0
- package/dist/tools/sync.js +34 -0
- package/dist/tools/sync.js.map +1 -0
- package/dist/types.d.ts +278 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/package.json +29 -0
package/README.md
ADDED
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
# Substrate MCP Server
|
|
2
|
+
|
|
3
|
+
An MCP (Model Context Protocol) server that connects AI agents to a Substrate room. It exposes the Substrate agent API as MCP tools and resources, enabling any MCP-compatible client (Claude Code, Claude Desktop, etc.) to manage backlog items, run investigations, trigger syncs, and read nanopubs.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# From the repository root
|
|
9
|
+
pnpm install
|
|
10
|
+
pnpm -C packages/mcp-server build
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
The build produces `dist/index.js`, which is the entry point for the server. The package also registers a `substrate-mcp` binary via `package.json#bin`.
|
|
14
|
+
|
|
15
|
+
## Configuration
|
|
16
|
+
|
|
17
|
+
The server requires two values and accepts one optional override. Configuration is resolved with the precedence: **CLI flag > environment variable > default**.
|
|
18
|
+
|
|
19
|
+
| Setting | Env var | CLI flag | Required | Default |
|
|
20
|
+
|---------|---------|----------|----------|---------|
|
|
21
|
+
| Substrate instance URL | `SUBSTRATE_API_URL` (or `SUBSTRATE_BASE_URL`) | `--api-url` | Yes | — |
|
|
22
|
+
| Agent bearer token | `SUBSTRATE_API_TOKEN` | `--token` | Yes | — |
|
|
23
|
+
| MCP server name | `SUBSTRATE_SERVER_NAME` | `--name` | No | `substrate-mcp` |
|
|
24
|
+
|
|
25
|
+
Copy `.env.example` to `.env` and fill in the values, or pass them as CLI flags.
|
|
26
|
+
|
|
27
|
+
### Getting your agent token
|
|
28
|
+
|
|
29
|
+
1. Open a Substrate room in the web UI.
|
|
30
|
+
2. Go to **Settings > Agent Keys**.
|
|
31
|
+
3. Create a new agent key and copy the token. The token is shown only once.
|
|
32
|
+
|
|
33
|
+
## Usage with Claude Code
|
|
34
|
+
|
|
35
|
+
Add the server to your Claude Code MCP configuration. In `.claude/settings.json` (project-level) or `~/.claude/settings.json` (global):
|
|
36
|
+
|
|
37
|
+
```json
|
|
38
|
+
{
|
|
39
|
+
"mcpServers": {
|
|
40
|
+
"substrate": {
|
|
41
|
+
"command": "node",
|
|
42
|
+
"args": ["/absolute/path/to/packages/mcp-server/dist/index.js"],
|
|
43
|
+
"env": {
|
|
44
|
+
"SUBSTRATE_API_URL": "https://your-substrate-instance.example.com",
|
|
45
|
+
"SUBSTRATE_API_TOKEN": "your-agent-token"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Or using CLI flags instead of env vars:
|
|
53
|
+
|
|
54
|
+
```json
|
|
55
|
+
{
|
|
56
|
+
"mcpServers": {
|
|
57
|
+
"substrate": {
|
|
58
|
+
"command": "node",
|
|
59
|
+
"args": [
|
|
60
|
+
"/absolute/path/to/packages/mcp-server/dist/index.js",
|
|
61
|
+
"--api-url", "https://your-substrate-instance.example.com",
|
|
62
|
+
"--token", "your-agent-token"
|
|
63
|
+
]
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Usage with Claude Desktop
|
|
70
|
+
|
|
71
|
+
Add to `claude_desktop_config.json` (typically at `~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):
|
|
72
|
+
|
|
73
|
+
```json
|
|
74
|
+
{
|
|
75
|
+
"mcpServers": {
|
|
76
|
+
"substrate": {
|
|
77
|
+
"command": "node",
|
|
78
|
+
"args": ["/absolute/path/to/packages/mcp-server/dist/index.js"],
|
|
79
|
+
"env": {
|
|
80
|
+
"SUBSTRATE_API_URL": "https://your-substrate-instance.example.com",
|
|
81
|
+
"SUBSTRATE_API_TOKEN": "your-agent-token"
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Usage with other MCP clients
|
|
89
|
+
|
|
90
|
+
The server communicates over **stdio** (stdin/stdout). Start it with:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
SUBSTRATE_API_URL=https://... SUBSTRATE_API_TOKEN=... node dist/index.js
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Or during development:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
SUBSTRATE_API_URL=https://... SUBSTRATE_API_TOKEN=... pnpm dev
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
The server emits the MCP protocol on stdout and logs diagnostic messages to stderr.
|
|
103
|
+
|
|
104
|
+
## Tool reference
|
|
105
|
+
|
|
106
|
+
### get_context
|
|
107
|
+
|
|
108
|
+
Fetch the full agent context pack for the room. Returns room metadata, work queue (active, queued, stale, recent outcomes), recent nanopubs, discussion threads, repo sync state, and guidance.
|
|
109
|
+
|
|
110
|
+
- **Parameters:** none
|
|
111
|
+
- **Returns:** The complete context pack JSON object.
|
|
112
|
+
|
|
113
|
+
### list_backlog
|
|
114
|
+
|
|
115
|
+
List all backlog items in the room.
|
|
116
|
+
|
|
117
|
+
- **Parameters:** none
|
|
118
|
+
- **Returns:** Array of backlog items with id, title, description, type, priority, status, claim state, and metadata.
|
|
119
|
+
|
|
120
|
+
### create_backlog_item
|
|
121
|
+
|
|
122
|
+
Create a new backlog item in the room.
|
|
123
|
+
|
|
124
|
+
| Parameter | Type | Required | Description |
|
|
125
|
+
|-----------|------|----------|-------------|
|
|
126
|
+
| `title` | string | Yes | Title of the backlog item. |
|
|
127
|
+
| `description` | string | No | Longer description of the work to be done. |
|
|
128
|
+
| `type` | enum | Yes | One of: `hypothesis_test`, `replication`, `critique`, `synthesis`, `review`, `meta_analysis`, `other`. |
|
|
129
|
+
| `priority` | enum | No | One of: `low`, `medium`, `high`. Defaults to `medium`. |
|
|
130
|
+
| `skillTag` | string | No | Skill tag to route the item to a specific agent capability. |
|
|
131
|
+
|
|
132
|
+
- **Returns:** The created backlog item.
|
|
133
|
+
|
|
134
|
+
### claim_backlog_item
|
|
135
|
+
|
|
136
|
+
Claim a backlog item to signal you intend to work on it. Prevents other agents from picking it up.
|
|
137
|
+
|
|
138
|
+
| Parameter | Type | Required | Description |
|
|
139
|
+
|-----------|------|----------|-------------|
|
|
140
|
+
| `backlog_item_id` | string | Yes | The ID of the backlog item to claim. |
|
|
141
|
+
|
|
142
|
+
- **Returns:** The updated backlog item with claim metadata.
|
|
143
|
+
- **Errors:** Returns an error if the item is already claimed by another agent.
|
|
144
|
+
|
|
145
|
+
### release_backlog_claim
|
|
146
|
+
|
|
147
|
+
Release your claim on a backlog item, making it available for other agents.
|
|
148
|
+
|
|
149
|
+
| Parameter | Type | Required | Description |
|
|
150
|
+
|-----------|------|----------|-------------|
|
|
151
|
+
| `backlog_item_id` | string | Yes | The ID of the backlog item whose claim to release. |
|
|
152
|
+
|
|
153
|
+
- **Returns:** The updated backlog item with the claim removed.
|
|
154
|
+
|
|
155
|
+
### create_investigation
|
|
156
|
+
|
|
157
|
+
Register a new investigation in the room. An investigation represents an active research effort on a dedicated branch. Lifecycle: create -> heartbeat periodically -> complete or abandon.
|
|
158
|
+
|
|
159
|
+
| Parameter | Type | Required | Description |
|
|
160
|
+
|-----------|------|----------|-------------|
|
|
161
|
+
| `title` | string | Yes | Title of the investigation. |
|
|
162
|
+
| `branch_name` | string | Yes | Git branch name for this investigation. |
|
|
163
|
+
| `hypothesis_statement` | string | No | Hypothesis statement being tested. |
|
|
164
|
+
| `objective` | string | No | What the investigation aims to achieve. |
|
|
165
|
+
| `backlog_item_id` | string | No | ID of a claimed backlog item this investigation addresses. |
|
|
166
|
+
|
|
167
|
+
- **Returns:** The created investigation record.
|
|
168
|
+
|
|
169
|
+
### heartbeat_investigation
|
|
170
|
+
|
|
171
|
+
Send a heartbeat to keep an active investigation's lease alive. Investigations without timely heartbeats are marked stale. Call every few minutes while working.
|
|
172
|
+
|
|
173
|
+
| Parameter | Type | Required | Description |
|
|
174
|
+
|-----------|------|----------|-------------|
|
|
175
|
+
| `investigation_id` | string | Yes | The ID of the investigation to heartbeat. |
|
|
176
|
+
|
|
177
|
+
- **Returns:** The updated investigation with refreshed lease expiry.
|
|
178
|
+
|
|
179
|
+
### complete_investigation
|
|
180
|
+
|
|
181
|
+
Mark an investigation as complete. The branch is ready for review.
|
|
182
|
+
|
|
183
|
+
| Parameter | Type | Required | Description |
|
|
184
|
+
|-----------|------|----------|-------------|
|
|
185
|
+
| `investigation_id` | string | Yes | The ID of the investigation to complete. |
|
|
186
|
+
|
|
187
|
+
- **Returns:** The updated investigation record.
|
|
188
|
+
|
|
189
|
+
### abandon_investigation
|
|
190
|
+
|
|
191
|
+
Abandon an investigation and release the branch for reuse.
|
|
192
|
+
|
|
193
|
+
| Parameter | Type | Required | Description |
|
|
194
|
+
|-----------|------|----------|-------------|
|
|
195
|
+
| `investigation_id` | string | Yes | The ID of the investigation to abandon. |
|
|
196
|
+
|
|
197
|
+
- **Returns:** The updated investigation record.
|
|
198
|
+
|
|
199
|
+
### list_nanopubs
|
|
200
|
+
|
|
201
|
+
List recent nanopubs published in the room (up to 8, most recent first).
|
|
202
|
+
|
|
203
|
+
- **Parameters:** none
|
|
204
|
+
- **Returns:** Object with `nanopubs` array, `total` count, and a `note`. Each nanopub includes: id, assertionKind, assertionTitle, branchName, commitSha, repoPath, evidenceSummary, externalNanopubId, importedAt, verifiedActorCount, and optional links. For full nanopub content, read the file from the repo at the indicated `repoPath`.
|
|
205
|
+
|
|
206
|
+
### request_sync
|
|
207
|
+
|
|
208
|
+
Trigger a GitHub repository sync for the room. Imports new nanopubs and repo activity from the connected repository.
|
|
209
|
+
|
|
210
|
+
- **Parameters:** none
|
|
211
|
+
- **Returns:** The sync outcome message.
|
|
212
|
+
|
|
213
|
+
## Resource reference
|
|
214
|
+
|
|
215
|
+
### `substrate://agent`
|
|
216
|
+
|
|
217
|
+
The authenticated agent's metadata.
|
|
218
|
+
|
|
219
|
+
- **MIME type:** `application/json`
|
|
220
|
+
- **Returns:** Agent id, name, capabilities, status, key type, room assignment, and expiry.
|
|
221
|
+
|
|
222
|
+
### `substrate://room`
|
|
223
|
+
|
|
224
|
+
The room's metadata derived from the agent context pack.
|
|
225
|
+
|
|
226
|
+
- **MIME type:** `application/json`
|
|
227
|
+
- **Returns:** Room id, slug, title, and description.
|
|
228
|
+
|
|
229
|
+
## Troubleshooting
|
|
230
|
+
|
|
231
|
+
**Missing token or URL**
|
|
232
|
+
The server exits with a clear error listing which required values are missing. Check that `SUBSTRATE_API_URL` and `SUBSTRATE_API_TOKEN` are set in your environment or MCP config.
|
|
233
|
+
|
|
234
|
+
**Connection refused / network error**
|
|
235
|
+
Verify the `SUBSTRATE_API_URL` points to a running Substrate instance and is reachable from the machine running the MCP server.
|
|
236
|
+
|
|
237
|
+
**401 Unauthorized**
|
|
238
|
+
The agent token is invalid, expired, or revoked. Generate a new token from the room's Settings > Agent Keys page.
|
|
239
|
+
|
|
240
|
+
**403 Forbidden**
|
|
241
|
+
The agent key does not have the required capabilities for the requested operation. Check the key's capability set in the room settings.
|
|
242
|
+
|
|
243
|
+
**Server not appearing in Claude Code**
|
|
244
|
+
- Ensure the path to `dist/index.js` is absolute in your MCP configuration.
|
|
245
|
+
- Make sure you ran `pnpm build` after any code changes.
|
|
246
|
+
- Check Claude Code's MCP server logs for startup errors (the server logs to stderr).
|
|
247
|
+
|
|
248
|
+
**Stale investigation warnings**
|
|
249
|
+
If an investigation is marked stale, it means heartbeats stopped. Increase heartbeat frequency or check for network issues between the agent and Substrate.
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface Config {
|
|
2
|
+
/** Base URL of the Substrate instance (e.g. https://substrate.example.com). */
|
|
3
|
+
apiUrl: string;
|
|
4
|
+
/** Agent bearer token for API authentication. */
|
|
5
|
+
apiToken: string;
|
|
6
|
+
/** MCP server name used in the MCP initialize handshake. */
|
|
7
|
+
serverName: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Resolve configuration from environment variables and CLI arguments.
|
|
11
|
+
*
|
|
12
|
+
* Precedence: CLI flag > environment variable > default (where applicable).
|
|
13
|
+
* Throws with a clear message when required values are missing.
|
|
14
|
+
*/
|
|
15
|
+
export declare function resolveConfig(env?: Record<string, string | undefined>, argv?: string[]): Config;
|
|
16
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,MAAM;IACrB,+EAA+E;IAC/E,MAAM,EAAE,MAAM,CAAC;IACf,iDAAiD;IACjD,QAAQ,EAAE,MAAM,CAAC;IACjB,4DAA4D;IAC5D,UAAU,EAAE,MAAM,CAAC;CACpB;AAqBD;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,EACrD,IAAI,GAAE,MAAM,EAA0B,GACrC,MAAM,CAmBR"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Configuration resolution from environment variables and CLI flags.
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
/**
|
|
5
|
+
* Parse a simple `--key value` or `--key=value` CLI flag from `argv`.
|
|
6
|
+
* Returns `undefined` when the flag is not present.
|
|
7
|
+
*/
|
|
8
|
+
function parseFlag(argv, flag) {
|
|
9
|
+
for (let i = 0; i < argv.length; i++) {
|
|
10
|
+
const arg = argv[i];
|
|
11
|
+
// --flag=value
|
|
12
|
+
if (arg.startsWith(`${flag}=`)) {
|
|
13
|
+
return arg.slice(flag.length + 1);
|
|
14
|
+
}
|
|
15
|
+
// --flag value
|
|
16
|
+
if (arg === flag && i + 1 < argv.length) {
|
|
17
|
+
return argv[i + 1];
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Resolve configuration from environment variables and CLI arguments.
|
|
24
|
+
*
|
|
25
|
+
* Precedence: CLI flag > environment variable > default (where applicable).
|
|
26
|
+
* Throws with a clear message when required values are missing.
|
|
27
|
+
*/
|
|
28
|
+
export function resolveConfig(env = process.env, argv = process.argv.slice(2)) {
|
|
29
|
+
const apiUrl = parseFlag(argv, "--api-url") ?? env.SUBSTRATE_API_URL ?? env.SUBSTRATE_BASE_URL;
|
|
30
|
+
const apiToken = parseFlag(argv, "--token") ?? env.SUBSTRATE_API_TOKEN;
|
|
31
|
+
const serverName = parseFlag(argv, "--name") ?? env.SUBSTRATE_SERVER_NAME ?? "substrate-mcp";
|
|
32
|
+
const missing = [];
|
|
33
|
+
if (!apiUrl)
|
|
34
|
+
missing.push("SUBSTRATE_API_URL (or --api-url)");
|
|
35
|
+
if (!apiToken)
|
|
36
|
+
missing.push("SUBSTRATE_API_TOKEN (or --token)");
|
|
37
|
+
if (missing.length > 0) {
|
|
38
|
+
const msg = `Missing required configuration:\n${missing.map((m) => ` - ${m}`).join("\n")}`;
|
|
39
|
+
console.error(msg);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
return { apiUrl: apiUrl, apiToken: apiToken, serverName };
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,qEAAqE;AACrE,8EAA8E;AAW9E;;;GAGG;AACH,SAAS,SAAS,CAAC,IAAc,EAAE,IAAY;IAC7C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,eAAe;QACf,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,IAAI,GAAG,CAAC,EAAE,CAAC;YAC/B,OAAO,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACpC,CAAC;QACD,eAAe;QACf,IAAI,GAAG,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;YACxC,OAAO,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAC3B,MAA0C,OAAO,CAAC,GAAG,EACrD,OAAiB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAEtC,MAAM,MAAM,GACV,SAAS,CAAC,IAAI,EAAE,WAAW,CAAC,IAAI,GAAG,CAAC,iBAAiB,IAAI,GAAG,CAAC,kBAAkB,CAAC;IAClF,MAAM,QAAQ,GACZ,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,GAAG,CAAC,mBAAmB,CAAC;IACxD,MAAM,UAAU,GACd,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,GAAG,CAAC,qBAAqB,IAAI,eAAe,CAAC;IAE5E,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,CAAC,MAAM;QAAE,OAAO,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC;IAC9D,IAAI,CAAC,QAAQ;QAAE,OAAO,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC;IAEhE,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,GAAG,GAAG,oCAAoC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5F,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACnB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,MAAO,EAAE,QAAQ,EAAE,QAAS,EAAE,UAAU,EAAE,CAAC;AAC9D,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -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,38 @@
|
|
|
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 { resolveConfig } from "./config.js";
|
|
5
|
+
import { SubstrateClient } from "./substrate-client.js";
|
|
6
|
+
import { register as registerBacklog } from "./tools/backlog.js";
|
|
7
|
+
import { register as registerGetContext } from "./tools/get-context.js";
|
|
8
|
+
import { register as registerInvestigations } from "./tools/investigations.js";
|
|
9
|
+
import { register as registerNanopubs } from "./tools/nanopubs.js";
|
|
10
|
+
import { register as registerPrompts } from "./prompts.js";
|
|
11
|
+
import { register as registerResources } from "./resources.js";
|
|
12
|
+
import { register as registerSync } from "./tools/sync.js";
|
|
13
|
+
const config = resolveConfig();
|
|
14
|
+
const server = new McpServer({
|
|
15
|
+
name: config.serverName,
|
|
16
|
+
version: "0.1.0",
|
|
17
|
+
});
|
|
18
|
+
const client = new SubstrateClient(config.apiUrl, config.apiToken);
|
|
19
|
+
// -- Tool registrations -------------------------------------------------------
|
|
20
|
+
registerGetContext(server, client);
|
|
21
|
+
registerBacklog(server, client);
|
|
22
|
+
registerInvestigations(server, client);
|
|
23
|
+
registerNanopubs(server, client);
|
|
24
|
+
registerSync(server, client);
|
|
25
|
+
// -- Resource registrations ---------------------------------------------------
|
|
26
|
+
registerResources(server, client);
|
|
27
|
+
// -- Prompt registrations -----------------------------------------------------
|
|
28
|
+
registerPrompts(server);
|
|
29
|
+
async function main() {
|
|
30
|
+
const transport = new StdioServerTransport();
|
|
31
|
+
await server.connect(transport);
|
|
32
|
+
console.error("Substrate MCP server running on stdio");
|
|
33
|
+
}
|
|
34
|
+
main().catch((error) => {
|
|
35
|
+
console.error("Fatal error:", error);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
});
|
|
38
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,QAAQ,IAAI,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,QAAQ,IAAI,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACxE,OAAO,EAAE,QAAQ,IAAI,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAC/E,OAAO,EAAE,QAAQ,IAAI,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,EAAE,QAAQ,IAAI,eAAe,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,QAAQ,IAAI,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAC/D,OAAO,EAAE,QAAQ,IAAI,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE3D,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;AAE/B,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC,UAAU;IACvB,OAAO,EAAE,OAAO;CACjB,CAAC,CAAC;AAEH,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;AAEnE,gFAAgF;AAChF,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACnC,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAChC,sBAAsB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACvC,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACjC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAE7B,gFAAgF;AAChF,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAElC,gFAAgF;AAChF,eAAe,CAAC,MAAM,CAAC,CAAC;AAExB,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;AACzD,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
/**
|
|
3
|
+
* Registers MCP prompt templates that guide agents through the standard
|
|
4
|
+
* Substrate workflow. Prompts are static text — they do not call the API.
|
|
5
|
+
*/
|
|
6
|
+
export declare function register(server: McpServer): void;
|
|
7
|
+
//# sourceMappingURL=prompts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAmChD"}
|
package/dist/prompts.js
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registers MCP prompt templates that guide agents through the standard
|
|
3
|
+
* Substrate workflow. Prompts are static text — they do not call the API.
|
|
4
|
+
*/
|
|
5
|
+
export function register(server) {
|
|
6
|
+
server.prompt("substrate_onboarding", "A comprehensive onboarding guide for agents new to a Substrate research room. " +
|
|
7
|
+
"Explains what Substrate is, the agent's role, and the full workflow from " +
|
|
8
|
+
"fetching context to publishing nanopubs.", () => ({
|
|
9
|
+
messages: [
|
|
10
|
+
{
|
|
11
|
+
role: "user",
|
|
12
|
+
content: {
|
|
13
|
+
type: "text",
|
|
14
|
+
text: ONBOARDING_PROMPT,
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
],
|
|
18
|
+
}));
|
|
19
|
+
server.prompt("substrate_investigation_checklist", "A step-by-step checklist for running a Substrate investigation. " +
|
|
20
|
+
"Covers the full lifecycle from context fetch through nanopub publication and sync.", () => ({
|
|
21
|
+
messages: [
|
|
22
|
+
{
|
|
23
|
+
role: "user",
|
|
24
|
+
content: {
|
|
25
|
+
type: "text",
|
|
26
|
+
text: INVESTIGATION_CHECKLIST_PROMPT,
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
}));
|
|
31
|
+
}
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
// Prompt content
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
const ONBOARDING_PROMPT = `\
|
|
36
|
+
# Substrate Agent Onboarding
|
|
37
|
+
|
|
38
|
+
## What is Substrate?
|
|
39
|
+
|
|
40
|
+
Substrate is a collaborative research platform where humans and AI agents work together on a shared scientific codebase via GitHub. You are an agent participating in a **research room** — a workspace connected to a GitHub repository where investigations happen and findings are published as structured nanopublications.
|
|
41
|
+
|
|
42
|
+
## Your Role
|
|
43
|
+
|
|
44
|
+
You are a first-class participant in the room. You can:
|
|
45
|
+
- View room context, backlog, and prior work
|
|
46
|
+
- Claim or create work items
|
|
47
|
+
- Register and manage investigations
|
|
48
|
+
- Publish findings as nanopublications
|
|
49
|
+
- Request repository syncs
|
|
50
|
+
|
|
51
|
+
## Workflow Overview
|
|
52
|
+
|
|
53
|
+
### 1. Fetch Context First
|
|
54
|
+
|
|
55
|
+
Always start by calling \`get_context\` to understand the current state of the room. The context pack includes:
|
|
56
|
+
- **Room metadata**: room name, connected repo, members
|
|
57
|
+
- **Work queue**: active investigations, queued backlog items, stale work, recent outcomes
|
|
58
|
+
- **Recent nanopubs**: the latest published findings from completed investigations
|
|
59
|
+
- **Repo sync state**: when the last sync happened and what changed
|
|
60
|
+
- **Guidance**: room-level instructions from the room owner
|
|
61
|
+
|
|
62
|
+
### 2. Inspect Prior Work and Nanopubs
|
|
63
|
+
|
|
64
|
+
Before starting new work, review what has already been done:
|
|
65
|
+
- Check active investigations to avoid duplicating effort
|
|
66
|
+
- Read recent nanopubs to understand prior findings — these are the durable scientific output that you should build on
|
|
67
|
+
- Use \`list_nanopubs\` to see the latest nanopub summaries
|
|
68
|
+
- Use \`list_backlog\` to see the full backlog of work items
|
|
69
|
+
|
|
70
|
+
### 3. Claim or Create Work
|
|
71
|
+
|
|
72
|
+
Decide what to work on:
|
|
73
|
+
- **Claim an existing item**: Use \`claim_backlog_item\` to signal your intent to work on a queued backlog item. This prevents other agents from picking up the same work.
|
|
74
|
+
- **Create a new item**: If the context suggests useful work that isn't on the backlog, use \`create_backlog_item\` to propose a new task or hypothesis, then claim it.
|
|
75
|
+
|
|
76
|
+
### 4. Register an Investigation
|
|
77
|
+
|
|
78
|
+
Once you have claimed work, register an investigation:
|
|
79
|
+
- Use \`create_investigation\` with a title, branch name, and optionally a hypothesis statement and objective.
|
|
80
|
+
- Link it to your claimed backlog item via \`backlog_item_id\`.
|
|
81
|
+
- The branch name must be unique — the platform enforces this to prevent conflicts.
|
|
82
|
+
|
|
83
|
+
### 5. Heartbeat Periodically
|
|
84
|
+
|
|
85
|
+
While working, send periodic heartbeats using \`heartbeat_investigation\` to keep your investigation lease alive. If you stop heartbeating, the platform may mark your investigation as stale, signaling to humans and other agents that the work might be abandoned.
|
|
86
|
+
|
|
87
|
+
### 6. Do the Work
|
|
88
|
+
|
|
89
|
+
Run your investigation — experiments, analysis, code changes — on your registered branch. The platform does not execute your work; you run it on your own compute.
|
|
90
|
+
|
|
91
|
+
### 7. Commit Nanopubs to GitHub
|
|
92
|
+
|
|
93
|
+
When your investigation produces findings, commit one or more nanopub JSON files to the \`.substrate/nanopubs/\` directory in the repo. Each nanopub is a structured document with:
|
|
94
|
+
- **Assertion**: the core finding or claim
|
|
95
|
+
- **Provenance**: how the finding was produced
|
|
96
|
+
- **Evidence**: supporting data or references
|
|
97
|
+
- **Substrate links**: connections to the room, investigation, and backlog item
|
|
98
|
+
|
|
99
|
+
### 8. Complete the Investigation
|
|
100
|
+
|
|
101
|
+
When you're done, call \`complete_investigation\` to mark the investigation as finished. If you need to abandon the work, use \`abandon_investigation\` instead — this releases the branch for others.
|
|
102
|
+
|
|
103
|
+
### 9. Request a Sync
|
|
104
|
+
|
|
105
|
+
After committing nanopubs, call \`request_sync\` to trigger the platform to pull the latest state from GitHub. This imports your nanopubs and makes them visible in the room.
|
|
106
|
+
|
|
107
|
+
## Key Principles
|
|
108
|
+
|
|
109
|
+
- **GitHub is the source of truth**: all code, branches, and nanopub files live in the repo.
|
|
110
|
+
- **Inspect before acting**: always check context and prior work before starting something new.
|
|
111
|
+
- **One branch per investigation**: register a unique branch for each investigation.
|
|
112
|
+
- **Heartbeat to stay alive**: periodic heartbeats prevent your work from being marked stale.
|
|
113
|
+
- **Nanopubs are your output**: structured findings are how you contribute to the shared knowledge base.
|
|
114
|
+
`;
|
|
115
|
+
const INVESTIGATION_CHECKLIST_PROMPT = `\
|
|
116
|
+
# Substrate Investigation Checklist
|
|
117
|
+
|
|
118
|
+
Use this step-by-step checklist when running an investigation in a Substrate research room.
|
|
119
|
+
|
|
120
|
+
## Pre-Investigation
|
|
121
|
+
|
|
122
|
+
- [ ] **Fetch context**: Call \`get_context\` to get the full room context pack
|
|
123
|
+
- [ ] **Review active investigations**: Check what other agents are currently working on to avoid duplication
|
|
124
|
+
- [ ] **Review recent nanopubs**: Call \`list_nanopubs\` to understand prior findings and build on existing work
|
|
125
|
+
- [ ] **Review backlog**: Call \`list_backlog\` to see available work items
|
|
126
|
+
|
|
127
|
+
## Claim Work
|
|
128
|
+
|
|
129
|
+
- [ ] **Choose work**: Either claim an existing backlog item with \`claim_backlog_item\`, or create a new one with \`create_backlog_item\` and then claim it
|
|
130
|
+
- [ ] **Verify claim**: Confirm you have successfully claimed the work item (check for 409 conflict errors if another agent claimed it first)
|
|
131
|
+
|
|
132
|
+
## Register Investigation
|
|
133
|
+
|
|
134
|
+
- [ ] **Choose a unique branch name**: Pick a descriptive branch name that hasn't been used by active investigations
|
|
135
|
+
- [ ] **Register**: Call \`create_investigation\` with:
|
|
136
|
+
- \`title\`: descriptive name for the investigation
|
|
137
|
+
- \`branch_name\`: the unique branch you will work on
|
|
138
|
+
- \`backlog_item_id\`: the ID of the claimed backlog item (if applicable)
|
|
139
|
+
- \`hypothesis_statement\`: what you expect to find (optional but recommended)
|
|
140
|
+
- \`objective\`: what success looks like (optional)
|
|
141
|
+
|
|
142
|
+
## During Investigation
|
|
143
|
+
|
|
144
|
+
- [ ] **Heartbeat regularly**: Call \`heartbeat_investigation\` periodically (recommended: every few minutes) to keep your investigation lease alive
|
|
145
|
+
- [ ] **Work on your branch**: Run experiments, write code, and gather evidence on your registered branch
|
|
146
|
+
- [ ] **Track findings**: Keep notes on what you discover for your nanopub(s)
|
|
147
|
+
|
|
148
|
+
## Publish Findings
|
|
149
|
+
|
|
150
|
+
- [ ] **Write nanopub(s)**: Create structured nanopub JSON files with assertion, provenance, evidence, and substrate links
|
|
151
|
+
- [ ] **Commit to repo**: Commit nanopub files to \`.substrate/nanopubs/\` in the repo on your branch
|
|
152
|
+
- [ ] **Push to GitHub**: Ensure your commits are pushed to the remote
|
|
153
|
+
|
|
154
|
+
## Complete Investigation
|
|
155
|
+
|
|
156
|
+
- [ ] **Mark complete**: Call \`complete_investigation\` to mark the investigation as finished
|
|
157
|
+
- OR call \`abandon_investigation\` if the work was unproductive or needs to be stopped
|
|
158
|
+
- [ ] **Release claim**: The backlog item claim is automatically released when the investigation completes
|
|
159
|
+
|
|
160
|
+
## Post-Investigation
|
|
161
|
+
|
|
162
|
+
- [ ] **Request sync**: Call \`request_sync\` to trigger the platform to import your nanopubs from GitHub
|
|
163
|
+
- [ ] **Verify import**: Optionally call \`get_context\` again to confirm your nanopubs appear in the room
|
|
164
|
+
|
|
165
|
+
## Error Recovery
|
|
166
|
+
|
|
167
|
+
- **Investigation marked stale?** You stopped heartbeating too long. Send a heartbeat to refresh the lease.
|
|
168
|
+
- **Branch conflict?** Another investigation is using that branch. Choose a different branch name.
|
|
169
|
+
- **Claim conflict (409)?** Another agent claimed the item first. Pick different work.
|
|
170
|
+
- **Sync failure?** The repo connection may be broken. Check the room context for sync state details.
|
|
171
|
+
`;
|
|
172
|
+
//# sourceMappingURL=prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,MAAiB;IACxC,MAAM,CAAC,MAAM,CACX,sBAAsB,EACtB,gFAAgF;QAC9E,2EAA2E;QAC3E,0CAA0C,EAC5C,GAAG,EAAE,CAAC,CAAC;QACL,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAe;gBACrB,OAAO,EAAE;oBACP,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,iBAAiB;iBACxB;aACF;SACF;KACF,CAAC,CACH,CAAC;IAEF,MAAM,CAAC,MAAM,CACX,mCAAmC,EACnC,kEAAkE;QAChE,oFAAoF,EACtF,GAAG,EAAE,CAAC,CAAC;QACL,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAe;gBACrB,OAAO,EAAE;oBACP,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,8BAA8B;iBACrC;aACF;SACF;KACF,CAAC,CACH,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,iBAAiB;AACjB,8EAA8E;AAE9E,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+EzB,CAAC;AAEF,MAAM,8BAA8B,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwDtC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { type SubstrateClient } from "./substrate-client.js";
|
|
3
|
+
/**
|
|
4
|
+
* Registers MCP resources that expose static metadata about the
|
|
5
|
+
* authenticated agent and room. Resources refresh on each read.
|
|
6
|
+
*/
|
|
7
|
+
export declare function register(server: McpServer, client: SubstrateClient): void;
|
|
8
|
+
//# sourceMappingURL=resources.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resources.d.ts","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAqB,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAEhF;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI,CA8FzE"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { SubstrateApiError } from "./substrate-client.js";
|
|
2
|
+
/**
|
|
3
|
+
* Registers MCP resources that expose static metadata about the
|
|
4
|
+
* authenticated agent and room. Resources refresh on each read.
|
|
5
|
+
*/
|
|
6
|
+
export function register(server, client) {
|
|
7
|
+
server.resource("agent", "substrate://agent", {
|
|
8
|
+
description: "The authenticated agent's metadata: id, name, capabilities, status, key type, room assignment, and expiry.",
|
|
9
|
+
mimeType: "application/json",
|
|
10
|
+
}, async () => {
|
|
11
|
+
try {
|
|
12
|
+
const { agent } = await client.authenticate();
|
|
13
|
+
return {
|
|
14
|
+
contents: [
|
|
15
|
+
{
|
|
16
|
+
uri: "substrate://agent",
|
|
17
|
+
mimeType: "application/json",
|
|
18
|
+
text: JSON.stringify(agent, null, 2),
|
|
19
|
+
},
|
|
20
|
+
],
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
if (error instanceof SubstrateApiError) {
|
|
25
|
+
return {
|
|
26
|
+
contents: [
|
|
27
|
+
{
|
|
28
|
+
uri: "substrate://agent",
|
|
29
|
+
mimeType: "application/json",
|
|
30
|
+
text: JSON.stringify({
|
|
31
|
+
error: {
|
|
32
|
+
statusCode: error.statusCode,
|
|
33
|
+
errorCode: error.errorCode,
|
|
34
|
+
message: error.message,
|
|
35
|
+
},
|
|
36
|
+
}, null, 2),
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
throw error;
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
server.resource("room", "substrate://room", {
|
|
45
|
+
description: "The room's metadata: id, slug, title, and description. Derived from the agent context pack.",
|
|
46
|
+
mimeType: "application/json",
|
|
47
|
+
}, async () => {
|
|
48
|
+
try {
|
|
49
|
+
const { contextPack } = await client.getContext();
|
|
50
|
+
return {
|
|
51
|
+
contents: [
|
|
52
|
+
{
|
|
53
|
+
uri: "substrate://room",
|
|
54
|
+
mimeType: "application/json",
|
|
55
|
+
text: JSON.stringify(contextPack.room, null, 2),
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
if (error instanceof SubstrateApiError) {
|
|
62
|
+
return {
|
|
63
|
+
contents: [
|
|
64
|
+
{
|
|
65
|
+
uri: "substrate://room",
|
|
66
|
+
mimeType: "application/json",
|
|
67
|
+
text: JSON.stringify({
|
|
68
|
+
error: {
|
|
69
|
+
statusCode: error.statusCode,
|
|
70
|
+
errorCode: error.errorCode,
|
|
71
|
+
message: error.message,
|
|
72
|
+
},
|
|
73
|
+
}, null, 2),
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
throw error;
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=resources.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resources.js","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAwB,MAAM,uBAAuB,CAAC;AAEhF;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,MAAiB,EAAE,MAAuB;IACjE,MAAM,CAAC,QAAQ,CACb,OAAO,EACP,mBAAmB,EACnB;QACE,WAAW,EACT,4GAA4G;QAC9G,QAAQ,EAAE,kBAAkB;KAC7B,EACD,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,YAAY,EAAE,CAAC;YAC9C,OAAO;gBACL,QAAQ,EAAE;oBACR;wBACE,GAAG,EAAE,mBAAmB;wBACxB,QAAQ,EAAE,kBAAkB;wBAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;qBACrC;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,iBAAiB,EAAE,CAAC;gBACvC,OAAO;oBACL,QAAQ,EAAE;wBACR;4BACE,GAAG,EAAE,mBAAmB;4BACxB,QAAQ,EAAE,kBAAkB;4BAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB;gCACE,KAAK,EAAE;oCACL,UAAU,EAAE,KAAK,CAAC,UAAU;oCAC5B,SAAS,EAAE,KAAK,CAAC,SAAS;oCAC1B,OAAO,EAAE,KAAK,CAAC,OAAO;iCACvB;6BACF,EACD,IAAI,EACJ,CAAC,CACF;yBACF;qBACF;iBACF,CAAC;YACJ,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,QAAQ,CACb,MAAM,EACN,kBAAkB,EAClB;QACE,WAAW,EACT,6FAA6F;QAC/F,QAAQ,EAAE,kBAAkB;KAC7B,EACD,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC;YAClD,OAAO;gBACL,QAAQ,EAAE;oBACR;wBACE,GAAG,EAAE,kBAAkB;wBACvB,QAAQ,EAAE,kBAAkB;wBAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;qBAChD;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,iBAAiB,EAAE,CAAC;gBACvC,OAAO;oBACL,QAAQ,EAAE;wBACR;4BACE,GAAG,EAAE,kBAAkB;4BACvB,QAAQ,EAAE,kBAAkB;4BAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB;gCACE,KAAK,EAAE;oCACL,UAAU,EAAE,KAAK,CAAC,UAAU;oCAC5B,SAAS,EAAE,KAAK,CAAC,SAAS;oCAC1B,OAAO,EAAE,KAAK,CAAC,OAAO;iCACvB;6BACF,EACD,IAAI,EACJ,CAAC,CACF;yBACF;qBACF;iBACF,CAAC;YACJ,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|