@outfitter/mcp 0.4.1 → 0.4.3
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 +39 -29
- package/dist/actions.d.ts +3 -3
- package/dist/actions.js +25 -4
- package/dist/core-tools.d.ts +3 -3
- package/dist/core-tools.js +140 -6
- package/dist/index.d.ts +7 -952
- package/dist/index.js +7 -959
- package/dist/logging.d.ts +1 -1
- package/dist/schema.d.ts +1 -1
- package/dist/schema.js +1 -1
- package/dist/server.d.ts +3 -3
- package/dist/server.js +2 -2
- package/dist/shared/@outfitter/{mcp-jk0ka9hw.d.ts → mcp-7kcw2814.d.ts} +4 -4
- package/dist/shared/@outfitter/{mcp-nmp5wf0w.js → mcp-b502y16n.js} +1 -1
- package/dist/shared/@outfitter/{mcp-a0cgfsnw.d.ts → mcp-d8vs6vry.d.ts} +1 -1
- package/dist/shared/@outfitter/{mcp-h2twz77x.d.ts → mcp-gqjg15f5.d.ts} +166 -196
- package/dist/shared/@outfitter/mcp-hw5wz4gb.js +1 -0
- package/dist/shared/@outfitter/{mcp-2vqyt1fj.d.ts → mcp-knq080yt.d.ts} +1 -1
- package/dist/shared/@outfitter/{mcp-dwd800vf.d.ts → mcp-s6afm4ff.d.ts} +14 -14
- package/dist/transport.d.ts +3 -3
- package/dist/transport.js +161 -5
- package/dist/types.d.ts +2 -2
- package/package.json +31 -30
- package/dist/shared/@outfitter/mcp-ktapzh9d.js +0 -28
- package/dist/shared/@outfitter/mcp-mzky3ck8.js +0 -165
- package/dist/shared/@outfitter/mcp-zv3ej45k.js +0 -143
- package/dist/shared/@outfitter/mcp-zy7b487d.js +0 -5
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { McpServer, McpServerOptions, PromptDefinition, ResourceDefinition, ResourceTemplateDefinition, ToolDefinition } from "./mcp-
|
|
1
|
+
import { McpServer, McpServerOptions, PromptDefinition, ResourceDefinition, ResourceTemplateDefinition, ToolDefinition } from "./mcp-gqjg15f5.js";
|
|
2
2
|
import { OutfitterError } from "@outfitter/contracts";
|
|
3
3
|
/**
|
|
4
4
|
* Create an MCP server instance.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ToolDefinition } from "./mcp-
|
|
1
|
+
import { ToolDefinition } from "./mcp-gqjg15f5.js";
|
|
2
2
|
import { HandlerContext, OutfitterError } from "@outfitter/contracts";
|
|
3
3
|
import { Result } from "@outfitter/contracts";
|
|
4
4
|
type DocsSection = "overview" | "tools" | "examples" | "schemas";
|
|
@@ -6,23 +6,23 @@ interface DocsToolInput {
|
|
|
6
6
|
section?: DocsSection | undefined;
|
|
7
7
|
}
|
|
8
8
|
interface DocsToolEntry {
|
|
9
|
-
name: string;
|
|
10
|
-
summary?: string;
|
|
11
9
|
examples?: Array<{
|
|
12
10
|
input: Record<string, unknown>;
|
|
13
11
|
description?: string;
|
|
14
12
|
}>;
|
|
13
|
+
name: string;
|
|
14
|
+
summary?: string;
|
|
15
15
|
}
|
|
16
16
|
interface DocsToolResponse {
|
|
17
|
-
overview?: string;
|
|
18
|
-
tools?: DocsToolEntry[];
|
|
19
17
|
examples?: Array<{
|
|
20
18
|
name?: string;
|
|
21
19
|
description?: string;
|
|
22
20
|
input?: Record<string, unknown>;
|
|
23
21
|
output?: unknown;
|
|
24
22
|
}>;
|
|
23
|
+
overview?: string;
|
|
25
24
|
schemas?: Record<string, unknown>;
|
|
25
|
+
tools?: DocsToolEntry[];
|
|
26
26
|
}
|
|
27
27
|
interface DocsToolOptions {
|
|
28
28
|
/** Optional override for the docs tool description. */
|
|
@@ -41,10 +41,10 @@ interface ConfigToolInput {
|
|
|
41
41
|
}
|
|
42
42
|
interface ConfigToolResponse {
|
|
43
43
|
action: ConfigAction;
|
|
44
|
+
config?: Record<string, unknown>;
|
|
45
|
+
found?: boolean;
|
|
44
46
|
key?: string;
|
|
45
47
|
value?: unknown;
|
|
46
|
-
found?: boolean;
|
|
47
|
-
config?: Record<string, unknown>;
|
|
48
48
|
}
|
|
49
49
|
interface ConfigStore {
|
|
50
50
|
get(key: string): {
|
|
@@ -54,8 +54,8 @@ interface ConfigStore {
|
|
|
54
54
|
value: unknown;
|
|
55
55
|
found: boolean;
|
|
56
56
|
}>;
|
|
57
|
-
set(key: string, value: unknown): void | Promise<void>;
|
|
58
57
|
list(): Record<string, unknown> | Promise<Record<string, unknown>>;
|
|
58
|
+
set(key: string, value: unknown): void | Promise<void>;
|
|
59
59
|
}
|
|
60
60
|
interface ConfigToolOptions {
|
|
61
61
|
/** Optional override for the config tool description. */
|
|
@@ -67,16 +67,16 @@ interface ConfigToolOptions {
|
|
|
67
67
|
}
|
|
68
68
|
declare function defineConfigTool(options?: ConfigToolOptions): ToolDefinition<ConfigToolInput, ConfigToolResponse>;
|
|
69
69
|
interface QueryToolInput {
|
|
70
|
-
q?: string | undefined;
|
|
71
|
-
query?: string | undefined;
|
|
72
|
-
limit?: number | undefined;
|
|
73
70
|
cursor?: string | undefined;
|
|
74
71
|
filters?: Record<string, unknown> | undefined;
|
|
72
|
+
limit?: number | undefined;
|
|
73
|
+
q?: string | undefined;
|
|
74
|
+
query?: string | undefined;
|
|
75
75
|
}
|
|
76
76
|
interface QueryToolResponse<T = unknown> {
|
|
77
|
-
results: T[];
|
|
78
|
-
nextCursor?: string;
|
|
79
77
|
_meta?: Record<string, unknown>;
|
|
78
|
+
nextCursor?: string;
|
|
79
|
+
results: T[];
|
|
80
80
|
}
|
|
81
81
|
interface QueryToolOptions<T = unknown> {
|
|
82
82
|
/** Optional override for the query tool description. */
|
|
@@ -86,8 +86,8 @@ interface QueryToolOptions<T = unknown> {
|
|
|
86
86
|
}
|
|
87
87
|
declare function defineQueryTool<T = unknown>(options?: QueryToolOptions<T>): ToolDefinition<QueryToolInput, QueryToolResponse<T>>;
|
|
88
88
|
interface CoreToolsOptions {
|
|
89
|
-
docs?: DocsToolOptions;
|
|
90
89
|
config?: ConfigToolOptions;
|
|
90
|
+
docs?: DocsToolOptions;
|
|
91
91
|
query?: QueryToolOptions;
|
|
92
92
|
}
|
|
93
93
|
type NormalizedQueryInput = Required<Pick<QueryToolInput, "q">> & Omit<QueryToolInput, "q">;
|
package/dist/transport.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { McpToolResponse, connectStdio, createSdkServer, wrapToolError, wrapToolResult } from "./shared/@outfitter/mcp-
|
|
2
|
-
import "./shared/@outfitter/mcp-
|
|
3
|
-
import "./shared/@outfitter/mcp-cqpyer9m";
|
|
1
|
+
import { McpToolResponse, connectStdio, createSdkServer, wrapToolError, wrapToolResult } from "./shared/@outfitter/mcp-7kcw2814.js";
|
|
2
|
+
import "./shared/@outfitter/mcp-gqjg15f5.js";
|
|
3
|
+
import "./shared/@outfitter/mcp-cqpyer9m.js";
|
|
4
4
|
export { wrapToolResult, wrapToolError, createSdkServer, connectStdio, McpToolResponse };
|
package/dist/transport.js
CHANGED
|
@@ -1,10 +1,166 @@
|
|
|
1
1
|
// @bun
|
|
2
|
+
// packages/mcp/src/transport.ts
|
|
3
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
4
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
2
5
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
CallToolRequestSchema,
|
|
7
|
+
CompleteRequestSchema,
|
|
8
|
+
GetPromptRequestSchema,
|
|
9
|
+
ListPromptsRequestSchema,
|
|
10
|
+
ListResourcesRequestSchema,
|
|
11
|
+
ListResourceTemplatesRequestSchema,
|
|
12
|
+
ListToolsRequestSchema,
|
|
13
|
+
ReadResourceRequestSchema,
|
|
14
|
+
McpError as SdkMcpError,
|
|
15
|
+
SetLevelRequestSchema,
|
|
16
|
+
SubscribeRequestSchema,
|
|
17
|
+
UnsubscribeRequestSchema
|
|
18
|
+
} from "@modelcontextprotocol/sdk/types.js";
|
|
19
|
+
import { safeStringify } from "@outfitter/contracts";
|
|
20
|
+
function isMcpToolResponse(value) {
|
|
21
|
+
if (!value || typeof value !== "object") {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
const content = value.content;
|
|
25
|
+
return Array.isArray(content);
|
|
26
|
+
}
|
|
27
|
+
function toTextPayload(value) {
|
|
28
|
+
if (typeof value === "string") {
|
|
29
|
+
return value;
|
|
30
|
+
}
|
|
31
|
+
return safeStringify(value);
|
|
32
|
+
}
|
|
33
|
+
function serializeError(error) {
|
|
34
|
+
if (error && typeof error === "object") {
|
|
35
|
+
const record = error;
|
|
36
|
+
return {
|
|
37
|
+
_tag: record._tag ?? "McpError",
|
|
38
|
+
message: record.message ?? "Unknown error",
|
|
39
|
+
code: record.code,
|
|
40
|
+
context: record.context
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
_tag: "McpError",
|
|
45
|
+
message: String(error)
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function wrapToolResult(value) {
|
|
49
|
+
if (isMcpToolResponse(value)) {
|
|
50
|
+
return value;
|
|
51
|
+
}
|
|
52
|
+
const structuredContent = value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
|
|
53
|
+
return {
|
|
54
|
+
content: [
|
|
55
|
+
{
|
|
56
|
+
type: "text",
|
|
57
|
+
text: toTextPayload(value)
|
|
58
|
+
}
|
|
59
|
+
],
|
|
60
|
+
...structuredContent ? { structuredContent } : {}
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function wrapToolError(error) {
|
|
64
|
+
return {
|
|
65
|
+
content: [
|
|
66
|
+
{
|
|
67
|
+
type: "text",
|
|
68
|
+
text: toTextPayload(serializeError(error))
|
|
69
|
+
}
|
|
70
|
+
],
|
|
71
|
+
isError: true
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
function toSdkError(error) {
|
|
75
|
+
return new SdkMcpError(error.code, error.message, error.context);
|
|
76
|
+
}
|
|
77
|
+
function createSdkServer(server) {
|
|
78
|
+
const capabilities = {
|
|
79
|
+
tools: { listChanged: true },
|
|
80
|
+
resources: { listChanged: true, subscribe: true },
|
|
81
|
+
prompts: { listChanged: true },
|
|
82
|
+
completions: {},
|
|
83
|
+
logging: {}
|
|
84
|
+
};
|
|
85
|
+
const sdkServer = new Server({ name: server.name, version: server.version }, { capabilities });
|
|
86
|
+
sdkServer.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
87
|
+
tools: server.getTools()
|
|
88
|
+
}));
|
|
89
|
+
sdkServer.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
90
|
+
const { name, arguments: args } = request.params;
|
|
91
|
+
const progressToken = request.params._meta?.progressToken;
|
|
92
|
+
const options = progressToken !== undefined ? { progressToken } : undefined;
|
|
93
|
+
const result = await server.invokeTool(name, args ?? {}, options);
|
|
94
|
+
if (result.isErr()) {
|
|
95
|
+
return wrapToolError(result.error);
|
|
96
|
+
}
|
|
97
|
+
return wrapToolResult(result.value);
|
|
98
|
+
});
|
|
99
|
+
sdkServer.setRequestHandler(ListResourcesRequestSchema, async () => ({
|
|
100
|
+
resources: server.getResources().map((r) => ({
|
|
101
|
+
uri: r.uri,
|
|
102
|
+
name: r.name,
|
|
103
|
+
...r.description ? { description: r.description } : {},
|
|
104
|
+
...r.mimeType ? { mimeType: r.mimeType } : {}
|
|
105
|
+
}))
|
|
106
|
+
}));
|
|
107
|
+
sdkServer.setRequestHandler(ListResourceTemplatesRequestSchema, async () => ({
|
|
108
|
+
resourceTemplates: server.getResourceTemplates().map((t) => ({
|
|
109
|
+
uriTemplate: t.uriTemplate,
|
|
110
|
+
name: t.name,
|
|
111
|
+
...t.description ? { description: t.description } : {},
|
|
112
|
+
...t.mimeType ? { mimeType: t.mimeType } : {}
|
|
113
|
+
}))
|
|
114
|
+
}));
|
|
115
|
+
sdkServer.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
116
|
+
const { uri } = request.params;
|
|
117
|
+
const result = await server.readResource(uri);
|
|
118
|
+
if (result.isErr()) {
|
|
119
|
+
throw toSdkError(result.error);
|
|
120
|
+
}
|
|
121
|
+
return { contents: result.value };
|
|
122
|
+
});
|
|
123
|
+
sdkServer.setRequestHandler(SubscribeRequestSchema, async (request) => {
|
|
124
|
+
server.subscribe(request.params.uri);
|
|
125
|
+
return {};
|
|
126
|
+
});
|
|
127
|
+
sdkServer.setRequestHandler(UnsubscribeRequestSchema, async (request) => {
|
|
128
|
+
server.unsubscribe(request.params.uri);
|
|
129
|
+
return {};
|
|
130
|
+
});
|
|
131
|
+
sdkServer.setRequestHandler(ListPromptsRequestSchema, async () => ({
|
|
132
|
+
prompts: server.getPrompts()
|
|
133
|
+
}));
|
|
134
|
+
sdkServer.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
135
|
+
const { name, arguments: args } = request.params;
|
|
136
|
+
const result = await server.getPrompt(name, args ?? {});
|
|
137
|
+
if (result.isErr()) {
|
|
138
|
+
throw toSdkError(result.error);
|
|
139
|
+
}
|
|
140
|
+
return { ...result.value };
|
|
141
|
+
});
|
|
142
|
+
sdkServer.setRequestHandler(CompleteRequestSchema, async (request) => {
|
|
143
|
+
const { ref, argument } = request.params;
|
|
144
|
+
const completionRef = ref.type === "ref/prompt" ? { type: "ref/prompt", name: ref.name } : { type: "ref/resource", uri: ref.uri };
|
|
145
|
+
const result = await server.complete(completionRef, argument.name, argument.value);
|
|
146
|
+
if (result.isErr()) {
|
|
147
|
+
throw toSdkError(result.error);
|
|
148
|
+
}
|
|
149
|
+
return { completion: result.value };
|
|
150
|
+
});
|
|
151
|
+
sdkServer.setRequestHandler(SetLevelRequestSchema, async (request) => {
|
|
152
|
+
const level = request.params.level;
|
|
153
|
+
server.setLogLevel?.(level);
|
|
154
|
+
return {};
|
|
155
|
+
});
|
|
156
|
+
server.bindSdkServer?.(sdkServer);
|
|
157
|
+
return sdkServer;
|
|
158
|
+
}
|
|
159
|
+
async function connectStdio(server, transport = new StdioServerTransport) {
|
|
160
|
+
const sdkServer = createSdkServer(server);
|
|
161
|
+
await sdkServer.connect(transport);
|
|
162
|
+
return sdkServer;
|
|
163
|
+
}
|
|
8
164
|
export {
|
|
9
165
|
wrapToolResult,
|
|
10
166
|
wrapToolError,
|
package/dist/types.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { BlobResourceContent, CompletionHandler, CompletionRef, CompletionResult, ContentAnnotations, InvokeToolOptions, McpError, McpHandlerContext, McpServer, McpServerOptions, ProgressReporter, PromptArgument, PromptDefinition, PromptHandler, PromptMessage, PromptMessageContent, PromptResult, ResourceContent, ResourceDefinition, ResourceReadHandler, ResourceTemplateDefinition, ResourceTemplateReadHandler, Result, SerializedTool, TOOL_ANNOTATIONS, TaggedError, TextResourceContent, ToolAnnotations, ToolDefinition, adaptHandler } from "./shared/@outfitter/mcp-
|
|
2
|
-
import "./shared/@outfitter/mcp-cqpyer9m";
|
|
1
|
+
import { BlobResourceContent, CompletionHandler, CompletionRef, CompletionResult, ContentAnnotations, InvokeToolOptions, McpError, McpHandlerContext, McpServer, McpServerOptions, ProgressReporter, PromptArgument, PromptDefinition, PromptHandler, PromptMessage, PromptMessageContent, PromptResult, ResourceContent, ResourceDefinition, ResourceReadHandler, ResourceTemplateDefinition, ResourceTemplateReadHandler, Result, SerializedTool, TOOL_ANNOTATIONS, TaggedError, TextResourceContent, ToolAnnotations, ToolDefinition, adaptHandler } from "./shared/@outfitter/mcp-gqjg15f5.js";
|
|
2
|
+
import "./shared/@outfitter/mcp-cqpyer9m.js";
|
|
3
3
|
export { adaptHandler, ToolDefinition, ToolAnnotations, TextResourceContent, TaggedError, TOOL_ANNOTATIONS, SerializedTool, Result, ResourceTemplateReadHandler, ResourceTemplateDefinition, ResourceReadHandler, ResourceDefinition, ResourceContent, PromptResult, PromptMessageContent, PromptMessage, PromptHandler, PromptDefinition, PromptArgument, ProgressReporter, McpServerOptions, McpServer, McpHandlerContext, McpError, InvokeToolOptions, ContentAnnotations, CompletionResult, CompletionRef, CompletionHandler, BlobResourceContent };
|
package/package.json
CHANGED
|
@@ -1,11 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@outfitter/mcp",
|
|
3
|
+
"version": "0.4.3",
|
|
3
4
|
"description": "MCP server framework with typed tools for Outfitter",
|
|
4
|
-
"
|
|
5
|
-
|
|
5
|
+
"keywords": [
|
|
6
|
+
"mcp",
|
|
7
|
+
"model-context-protocol",
|
|
8
|
+
"outfitter",
|
|
9
|
+
"tools",
|
|
10
|
+
"typescript"
|
|
11
|
+
],
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "https://github.com/outfitter-dev/outfitter.git",
|
|
16
|
+
"directory": "packages/mcp"
|
|
17
|
+
},
|
|
6
18
|
"files": [
|
|
7
19
|
"dist"
|
|
8
20
|
],
|
|
21
|
+
"type": "module",
|
|
22
|
+
"sideEffects": false,
|
|
9
23
|
"module": "./dist/index.js",
|
|
10
24
|
"types": "./dist/index.d.ts",
|
|
11
25
|
"exports": {
|
|
@@ -59,45 +73,32 @@
|
|
|
59
73
|
}
|
|
60
74
|
}
|
|
61
75
|
},
|
|
62
|
-
"
|
|
76
|
+
"publishConfig": {
|
|
77
|
+
"access": "public"
|
|
78
|
+
},
|
|
63
79
|
"scripts": {
|
|
64
|
-
"build": "bunup --filter @outfitter/mcp",
|
|
65
|
-
"lint": "
|
|
66
|
-
"lint:fix": "
|
|
80
|
+
"build": "cd ../.. && bunup --filter @outfitter/mcp",
|
|
81
|
+
"lint": "oxlint ./src",
|
|
82
|
+
"lint:fix": "oxlint --fix ./src",
|
|
67
83
|
"test": "bun test",
|
|
68
84
|
"typecheck": "tsc --noEmit",
|
|
69
|
-
"clean": "rm -rf dist"
|
|
85
|
+
"clean": "rm -rf dist",
|
|
86
|
+
"prepublishOnly": "bun ../../scripts/check-publish-manifest.ts"
|
|
70
87
|
},
|
|
71
88
|
"dependencies": {
|
|
72
89
|
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
73
90
|
"zod": "^4.3.5"
|
|
74
91
|
},
|
|
92
|
+
"devDependencies": {
|
|
93
|
+
"@outfitter/config": "0.3.4",
|
|
94
|
+
"@outfitter/contracts": "0.4.2",
|
|
95
|
+
"@outfitter/logging": "0.4.2",
|
|
96
|
+
"@types/bun": "^1.3.9",
|
|
97
|
+
"typescript": "^5.9.3"
|
|
98
|
+
},
|
|
75
99
|
"peerDependencies": {
|
|
76
100
|
"@outfitter/config": ">=0.3.0",
|
|
77
101
|
"@outfitter/contracts": ">=0.2.0",
|
|
78
102
|
"@outfitter/logging": ">=0.3.0"
|
|
79
|
-
},
|
|
80
|
-
"devDependencies": {
|
|
81
|
-
"@outfitter/config": "0.3.2",
|
|
82
|
-
"@outfitter/contracts": "0.4.0",
|
|
83
|
-
"@outfitter/logging": "0.4.0",
|
|
84
|
-
"@types/bun": "latest",
|
|
85
|
-
"typescript": "^5.8.0"
|
|
86
|
-
},
|
|
87
|
-
"keywords": [
|
|
88
|
-
"outfitter",
|
|
89
|
-
"mcp",
|
|
90
|
-
"model-context-protocol",
|
|
91
|
-
"tools",
|
|
92
|
-
"typescript"
|
|
93
|
-
],
|
|
94
|
-
"license": "MIT",
|
|
95
|
-
"repository": {
|
|
96
|
-
"type": "git",
|
|
97
|
-
"url": "https://github.com/outfitter-dev/outfitter.git",
|
|
98
|
-
"directory": "packages/mcp"
|
|
99
|
-
},
|
|
100
|
-
"publishConfig": {
|
|
101
|
-
"access": "public"
|
|
102
103
|
}
|
|
103
104
|
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
import {
|
|
3
|
-
defineTool
|
|
4
|
-
} from "./mcp-nmp5wf0w.js";
|
|
5
|
-
|
|
6
|
-
// packages/mcp/src/actions.ts
|
|
7
|
-
import { DEFAULT_REGISTRY_SURFACES } from "@outfitter/contracts";
|
|
8
|
-
function isActionRegistry(source) {
|
|
9
|
-
return "list" in source;
|
|
10
|
-
}
|
|
11
|
-
function buildMcpTools(source, options = {}) {
|
|
12
|
-
const actions = isActionRegistry(source) ? source.list() : source;
|
|
13
|
-
const includeSurfaces = options.includeSurfaces ?? [
|
|
14
|
-
"mcp"
|
|
15
|
-
];
|
|
16
|
-
return actions.filter((action) => {
|
|
17
|
-
const surfaces = action.surfaces ?? DEFAULT_REGISTRY_SURFACES;
|
|
18
|
-
return surfaces.some((surface) => includeSurfaces.includes(surface));
|
|
19
|
-
}).map((action) => defineTool({
|
|
20
|
-
name: action.mcp?.tool ?? action.id,
|
|
21
|
-
description: action.mcp?.description ?? action.description ?? action.id,
|
|
22
|
-
inputSchema: action.input,
|
|
23
|
-
handler: async (input, ctx) => action.handler(input, ctx),
|
|
24
|
-
...action.mcp?.deferLoading !== undefined ? { deferLoading: action.mcp.deferLoading } : {}
|
|
25
|
-
}));
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export { buildMcpTools };
|
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
// packages/mcp/src/transport.ts
|
|
3
|
-
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
4
|
-
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
5
|
-
import {
|
|
6
|
-
CallToolRequestSchema,
|
|
7
|
-
CompleteRequestSchema,
|
|
8
|
-
GetPromptRequestSchema,
|
|
9
|
-
ListPromptsRequestSchema,
|
|
10
|
-
ListResourcesRequestSchema,
|
|
11
|
-
ListResourceTemplatesRequestSchema,
|
|
12
|
-
ListToolsRequestSchema,
|
|
13
|
-
ReadResourceRequestSchema,
|
|
14
|
-
McpError as SdkMcpError,
|
|
15
|
-
SetLevelRequestSchema,
|
|
16
|
-
SubscribeRequestSchema,
|
|
17
|
-
UnsubscribeRequestSchema
|
|
18
|
-
} from "@modelcontextprotocol/sdk/types.js";
|
|
19
|
-
import { safeStringify } from "@outfitter/contracts";
|
|
20
|
-
function isMcpToolResponse(value) {
|
|
21
|
-
if (!value || typeof value !== "object") {
|
|
22
|
-
return false;
|
|
23
|
-
}
|
|
24
|
-
const content = value.content;
|
|
25
|
-
return Array.isArray(content);
|
|
26
|
-
}
|
|
27
|
-
function toTextPayload(value) {
|
|
28
|
-
if (typeof value === "string") {
|
|
29
|
-
return value;
|
|
30
|
-
}
|
|
31
|
-
return safeStringify(value);
|
|
32
|
-
}
|
|
33
|
-
function serializeError(error) {
|
|
34
|
-
if (error && typeof error === "object") {
|
|
35
|
-
const record = error;
|
|
36
|
-
return {
|
|
37
|
-
_tag: record._tag ?? "McpError",
|
|
38
|
-
message: record.message ?? "Unknown error",
|
|
39
|
-
code: record.code,
|
|
40
|
-
context: record.context
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
return {
|
|
44
|
-
_tag: "McpError",
|
|
45
|
-
message: String(error)
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
function wrapToolResult(value) {
|
|
49
|
-
if (isMcpToolResponse(value)) {
|
|
50
|
-
return value;
|
|
51
|
-
}
|
|
52
|
-
const structuredContent = value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
|
|
53
|
-
return {
|
|
54
|
-
content: [
|
|
55
|
-
{
|
|
56
|
-
type: "text",
|
|
57
|
-
text: toTextPayload(value)
|
|
58
|
-
}
|
|
59
|
-
],
|
|
60
|
-
...structuredContent ? { structuredContent } : {}
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
function wrapToolError(error) {
|
|
64
|
-
return {
|
|
65
|
-
content: [
|
|
66
|
-
{
|
|
67
|
-
type: "text",
|
|
68
|
-
text: toTextPayload(serializeError(error))
|
|
69
|
-
}
|
|
70
|
-
],
|
|
71
|
-
isError: true
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
function toSdkError(error) {
|
|
75
|
-
return new SdkMcpError(error.code, error.message, error.context);
|
|
76
|
-
}
|
|
77
|
-
function createSdkServer(server) {
|
|
78
|
-
const capabilities = {
|
|
79
|
-
tools: { listChanged: true },
|
|
80
|
-
resources: { listChanged: true, subscribe: true },
|
|
81
|
-
prompts: { listChanged: true },
|
|
82
|
-
completions: {},
|
|
83
|
-
logging: {}
|
|
84
|
-
};
|
|
85
|
-
const sdkServer = new Server({ name: server.name, version: server.version }, { capabilities });
|
|
86
|
-
sdkServer.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
87
|
-
tools: server.getTools()
|
|
88
|
-
}));
|
|
89
|
-
sdkServer.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
90
|
-
const { name, arguments: args } = request.params;
|
|
91
|
-
const progressToken = request.params._meta?.progressToken;
|
|
92
|
-
const options = progressToken !== undefined ? { progressToken } : undefined;
|
|
93
|
-
const result = await server.invokeTool(name, args ?? {}, options);
|
|
94
|
-
if (result.isErr()) {
|
|
95
|
-
return wrapToolError(result.error);
|
|
96
|
-
}
|
|
97
|
-
return wrapToolResult(result.value);
|
|
98
|
-
});
|
|
99
|
-
sdkServer.setRequestHandler(ListResourcesRequestSchema, async () => ({
|
|
100
|
-
resources: server.getResources().map((r) => ({
|
|
101
|
-
uri: r.uri,
|
|
102
|
-
name: r.name,
|
|
103
|
-
...r.description ? { description: r.description } : {},
|
|
104
|
-
...r.mimeType ? { mimeType: r.mimeType } : {}
|
|
105
|
-
}))
|
|
106
|
-
}));
|
|
107
|
-
sdkServer.setRequestHandler(ListResourceTemplatesRequestSchema, async () => ({
|
|
108
|
-
resourceTemplates: server.getResourceTemplates().map((t) => ({
|
|
109
|
-
uriTemplate: t.uriTemplate,
|
|
110
|
-
name: t.name,
|
|
111
|
-
...t.description ? { description: t.description } : {},
|
|
112
|
-
...t.mimeType ? { mimeType: t.mimeType } : {}
|
|
113
|
-
}))
|
|
114
|
-
}));
|
|
115
|
-
sdkServer.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
116
|
-
const { uri } = request.params;
|
|
117
|
-
const result = await server.readResource(uri);
|
|
118
|
-
if (result.isErr()) {
|
|
119
|
-
throw toSdkError(result.error);
|
|
120
|
-
}
|
|
121
|
-
return { contents: result.value };
|
|
122
|
-
});
|
|
123
|
-
sdkServer.setRequestHandler(SubscribeRequestSchema, async (request) => {
|
|
124
|
-
server.subscribe(request.params.uri);
|
|
125
|
-
return {};
|
|
126
|
-
});
|
|
127
|
-
sdkServer.setRequestHandler(UnsubscribeRequestSchema, async (request) => {
|
|
128
|
-
server.unsubscribe(request.params.uri);
|
|
129
|
-
return {};
|
|
130
|
-
});
|
|
131
|
-
sdkServer.setRequestHandler(ListPromptsRequestSchema, async () => ({
|
|
132
|
-
prompts: server.getPrompts()
|
|
133
|
-
}));
|
|
134
|
-
sdkServer.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
135
|
-
const { name, arguments: args } = request.params;
|
|
136
|
-
const result = await server.getPrompt(name, args ?? {});
|
|
137
|
-
if (result.isErr()) {
|
|
138
|
-
throw toSdkError(result.error);
|
|
139
|
-
}
|
|
140
|
-
return { ...result.value };
|
|
141
|
-
});
|
|
142
|
-
sdkServer.setRequestHandler(CompleteRequestSchema, async (request) => {
|
|
143
|
-
const { ref, argument } = request.params;
|
|
144
|
-
const completionRef = ref.type === "ref/prompt" ? { type: "ref/prompt", name: ref.name } : { type: "ref/resource", uri: ref.uri };
|
|
145
|
-
const result = await server.complete(completionRef, argument.name, argument.value);
|
|
146
|
-
if (result.isErr()) {
|
|
147
|
-
throw toSdkError(result.error);
|
|
148
|
-
}
|
|
149
|
-
return { completion: result.value };
|
|
150
|
-
});
|
|
151
|
-
sdkServer.setRequestHandler(SetLevelRequestSchema, async (request) => {
|
|
152
|
-
const level = request.params.level;
|
|
153
|
-
server.setLogLevel?.(level);
|
|
154
|
-
return {};
|
|
155
|
-
});
|
|
156
|
-
server.bindSdkServer?.(sdkServer);
|
|
157
|
-
return sdkServer;
|
|
158
|
-
}
|
|
159
|
-
async function connectStdio(server, transport = new StdioServerTransport) {
|
|
160
|
-
const sdkServer = createSdkServer(server);
|
|
161
|
-
await sdkServer.connect(transport);
|
|
162
|
-
return sdkServer;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
export { wrapToolResult, wrapToolError, createSdkServer, connectStdio };
|