@sigrun/ext-mcp 0.0.0-stage → 0.2.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/CHANGELOG.md +45 -0
- package/LICENSE +21 -0
- package/README.md +108 -2
- package/dist/bin.d.ts +6 -0
- package/dist/bin.js +9 -0
- package/dist/cli.d.ts +29 -0
- package/dist/cli.js +109 -0
- package/dist/client.d.ts +42 -0
- package/dist/client.js +685 -0
- package/dist/config.d.ts +113 -0
- package/dist/config.js +286 -0
- package/dist/extension.d.ts +51 -0
- package/dist/extension.js +212 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +13 -0
- package/dist/oauth.d.ts +60 -0
- package/dist/oauth.js +238 -0
- package/dist/section.d.ts +58 -0
- package/dist/section.js +92 -0
- package/dist/tokens.d.ts +55 -0
- package/dist/tokens.js +118 -0
- package/dist/types.d.ts +28 -0
- package/dist/types.js +2 -0
- package/package.json +58 -5
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.2.0] - 2026-10-22
|
|
11
|
+
### Added
|
|
12
|
+
- Remote MCP servers: a `servers` entry may be `{url, headers?, exposure?,
|
|
13
|
+
toolExposure?, timeout?}` instead of a stdio `{command, args}`. Streamable
|
|
14
|
+
HTTP is the transport (POST per frame, JSON or SSE reply,
|
|
15
|
+
`mcp-session-id` captured and echoed); a legacy HTTP+SSE server is adopted
|
|
16
|
+
automatically — whether it 404/405s the POST or (crawl4ai's shape) answers
|
|
17
|
+
it with an `endpoint` event — so no supergateway-style adapter is needed.
|
|
18
|
+
- `mcp.json` now resolves from the sigrun config dir
|
|
19
|
+
(`SIGRUN_CONFIG_DIR/mcp.json`) before the home fallback, matching every
|
|
20
|
+
other sigrun store.
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
- SSE parsing handles CRLF line endings (the spec allows them; live servers
|
|
24
|
+
emit them).
|
|
25
|
+
- Streamable replies stop at the id-matching frame — servers legitimately
|
|
26
|
+
hold SSE streams open past the reply.
|
|
27
|
+
|
|
28
|
+
## [0.1.0] - 2026-10-13
|
|
29
|
+
### Added
|
|
30
|
+
- Renamed to `@sigrun/ext-mcp` for the 0.1.0 release (repo stays
|
|
31
|
+
`sigrun-ai/sigrun-ext-mcp`): published package metadata
|
|
32
|
+
(`publishConfig` access/provenance), host modules moved to
|
|
33
|
+
`peerDependencies` mirrored in `devDependencies` at exact pins
|
|
34
|
+
(`typebox` now declared — it was an undeclared host import),
|
|
35
|
+
CHANGELOG.md joined the files whitelist, and a manifest hygiene check
|
|
36
|
+
wired into `npm test`.
|
|
37
|
+
- MCP client over stdio: server discovery, tool registration (`<server>/<tool>`
|
|
38
|
+
naming), OAuth (PKCE paste-the-URL flow) with a durable token store.
|
|
39
|
+
- The MCP exposure model on pi-durable 1.2.0: per-server
|
|
40
|
+
`exposure: codemode|deferred|direct|hidden` (default `codemode`),
|
|
41
|
+
per-tool `toolExposure` overrides (exact over patterns, first wins),
|
|
42
|
+
`enabled`, and per-request `timeout` with progress-notification reset.
|
|
43
|
+
- The `mcp_servers` prompt section: live-rendered, 4KB whole-line-truncated,
|
|
44
|
+
gated on the discovery tool being model-offered, with an honest
|
|
45
|
+
enable-notice line for unreachable servers.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Michael MacLeod
|
|
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
CHANGED
|
@@ -1,3 +1,109 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @sigrun/ext-mcp
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Register MCP server tools as pi-durable tools, named `<server>/<tool>`.
|
|
4
|
+
|
|
5
|
+
Config: the sigrun config dir's `mcp.json` (`SIGRUN_CONFIG_DIR/mcp.json`; a
|
|
6
|
+
bare user install falls back to `~/.config/sigrun/mcp.json`; the
|
|
7
|
+
`SIGRUN_MCP_CONFIG` env override points at any path). Each entry under
|
|
8
|
+
`"servers"` names an MCP server — stdio or remote:
|
|
9
|
+
|
|
10
|
+
```json
|
|
11
|
+
{
|
|
12
|
+
"servers": {
|
|
13
|
+
"github": {
|
|
14
|
+
"command": "npx",
|
|
15
|
+
"args": ["-y", "@modelcontextprotocol/server-github"],
|
|
16
|
+
"exposure": "codemode",
|
|
17
|
+
"timeout": 120
|
|
18
|
+
},
|
|
19
|
+
"search": {
|
|
20
|
+
"url": "https://mcp.example.test/mcp",
|
|
21
|
+
"headers": { "Authorization": "Bearer <token>" },
|
|
22
|
+
"exposure": "direct"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Server fields
|
|
29
|
+
|
|
30
|
+
- `command`, `args` (stdio) — how to spawn the server.
|
|
31
|
+
- `url` (remote) — the server endpoint (http/https). Streamable HTTP is the
|
|
32
|
+
transport; a legacy HTTP+SSE server (2024-11-05 shape — GET stream +
|
|
33
|
+
`endpoint` event + message POSTs) is adopted automatically, so no adapter
|
|
34
|
+
process is needed.
|
|
35
|
+
- `headers` (remote) — extra request headers (auth etc.), sent on every
|
|
36
|
+
request.
|
|
37
|
+
- `env` (stdio) — extra environment variables for the child process.
|
|
38
|
+
- `enabled` (default `true`) / `disabled` — skip the server entirely. Set one,
|
|
39
|
+
never both: a server that is simultaneously on and off is a config error and
|
|
40
|
+
fails loudly.
|
|
41
|
+
- `timeout` — per-request wire timeout in seconds (default `60`). A request
|
|
42
|
+
that gets no reply by its deadline rejects. A server that keeps sending
|
|
43
|
+
`notifications/progress` for a pending request never dies at the deadline
|
|
44
|
+
while it keeps reporting work — progress resets the deadline.
|
|
45
|
+
- `exposure` — how the server's tools register (see below). Default `"codemode"`.
|
|
46
|
+
- `toolExposure` — per-tool overrides of `exposure`: an object mapping tool
|
|
47
|
+
names (exact) or `*`-globs (e.g. `"get-*"`) to exposure words. An exact name
|
|
48
|
+
always wins; among matching patterns the FIRST one in config order wins.
|
|
49
|
+
- `oauth` (stdio) — the authorization-code (PKCE) flow block; see
|
|
50
|
+
`sigrun-ext-mcp oauth <server>` (the CLI mints and stores a token; the spawn
|
|
51
|
+
injects it).
|
|
52
|
+
|
|
53
|
+
## Exposure: how tools reach callers
|
|
54
|
+
|
|
55
|
+
On pi-durable 1.2.0 semantics, `"exposure"` decides who can call a server's
|
|
56
|
+
tools:
|
|
57
|
+
|
|
58
|
+
| exposure | registration | who can call |
|
|
59
|
+
| ----------- | ------------------------- | ------------------------------------- |
|
|
60
|
+
| `codemode` | `callers: ["tools"]` | scripts only (never model-offered) |
|
|
61
|
+
| `deferred` | `deferred: true` | the model, once `tool_search` loads it |
|
|
62
|
+
| `direct` | normal | the model (offered when in the set) |
|
|
63
|
+
| `hidden` | not registered | nobody (config entry kept) |
|
|
64
|
+
|
|
65
|
+
The `codemode-deferred` word is kept as an alias for `codemode` (pi compat).
|
|
66
|
+
|
|
67
|
+
### The default flip — a breaking change
|
|
68
|
+
|
|
69
|
+
**Before 1.2.0, an `mcp.json` server entry with no `exposure` field had its
|
|
70
|
+
tools offered to the model. Now the default is `"codemode"`:** a
|
|
71
|
+
default-exposure server's tools are callable by scripts (codemode), never
|
|
72
|
+
offered to the model directly. To restore the old behavior, set the server
|
|
73
|
+
(or the tool, via `toolExposure`) to `"exposure": "direct"`:
|
|
74
|
+
|
|
75
|
+
```json
|
|
76
|
+
{ "exposure": "direct" }
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
The `mcp_servers` system-prompt section lists codemode/deferred servers when
|
|
80
|
+
their discovery tool (`codemode`, `tool_search`) is offered in the request;
|
|
81
|
+
when such servers exist but their tools are unreachable, it appends one
|
|
82
|
+
notice line naming the count and the Settings → default tools fix.
|
|
83
|
+
|
|
84
|
+
## Tool naming: `<server>/<tool>` (decision)
|
|
85
|
+
|
|
86
|
+
Tools keep the existing `<server>/<tool>` shape rather than upstream pi's
|
|
87
|
+
`mcp__<server>__<tool>`:
|
|
88
|
+
|
|
89
|
+
- The upstream codemode section groups tools by `CodemodeNamespace.prefix`
|
|
90
|
+
(longest match wins), and the namespaces are **config-side** — the host
|
|
91
|
+
passes the groups, so any naming can namespace trivially: ours groups as
|
|
92
|
+
`prefix: "<server>/"` with no rename at all.
|
|
93
|
+
- The name-addressed surface makes per-tool replacement and `toolExposure`
|
|
94
|
+
patterns readable (`"github/*"`), and the existing wire name is already
|
|
95
|
+
deployed in configs and scripts.
|
|
96
|
+
|
|
97
|
+
No section-rendering compat requires the upstream spelling; the decision is
|
|
98
|
+
recorded here per the spec's open item.
|
|
99
|
+
|
|
100
|
+
## Replacement semantics
|
|
101
|
+
|
|
102
|
+
Replacement works by not installing ours and installing yours: the
|
|
103
|
+
name-addressed tool surface (`<server>/<tool>`) makes per-name replacement
|
|
104
|
+
trivial. Co-installing this package with another that registers the same
|
|
105
|
+
tool names shadows silently (pi-durable resolves cross-extension duplicates
|
|
106
|
+
last-selected-wins) — **do not co-install**. Sigrun's extension loader
|
|
107
|
+
(made the shadowing visible at boot: it `console.warn`s once per duplicate
|
|
108
|
+
tool name, naming the extensions and the last-wins resolution) but the
|
|
109
|
+
warning changes nothing: last-wins stands. Replace, don't co-install.
|
package/dist/bin.d.ts
ADDED
package/dist/bin.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The package bin entry (`sigrun-ext-mcp` → dist/bin.js): parse-and-run the
|
|
3
|
+
* CLI, mapping the result to the process exit code. The body lives in
|
|
4
|
+
* ./cli.ts so tests can exercise it without spawning a process.
|
|
5
|
+
*/
|
|
6
|
+
import { runCli } from "./cli.js";
|
|
7
|
+
void runCli(process.argv.slice(2)).then((code) => {
|
|
8
|
+
process.exitCode = code;
|
|
9
|
+
});
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `sigrun-ext-mcp` CLI bin (ruling 4): `sigrun-ext-mcp oauth <server>`
|
|
3
|
+
* runs the paste-the-URL OAuth flow for one configured server.
|
|
4
|
+
*
|
|
5
|
+
* argv surface (parsed minimally — no new deps):
|
|
6
|
+
* sigrun-ext-mcp oauth <server> [--paste]
|
|
7
|
+
*
|
|
8
|
+
* Default mode: the loopback listener runs AND stdin is read (paste
|
|
9
|
+
* fallback) — first arrival wins. `--paste` is accepted for hosts that want
|
|
10
|
+
* the semantics explicit; the flow is identical either way.
|
|
11
|
+
*
|
|
12
|
+
* Prints to stdout:
|
|
13
|
+
* - the authorize URL (open this in a browser)
|
|
14
|
+
* - the redirect_uri (what the AS will redirect to)
|
|
15
|
+
* - a paste prompt
|
|
16
|
+
* Exits 0 with the token stored, or 1 with a clear error (usage / config /
|
|
17
|
+
* flow / 5-minute timeout).
|
|
18
|
+
*/
|
|
19
|
+
/** Parse argv minimally: `oauth <server> [--paste]`. */
|
|
20
|
+
export declare function parseCliArgs(argv: readonly string[]): {
|
|
21
|
+
readonly command: "oauth";
|
|
22
|
+
readonly server: string;
|
|
23
|
+
readonly paste: boolean;
|
|
24
|
+
};
|
|
25
|
+
/** The CLI body (exported for tests); returns the process exit code. */
|
|
26
|
+
export declare function runCli(argv: readonly string[], io?: {
|
|
27
|
+
readonly stdout: NodeJS.WriteStream;
|
|
28
|
+
readonly stderr: NodeJS.WriteStream;
|
|
29
|
+
}): Promise<number>;
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `sigrun-ext-mcp` CLI bin (ruling 4): `sigrun-ext-mcp oauth <server>`
|
|
3
|
+
* runs the paste-the-URL OAuth flow for one configured server.
|
|
4
|
+
*
|
|
5
|
+
* argv surface (parsed minimally — no new deps):
|
|
6
|
+
* sigrun-ext-mcp oauth <server> [--paste]
|
|
7
|
+
*
|
|
8
|
+
* Default mode: the loopback listener runs AND stdin is read (paste
|
|
9
|
+
* fallback) — first arrival wins. `--paste` is accepted for hosts that want
|
|
10
|
+
* the semantics explicit; the flow is identical either way.
|
|
11
|
+
*
|
|
12
|
+
* Prints to stdout:
|
|
13
|
+
* - the authorize URL (open this in a browser)
|
|
14
|
+
* - the redirect_uri (what the AS will redirect to)
|
|
15
|
+
* - a paste prompt
|
|
16
|
+
* Exits 0 with the token stored, or 1 with a clear error (usage / config /
|
|
17
|
+
* flow / 5-minute timeout).
|
|
18
|
+
*/
|
|
19
|
+
import { createInterface } from "node:readline";
|
|
20
|
+
import { isStdioServer, loadMcpConfig, MCP_CONFIG_ENV, } from "./config.js";
|
|
21
|
+
import { startOauth } from "./oauth.js";
|
|
22
|
+
import { resolveMcpTokenPath } from "./tokens.js";
|
|
23
|
+
/** The flow timeout (matches startOauth's default; explicit so the user's
|
|
24
|
+
* error message is deterministic). */
|
|
25
|
+
const TIMEOUT_MS = 5 * 60_000;
|
|
26
|
+
/** Print the usage banner. */
|
|
27
|
+
function usage(out) {
|
|
28
|
+
out.write("usage: sigrun-ext-mcp oauth <server> [--paste]\n");
|
|
29
|
+
out.write(`reads the MCP config (env ${MCP_CONFIG_ENV} or ~/.config/sigrun/mcp.json);\n` +
|
|
30
|
+
`the named server needs an oauth block; the token is stored beside the\n` +
|
|
31
|
+
`config as mcp-tokens.json (0600)\n`);
|
|
32
|
+
}
|
|
33
|
+
/** Parse argv minimally: `oauth <server> [--paste]`. */
|
|
34
|
+
export function parseCliArgs(argv) {
|
|
35
|
+
const args = [...argv];
|
|
36
|
+
const head = args.shift();
|
|
37
|
+
if (head !== "oauth") {
|
|
38
|
+
throw new Error(`unknown command: ${String(head)}`);
|
|
39
|
+
}
|
|
40
|
+
const paste = args.includes("--paste");
|
|
41
|
+
const positional = args.filter((arg) => arg !== "--paste");
|
|
42
|
+
if (positional.length !== 1) {
|
|
43
|
+
throw new Error("expected exactly one server name");
|
|
44
|
+
}
|
|
45
|
+
return { command: "oauth", server: positional[0], paste };
|
|
46
|
+
}
|
|
47
|
+
/** Load the config, turning a malformed config into exit-1 (not a crash). */
|
|
48
|
+
function loadMcpConfigSafe(stderr) {
|
|
49
|
+
try {
|
|
50
|
+
return loadMcpConfig();
|
|
51
|
+
}
|
|
52
|
+
catch (cause) {
|
|
53
|
+
stderr.write(`error: ${cause instanceof Error ? cause.message : String(cause)}\n`);
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/** The CLI body (exported for tests); returns the process exit code. */
|
|
58
|
+
export async function runCli(argv, io = { stdout: process.stdout, stderr: process.stderr }) {
|
|
59
|
+
let parsed;
|
|
60
|
+
try {
|
|
61
|
+
parsed = parseCliArgs(argv);
|
|
62
|
+
}
|
|
63
|
+
catch (cause) {
|
|
64
|
+
usage(io.stderr);
|
|
65
|
+
io.stderr.write(`error: ${cause instanceof Error ? cause.message : String(cause)}\n`);
|
|
66
|
+
return 1;
|
|
67
|
+
}
|
|
68
|
+
const config = loadMcpConfigSafe(io.stderr);
|
|
69
|
+
const server = config.servers[parsed.server];
|
|
70
|
+
if (server === undefined) {
|
|
71
|
+
io.stderr.write(`error: no server named "${parsed.server}" in the MCP config\n`);
|
|
72
|
+
return 1;
|
|
73
|
+
}
|
|
74
|
+
if (!isStdioServer(server) || server.oauth === undefined) {
|
|
75
|
+
io.stderr.write(`error: server "${parsed.server}" has no oauth block in the MCP config\n`);
|
|
76
|
+
return 1;
|
|
77
|
+
}
|
|
78
|
+
const flow = await startOauth(parsed.server, server.oauth, {
|
|
79
|
+
timeoutMs: TIMEOUT_MS,
|
|
80
|
+
});
|
|
81
|
+
io.stdout.write(`Authorize URL:\n ${flow.authorizeUrl}\n`);
|
|
82
|
+
io.stdout.write(`Redirect URI:\n ${flow.redirectUri}\n`);
|
|
83
|
+
io.stdout.write("Open the Authorize URL in a browser and approve. If the redirect does\n" +
|
|
84
|
+
"not reach this machine, paste the FULL redirected URL here instead:\n");
|
|
85
|
+
// The paste fallback: every stdin line is fed to the flow; first arrival
|
|
86
|
+
// wins (the loopback listener or the paste settles the code). pasteUrl
|
|
87
|
+
// never throws (lines with no code are ignored), so the readline handler
|
|
88
|
+
// cannot crash the bin.
|
|
89
|
+
const lines = createInterface({ input: process.stdin });
|
|
90
|
+
lines.on("line", (line) => {
|
|
91
|
+
const trimmed = line.trim();
|
|
92
|
+
if (trimmed !== "")
|
|
93
|
+
flow.pasteUrl(trimmed);
|
|
94
|
+
});
|
|
95
|
+
try {
|
|
96
|
+
await flow.done;
|
|
97
|
+
lines.close();
|
|
98
|
+
io.stdout.write(`Token stored for "${parsed.server}" in:\n ${resolveMcpTokenPath()}\n`);
|
|
99
|
+
return 0;
|
|
100
|
+
}
|
|
101
|
+
catch (cause) {
|
|
102
|
+
lines.close();
|
|
103
|
+
flow.stop();
|
|
104
|
+
io.stderr.write(`error: ${cause instanceof Error ? cause.message : String(cause)}\n`);
|
|
105
|
+
return 1;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// This module is the CLI body only (pure exports; importable for tests).
|
|
109
|
+
// The bin entry lives in ./bin.ts — dist/bin.js is the package.json "bin".
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The MCP client: a transport-neutral JSON-RPC 2.0 engine plus two
|
|
3
|
+
* transports.
|
|
4
|
+
*
|
|
5
|
+
* stdio (the original transport): newline-delimited JSON-RPC over a spawned
|
|
6
|
+
* child's pipes. Remote (streamable HTTP): every request POSTs to the
|
|
7
|
+
* configured URL; the reply is a JSON body OR an SSE stream. A server that
|
|
8
|
+
* 404/405s the POST (the pre-2025-03-26 "HTTP+SSE" transport — still common,
|
|
9
|
+
* e.g. many self-hosted servers) falls back to the legacy shape: a GET
|
|
10
|
+
* stream for server→client frames and a discovered message endpoint for
|
|
11
|
+
* client→server POSTs.
|
|
12
|
+
*
|
|
13
|
+
* Lifecycle (both transports): `initialize` handshake (protocolVersion
|
|
14
|
+
* "2025-06-18", clientInfo, capabilities) → `notifications/initialized` →
|
|
15
|
+
* `tools/list` (discovery) → `tools/call` (execution). Requests correlate
|
|
16
|
+
* by id; the response frame's `id` must match a pending request (a
|
|
17
|
+
* notification is never a reply). A connect failure rejects `connect`,
|
|
18
|
+
* never affecting any other server (per-server isolation).
|
|
19
|
+
*
|
|
20
|
+
* Per-request timeout (codemode parity, spec slice 3): every request REJECTS
|
|
21
|
+
* at its deadline (default 60s; config `timeout` per server) instead of
|
|
22
|
+
* awaiting a hung server forever. A `notifications/progress` frame naming a
|
|
23
|
+
* pending request's id (sent as the request's `progressToken`) RESETS that
|
|
24
|
+
* request's deadline — a server that keeps reporting progress stays alive
|
|
25
|
+
* as long as it works. A timeout rejects the call but never kills the
|
|
26
|
+
* transport (per-server isolation: the next request gets a fresh chance).
|
|
27
|
+
*/
|
|
28
|
+
import type { McpServerConfig, McpToolDefinition, McpToolResult } from "./types.js";
|
|
29
|
+
/** The public client surface (what the extension consumes). */
|
|
30
|
+
export interface McpClient {
|
|
31
|
+
listTools(): Promise<McpToolDefinition[]>;
|
|
32
|
+
callTool(name: string, args: Record<string, unknown>, timeoutSeconds?: number): Promise<McpToolResult>;
|
|
33
|
+
/** Tear the connection down (idempotent). */
|
|
34
|
+
close(): void;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Spawn/connect one configured MCP server (stdio or remote by config
|
|
38
|
+
* shape). Throws on spawn/connect failure or a failed handshake —
|
|
39
|
+
* per-server isolation is the CALLER's policy (the extension connects all
|
|
40
|
+
* servers with `.catch` per server).
|
|
41
|
+
*/
|
|
42
|
+
export declare function connectMcpServer(name: string, config: McpServerConfig): Promise<McpClient>;
|