@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
package/README.md
CHANGED
|
@@ -54,9 +54,9 @@ Creates an MCP server instance.
|
|
|
54
54
|
|
|
55
55
|
```typescript
|
|
56
56
|
interface McpServerOptions {
|
|
57
|
-
name: string;
|
|
58
|
-
version: string;
|
|
59
|
-
logger?: Logger;
|
|
57
|
+
name: string; // Server name for MCP handshake
|
|
58
|
+
version: string; // Server version (semver)
|
|
59
|
+
logger?: Logger; // Optional structured logger (BYO)
|
|
60
60
|
defaultLogLevel?: McpLogLevel | null; // Default log forwarding level
|
|
61
61
|
}
|
|
62
62
|
|
|
@@ -140,6 +140,7 @@ const server = createMcpServer({
|
|
|
140
140
|
MCP servers can forward log messages to the connected client. The default log level is resolved from environment configuration:
|
|
141
141
|
|
|
142
142
|
**Precedence** (highest wins):
|
|
143
|
+
|
|
143
144
|
1. `OUTFITTER_LOG_LEVEL` environment variable
|
|
144
145
|
2. `options.defaultLogLevel`
|
|
145
146
|
3. `OUTFITTER_ENV` profile defaults (`"debug"` in development, `null` otherwise)
|
|
@@ -176,11 +177,11 @@ Helper for defining typed tools with better type inference.
|
|
|
176
177
|
|
|
177
178
|
```typescript
|
|
178
179
|
interface ToolDefinition<TInput, TOutput, TError> {
|
|
179
|
-
name: string;
|
|
180
|
-
description: string;
|
|
181
|
-
inputSchema: z.ZodType<TInput>;
|
|
180
|
+
name: string; // Unique tool name (kebab-case)
|
|
181
|
+
description: string; // Human-readable description
|
|
182
|
+
inputSchema: z.ZodType<TInput>; // Zod schema for validation
|
|
182
183
|
handler: Handler<TInput, TOutput, TError>;
|
|
183
|
-
deferLoading?: boolean;
|
|
184
|
+
deferLoading?: boolean; // Default: true
|
|
184
185
|
}
|
|
185
186
|
|
|
186
187
|
const getUserTool = defineTool({
|
|
@@ -203,10 +204,10 @@ Helper for defining MCP resources.
|
|
|
203
204
|
|
|
204
205
|
```typescript
|
|
205
206
|
interface ResourceDefinition {
|
|
206
|
-
uri: string;
|
|
207
|
-
name: string;
|
|
208
|
-
description?: string;
|
|
209
|
-
mimeType?: string;
|
|
207
|
+
uri: string; // Unique resource URI
|
|
208
|
+
name: string; // Human-readable name
|
|
209
|
+
description?: string; // Optional description
|
|
210
|
+
mimeType?: string; // Content MIME type
|
|
210
211
|
handler?: ResourceReadHandler; // Optional resources/read handler
|
|
211
212
|
}
|
|
212
213
|
|
|
@@ -255,7 +256,11 @@ interface McpServer {
|
|
|
255
256
|
|
|
256
257
|
// Invocation
|
|
257
258
|
readResource(uri: string): Promise<Result<ResourceContent[], McpError>>;
|
|
258
|
-
invokeTool<T>(
|
|
259
|
+
invokeTool<T>(
|
|
260
|
+
name: string,
|
|
261
|
+
input: unknown,
|
|
262
|
+
options?: InvokeToolOptions
|
|
263
|
+
): Promise<Result<T, McpError>>;
|
|
259
264
|
|
|
260
265
|
// Lifecycle
|
|
261
266
|
start(): Promise<void>;
|
|
@@ -269,7 +274,7 @@ Extended handler context for MCP tools with additional metadata:
|
|
|
269
274
|
|
|
270
275
|
```typescript
|
|
271
276
|
interface McpHandlerContext extends HandlerContext {
|
|
272
|
-
toolName?: string;
|
|
277
|
+
toolName?: string; // Name of the tool being invoked
|
|
273
278
|
}
|
|
274
279
|
```
|
|
275
280
|
|
|
@@ -372,7 +377,9 @@ const listTool = defineTool({
|
|
|
372
377
|
description: "List all items",
|
|
373
378
|
inputSchema: z.object({}),
|
|
374
379
|
annotations: TOOL_ANNOTATIONS.readOnly,
|
|
375
|
-
handler: async (input, ctx) => {
|
|
380
|
+
handler: async (input, ctx) => {
|
|
381
|
+
/* ... */
|
|
382
|
+
},
|
|
376
383
|
});
|
|
377
384
|
|
|
378
385
|
// Spread and override for edge cases
|
|
@@ -381,17 +388,19 @@ const searchTool = defineTool({
|
|
|
381
388
|
description: "Search external APIs",
|
|
382
389
|
inputSchema: z.object({ q: z.string() }),
|
|
383
390
|
annotations: { ...TOOL_ANNOTATIONS.readOnly, openWorldHint: true },
|
|
384
|
-
handler: async (input, ctx) => {
|
|
391
|
+
handler: async (input, ctx) => {
|
|
392
|
+
/* ... */
|
|
393
|
+
},
|
|
385
394
|
});
|
|
386
395
|
```
|
|
387
396
|
|
|
388
|
-
| Preset
|
|
389
|
-
|
|
390
|
-
| `readOnly`
|
|
391
|
-
| `write`
|
|
392
|
-
| `writeIdempotent` | false
|
|
393
|
-
| `destructive`
|
|
394
|
-
| `openWorld`
|
|
397
|
+
| Preset | readOnly | destructive | idempotent | openWorld |
|
|
398
|
+
| ----------------- | -------- | ----------- | ---------- | --------- |
|
|
399
|
+
| `readOnly` | true | false | true | false |
|
|
400
|
+
| `write` | false | false | false | false |
|
|
401
|
+
| `writeIdempotent` | false | false | true | false |
|
|
402
|
+
| `destructive` | false | true | true | false |
|
|
403
|
+
| `openWorld` | false | false | false | true |
|
|
395
404
|
|
|
396
405
|
For multi-action tools, use the most conservative union of hints. Per-action annotations are an MCP spec limitation.
|
|
397
406
|
|
|
@@ -454,12 +463,12 @@ const { server: sdkServer, toolsList, callTool } = createSdkServer(mcpServer);
|
|
|
454
463
|
|
|
455
464
|
Tools return Results with typed errors. The framework automatically translates `OutfitterError` categories to JSON-RPC error codes:
|
|
456
465
|
|
|
457
|
-
| Category
|
|
458
|
-
|
|
459
|
-
| `validation` | -32602
|
|
460
|
-
| `not_found`
|
|
461
|
-
| `permission` | -32600
|
|
462
|
-
| `internal`
|
|
466
|
+
| Category | JSON-RPC Code | Description |
|
|
467
|
+
| ------------ | ------------- | ---------------- |
|
|
468
|
+
| `validation` | -32602 | Invalid params |
|
|
469
|
+
| `not_found` | -32601 | Method not found |
|
|
470
|
+
| `permission` | -32600 | Invalid request |
|
|
471
|
+
| `internal` | -32603 | Internal error |
|
|
463
472
|
|
|
464
473
|
```typescript
|
|
465
474
|
const result = await server.invokeTool("get-user", { userId: "123" });
|
|
@@ -523,13 +532,14 @@ Add your MCP server to Claude Desktop:
|
|
|
523
532
|
```
|
|
524
533
|
|
|
525
534
|
Config location:
|
|
535
|
+
|
|
526
536
|
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
527
537
|
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
528
538
|
- Linux: `~/.config/claude/claude_desktop_config.json`
|
|
529
539
|
|
|
530
540
|
## Upgrading
|
|
531
541
|
|
|
532
|
-
Run `outfitter
|
|
542
|
+
Run `outfitter upgrade --guide` for version-specific migration instructions, or check the [migration docs](https://github.com/outfitter-dev/outfitter/tree/main/plugins/outfitter/shared/migrations) for detailed upgrade steps.
|
|
533
543
|
|
|
534
544
|
## Related Packages
|
|
535
545
|
|
package/dist/actions.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BuildMcpToolsOptions, buildMcpTools } from "./shared/@outfitter/mcp-
|
|
2
|
-
import "./shared/@outfitter/mcp-
|
|
3
|
-
import "./shared/@outfitter/mcp-cqpyer9m";
|
|
1
|
+
import { BuildMcpToolsOptions, buildMcpTools } from "./shared/@outfitter/mcp-d8vs6vry.js";
|
|
2
|
+
import "./shared/@outfitter/mcp-gqjg15f5.js";
|
|
3
|
+
import "./shared/@outfitter/mcp-cqpyer9m.js";
|
|
4
4
|
export { buildMcpTools, BuildMcpToolsOptions };
|
package/dist/actions.js
CHANGED
|
@@ -1,11 +1,32 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
} from "./shared/@outfitter/mcp-
|
|
5
|
-
import"./shared/@outfitter/mcp-nmp5wf0w.js";
|
|
3
|
+
defineTool
|
|
4
|
+
} from "./shared/@outfitter/mcp-b502y16n.js";
|
|
6
5
|
import"./shared/@outfitter/mcp-fjtxsa0x.js";
|
|
7
6
|
import"./shared/@outfitter/mcp-9m5hs2z0.js";
|
|
8
|
-
import"./shared/@outfitter/mcp-
|
|
7
|
+
import"./shared/@outfitter/mcp-hw5wz4gb.js";
|
|
8
|
+
|
|
9
|
+
// packages/mcp/src/actions.ts
|
|
10
|
+
import { DEFAULT_REGISTRY_SURFACES } from "@outfitter/contracts";
|
|
11
|
+
function isActionRegistry(source) {
|
|
12
|
+
return "list" in source;
|
|
13
|
+
}
|
|
14
|
+
function buildMcpTools(source, options = {}) {
|
|
15
|
+
const actions = isActionRegistry(source) ? source.list() : source;
|
|
16
|
+
const includeSurfaces = options.includeSurfaces ?? [
|
|
17
|
+
"mcp"
|
|
18
|
+
];
|
|
19
|
+
return actions.filter((action) => {
|
|
20
|
+
const surfaces = action.surfaces ?? DEFAULT_REGISTRY_SURFACES;
|
|
21
|
+
return surfaces.some((surface) => includeSurfaces.includes(surface));
|
|
22
|
+
}).map((action) => defineTool({
|
|
23
|
+
name: action.mcp?.tool ?? action.id,
|
|
24
|
+
description: action.mcp?.description ?? action.description ?? action.id,
|
|
25
|
+
inputSchema: action.input,
|
|
26
|
+
handler: async (input, ctx) => action.handler(input, ctx),
|
|
27
|
+
...action.mcp?.deferLoading !== undefined ? { deferLoading: action.mcp.deferLoading } : {}
|
|
28
|
+
}));
|
|
29
|
+
}
|
|
9
30
|
export {
|
|
10
31
|
buildMcpTools
|
|
11
32
|
};
|
package/dist/core-tools.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ConfigAction, ConfigStore, ConfigToolInput, ConfigToolOptions, ConfigToolResponse, CoreToolDefinition, CoreToolsOptions, DocsSection, DocsToolEntry, DocsToolInput, DocsToolOptions, DocsToolResponse, NormalizedQueryInput, QueryToolInput, QueryToolOptions, QueryToolResponse, createCoreTools, defineConfigTool, defineDocsTool, defineQueryTool } from "./shared/@outfitter/mcp-
|
|
2
|
-
import "./shared/@outfitter/mcp-
|
|
3
|
-
import "./shared/@outfitter/mcp-cqpyer9m";
|
|
1
|
+
import { ConfigAction, ConfigStore, ConfigToolInput, ConfigToolOptions, ConfigToolResponse, CoreToolDefinition, CoreToolsOptions, DocsSection, DocsToolEntry, DocsToolInput, DocsToolOptions, DocsToolResponse, NormalizedQueryInput, QueryToolInput, QueryToolOptions, QueryToolResponse, createCoreTools, defineConfigTool, defineDocsTool, defineQueryTool } from "./shared/@outfitter/mcp-s6afm4ff.js";
|
|
2
|
+
import "./shared/@outfitter/mcp-gqjg15f5.js";
|
|
3
|
+
import "./shared/@outfitter/mcp-cqpyer9m.js";
|
|
4
4
|
export { defineQueryTool, defineDocsTool, defineConfigTool, createCoreTools, QueryToolResponse, QueryToolOptions, QueryToolInput, NormalizedQueryInput, DocsToolResponse, DocsToolOptions, DocsToolInput, DocsToolEntry, DocsSection, CoreToolsOptions, CoreToolDefinition, ConfigToolResponse, ConfigToolOptions, ConfigToolInput, ConfigStore, ConfigAction };
|
package/dist/core-tools.js
CHANGED
|
@@ -1,10 +1,144 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
// packages/mcp/src/core-tools.ts
|
|
3
|
+
import { Result, ValidationError } from "@outfitter/contracts";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
var DEFAULT_DOCS = {
|
|
6
|
+
overview: "No documentation configured yet.",
|
|
7
|
+
tools: [],
|
|
8
|
+
examples: [],
|
|
9
|
+
schemas: {}
|
|
10
|
+
};
|
|
11
|
+
var docsSchema = z.object({
|
|
12
|
+
section: z.enum(["overview", "tools", "examples", "schemas"]).optional()
|
|
13
|
+
});
|
|
14
|
+
function pickDocsSection(payload, section) {
|
|
15
|
+
if (!section) {
|
|
16
|
+
return payload;
|
|
17
|
+
}
|
|
18
|
+
return {
|
|
19
|
+
[section]: payload[section]
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function defineDocsTool(options = {}) {
|
|
23
|
+
return {
|
|
24
|
+
name: "docs",
|
|
25
|
+
description: options.description ?? "Documentation, usage patterns, and examples for this MCP server.",
|
|
26
|
+
deferLoading: false,
|
|
27
|
+
inputSchema: docsSchema,
|
|
28
|
+
handler: async (input) => {
|
|
29
|
+
const payload = options.getDocs ? await options.getDocs(input.section) : options.docs ?? DEFAULT_DOCS;
|
|
30
|
+
return Result.ok(pickDocsSection(payload, input.section));
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
var configSchema = z.object({
|
|
35
|
+
action: z.enum(["get", "set", "list"]),
|
|
36
|
+
key: z.string().optional(),
|
|
37
|
+
value: z.unknown().optional()
|
|
38
|
+
});
|
|
39
|
+
function createInMemoryStore(initial = {}) {
|
|
40
|
+
const store = new Map(Object.entries(initial));
|
|
41
|
+
return {
|
|
42
|
+
get(key) {
|
|
43
|
+
return { value: store.get(key), found: store.has(key) };
|
|
44
|
+
},
|
|
45
|
+
set(key, value) {
|
|
46
|
+
store.set(key, value);
|
|
47
|
+
},
|
|
48
|
+
list() {
|
|
49
|
+
return Object.fromEntries(store.entries());
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
function defineConfigTool(options = {}) {
|
|
54
|
+
const store = options.store ?? createInMemoryStore(options.initial);
|
|
55
|
+
return {
|
|
56
|
+
name: "config",
|
|
57
|
+
description: options.description ?? "Read or modify server configuration values.",
|
|
58
|
+
deferLoading: false,
|
|
59
|
+
inputSchema: configSchema,
|
|
60
|
+
handler: async (input) => {
|
|
61
|
+
switch (input.action) {
|
|
62
|
+
case "list": {
|
|
63
|
+
const config = await store.list();
|
|
64
|
+
return Result.ok({ action: "list", config });
|
|
65
|
+
}
|
|
66
|
+
case "get": {
|
|
67
|
+
if (!input.key) {
|
|
68
|
+
return Result.err(new ValidationError({
|
|
69
|
+
message: "Config key is required for action 'get'.",
|
|
70
|
+
field: "key"
|
|
71
|
+
}));
|
|
72
|
+
}
|
|
73
|
+
const { value, found } = await store.get(input.key);
|
|
74
|
+
return Result.ok({ action: "get", key: input.key, value, found });
|
|
75
|
+
}
|
|
76
|
+
case "set": {
|
|
77
|
+
if (!input.key) {
|
|
78
|
+
return Result.err(new ValidationError({
|
|
79
|
+
message: "Config key is required for action 'set'.",
|
|
80
|
+
field: "key"
|
|
81
|
+
}));
|
|
82
|
+
}
|
|
83
|
+
await store.set(input.key, input.value);
|
|
84
|
+
return Result.ok({
|
|
85
|
+
action: "set",
|
|
86
|
+
key: input.key,
|
|
87
|
+
value: input.value
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
default:
|
|
91
|
+
return Result.err(new ValidationError({
|
|
92
|
+
message: `Unknown action: ${input.action}`,
|
|
93
|
+
field: "action"
|
|
94
|
+
}));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
var querySchema = z.object({
|
|
100
|
+
q: z.string().min(1).describe("Search query. Supports natural language or filter syntax.").optional(),
|
|
101
|
+
query: z.string().min(1).describe("Alias for q. Supports natural language or filter syntax.").optional(),
|
|
102
|
+
limit: z.number().int().positive().optional(),
|
|
103
|
+
cursor: z.string().optional(),
|
|
104
|
+
filters: z.record(z.string(), z.unknown()).optional()
|
|
105
|
+
}).refine((value) => {
|
|
106
|
+
const queryValue = (value.q ?? value.query)?.trim();
|
|
107
|
+
return typeof queryValue === "string" && queryValue.length > 0;
|
|
108
|
+
}, {
|
|
109
|
+
message: "Query is required.",
|
|
110
|
+
path: ["q"]
|
|
111
|
+
});
|
|
112
|
+
function defineQueryTool(options = {}) {
|
|
113
|
+
return {
|
|
114
|
+
name: "query",
|
|
115
|
+
description: options.description ?? "Search and discover resources with filters and pagination.",
|
|
116
|
+
deferLoading: false,
|
|
117
|
+
inputSchema: querySchema,
|
|
118
|
+
handler: (input, ctx) => {
|
|
119
|
+
const normalized = {
|
|
120
|
+
...input,
|
|
121
|
+
q: (input.q ?? input.query ?? "").trim()
|
|
122
|
+
};
|
|
123
|
+
if (options.handler) {
|
|
124
|
+
return options.handler(normalized, ctx);
|
|
125
|
+
}
|
|
126
|
+
return Promise.resolve(Result.ok({
|
|
127
|
+
results: [],
|
|
128
|
+
_meta: {
|
|
129
|
+
note: "No query handler configured."
|
|
130
|
+
}
|
|
131
|
+
}));
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
function createCoreTools(options = {}) {
|
|
136
|
+
return [
|
|
137
|
+
defineDocsTool(options.docs),
|
|
138
|
+
defineConfigTool(options.config),
|
|
139
|
+
defineQueryTool(options.query)
|
|
140
|
+
];
|
|
141
|
+
}
|
|
8
142
|
export {
|
|
9
143
|
defineQueryTool,
|
|
10
144
|
defineDocsTool,
|