@oat-app/mcp-bridge 0.1.0 → 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/README.md +1 -0
- package/dist/bridge.js +9 -2
- package/dist/bridge.js.map +1 -1
- package/dist/cache.d.ts +21 -0
- package/dist/cache.js +61 -0
- package/dist/cache.js.map +1 -0
- package/dist/config.d.ts +1 -0
- package/dist/config.js +10 -0
- package/dist/config.js.map +1 -1
- package/dist/constants.d.ts +1 -1
- package/dist/constants.js +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/manifest.d.ts +158 -0
- package/dist/manifest.js +114 -0
- package/dist/manifest.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -95,6 +95,7 @@ https://oat-blond.vercel.app/api/mcp
|
|
|
95
95
|
| `OAT_MCP_URL` | No | Endpoint override. Defaults to `https://oat-blond.vercel.app/api/mcp` |
|
|
96
96
|
| `OAT_MCP_DEBUG` | No | Set to `1` for stderr debug logs |
|
|
97
97
|
| `OAT_MCP_TIMEOUT_MS` | No | Request timeout. Defaults to `30000` |
|
|
98
|
+
| `OAT_MCP_CACHE_TTL_MS` | No | Low-risk tool cache TTL. Set to `0` to disable `get_context` and `list_references` caching |
|
|
98
99
|
|
|
99
100
|
Tokens are accepted only through environment variables. `--token` and `--url`
|
|
100
101
|
arguments are intentionally not supported.
|
package/dist/bridge.js
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
2
2
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
3
|
import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
4
|
+
import { CachedRemoteMcpClient } from "./cache.js";
|
|
4
5
|
import { PACKAGE_NAME, PACKAGE_VERSION } from "./constants.js";
|
|
6
|
+
import { BRIDGE_TOOL_DEFINITIONS } from "./manifest.js";
|
|
5
7
|
import { RemoteMcpClient } from "./remote.js";
|
|
6
8
|
export async function runBridge(config, logger) {
|
|
7
9
|
const remote = new RemoteMcpClient(config, logger);
|
|
8
10
|
await remote.connect();
|
|
11
|
+
const cachedRemote = new CachedRemoteMcpClient(remote, {
|
|
12
|
+
cacheTtlMs: config.cacheTtlMs,
|
|
13
|
+
});
|
|
9
14
|
const server = new Server({
|
|
10
15
|
name: PACKAGE_NAME,
|
|
11
16
|
version: PACKAGE_VERSION,
|
|
@@ -14,8 +19,10 @@ export async function runBridge(config, logger) {
|
|
|
14
19
|
tools: {},
|
|
15
20
|
},
|
|
16
21
|
});
|
|
17
|
-
server.setRequestHandler(ListToolsRequestSchema, (
|
|
18
|
-
|
|
22
|
+
server.setRequestHandler(ListToolsRequestSchema, () => ({
|
|
23
|
+
tools: BRIDGE_TOOL_DEFINITIONS,
|
|
24
|
+
}));
|
|
25
|
+
server.setRequestHandler(CallToolRequestSchema, (request) => cachedRemote.callTool(request.params));
|
|
19
26
|
const transport = new StdioServerTransport();
|
|
20
27
|
transport.onerror = (error) => {
|
|
21
28
|
logger.error("stdio transport error", { message: error.message });
|
package/dist/bridge.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bridge.js","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"bridge.js","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAEnD,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAE/D,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,MAAoB,EACpB,MAAc;IAEd,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnD,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;IACvB,MAAM,YAAY,GAAG,IAAI,qBAAqB,CAAC,MAAM,EAAE;QACrD,UAAU,EAAE,MAAM,CAAC,UAAU;KAC9B,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,IAAI,MAAM,CACvB;QACE,IAAI,EAAE,YAAY;QAClB,OAAO,EAAE,eAAe;KACzB,EACD;QACE,YAAY,EAAE;YACZ,KAAK,EAAE,EAAE;SACV;KACF,CACF,CAAC;IAEF,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,GAAG,EAAE,CAAC,CAAC;QACtD,KAAK,EAAE,uBAAuB;KAC/B,CAAC,CAAC,CAAC;IACJ,MAAM,CAAC,iBAAiB,CAAC,qBAAqB,EAAE,CAAC,OAAO,EAAE,EAAE,CAC1D,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CACtC,CAAC;IAEF,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,SAAS,CAAC,OAAO,GAAG,CAAC,KAAK,EAAE,EAAE;QAC5B,MAAM,CAAC,KAAK,CAAC,uBAAuB,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IACpE,CAAC,CAAC;IAEF,MAAM,KAAK,GAAG,KAAK,IAAI,EAAE;QACvB,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QACrB,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC,CAAC;IAEF,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE;QAC1B,KAAK,EAAE;aACJ,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;YACxB,MAAM,CAAC,KAAK,CAAC,wBAAwB,EAAE;gBACrC,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;aAChE,CAAC,CAAC;QACL,CAAC,CAAC;aACD,OAAO,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,MAAM,CAAC,KAAK,CAAC,sBAAsB,EAAE,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;AACvE,CAAC"}
|
package/dist/cache.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { CallToolRequest, ServerResult } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
export declare const DEFAULT_CONTEXT_CACHE_TTL_MS = 60000;
|
|
3
|
+
export declare const DEFAULT_REFERENCES_CACHE_TTL_MS = 120000;
|
|
4
|
+
type CallToolParams = CallToolRequest["params"];
|
|
5
|
+
export interface RemoteToolCaller {
|
|
6
|
+
callTool(params: CallToolParams): Promise<ServerResult>;
|
|
7
|
+
}
|
|
8
|
+
interface CachedRemoteMcpClientOptions {
|
|
9
|
+
cacheTtlMs?: number;
|
|
10
|
+
now?: () => number;
|
|
11
|
+
}
|
|
12
|
+
export declare class CachedRemoteMcpClient {
|
|
13
|
+
private readonly remote;
|
|
14
|
+
private readonly options;
|
|
15
|
+
private readonly cache;
|
|
16
|
+
private readonly now;
|
|
17
|
+
constructor(remote: RemoteToolCaller, options?: CachedRemoteMcpClientOptions);
|
|
18
|
+
callTool(params: CallToolParams): Promise<ServerResult>;
|
|
19
|
+
private getTtl;
|
|
20
|
+
}
|
|
21
|
+
export {};
|
package/dist/cache.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
export const DEFAULT_CONTEXT_CACHE_TTL_MS = 60_000;
|
|
2
|
+
export const DEFAULT_REFERENCES_CACHE_TTL_MS = 120_000;
|
|
3
|
+
const DEFAULT_TOOL_TTLS = new Map([
|
|
4
|
+
["get_context", DEFAULT_CONTEXT_CACHE_TTL_MS],
|
|
5
|
+
["list_references", DEFAULT_REFERENCES_CACHE_TTL_MS],
|
|
6
|
+
]);
|
|
7
|
+
function normalizeArguments(args) {
|
|
8
|
+
const value = args && typeof args === "object" ? args : {};
|
|
9
|
+
const { forceRefresh, ...forwardedArguments } = value;
|
|
10
|
+
return {
|
|
11
|
+
forceRefresh: forceRefresh === true,
|
|
12
|
+
forwardedArguments,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function stableStringify(value) {
|
|
16
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
17
|
+
return JSON.stringify(value);
|
|
18
|
+
}
|
|
19
|
+
const record = value;
|
|
20
|
+
return JSON.stringify(Object.keys(record)
|
|
21
|
+
.sort()
|
|
22
|
+
.reduce((result, key) => {
|
|
23
|
+
result[key] = record[key];
|
|
24
|
+
return result;
|
|
25
|
+
}, {}));
|
|
26
|
+
}
|
|
27
|
+
export class CachedRemoteMcpClient {
|
|
28
|
+
remote;
|
|
29
|
+
options;
|
|
30
|
+
cache = new Map();
|
|
31
|
+
now;
|
|
32
|
+
constructor(remote, options = {}) {
|
|
33
|
+
this.remote = remote;
|
|
34
|
+
this.options = options;
|
|
35
|
+
this.now = options.now ?? Date.now;
|
|
36
|
+
}
|
|
37
|
+
async callTool(params) {
|
|
38
|
+
const { forceRefresh, forwardedArguments } = normalizeArguments(params.arguments);
|
|
39
|
+
const forwardedParams = { ...params, arguments: forwardedArguments };
|
|
40
|
+
const ttl = this.getTtl(params.name);
|
|
41
|
+
if (ttl <= 0) {
|
|
42
|
+
return this.remote.callTool(forwardedParams);
|
|
43
|
+
}
|
|
44
|
+
const cacheKey = `${params.name}:${stableStringify(forwardedArguments)}`;
|
|
45
|
+
const cached = this.cache.get(cacheKey);
|
|
46
|
+
const now = this.now();
|
|
47
|
+
if (!forceRefresh && cached && cached.expiresAt > now) {
|
|
48
|
+
return cached.value;
|
|
49
|
+
}
|
|
50
|
+
const value = await this.remote.callTool(forwardedParams);
|
|
51
|
+
this.cache.set(cacheKey, { value, expiresAt: now + ttl });
|
|
52
|
+
return value;
|
|
53
|
+
}
|
|
54
|
+
getTtl(toolName) {
|
|
55
|
+
const defaultTtl = DEFAULT_TOOL_TTLS.get(toolName);
|
|
56
|
+
if (defaultTtl === undefined)
|
|
57
|
+
return 0;
|
|
58
|
+
return this.options.cacheTtlMs ?? defaultTtl;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAKA,MAAM,CAAC,MAAM,4BAA4B,GAAG,MAAM,CAAC;AACnD,MAAM,CAAC,MAAM,+BAA+B,GAAG,OAAO,CAAC;AAkBvD,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAiB;IAChD,CAAC,aAAa,EAAE,4BAA4B,CAAC;IAC7C,CAAC,iBAAiB,EAAE,+BAA+B,CAAC;CACrD,CAAC,CAAC;AAEH,SAAS,kBAAkB,CAAC,IAAa;IAIvC,MAAM,KAAK,GACT,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAE,IAAgC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5E,MAAM,EAAE,YAAY,EAAE,GAAG,kBAAkB,EAAE,GAAG,KAAK,CAAC;IAEtD,OAAO;QACL,YAAY,EAAE,YAAY,KAAK,IAAI;QACnC,kBAAkB;KACnB,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,KAAc;IACrC,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAChE,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IAED,MAAM,MAAM,GAAG,KAAgC,CAAC;IAChD,OAAO,IAAI,CAAC,SAAS,CACnB,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;SAChB,IAAI,EAAE;SACN,MAAM,CAA0B,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;QAC/C,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1B,OAAO,MAAM,CAAC;IAChB,CAAC,EAAE,EAAE,CAAC,CACT,CAAC;AACJ,CAAC;AAED,MAAM,OAAO,qBAAqB;IAKb;IACA;IALF,KAAK,GAAG,IAAI,GAAG,EAAsB,CAAC;IACtC,GAAG,CAAe;IAEnC,YACmB,MAAwB,EACxB,UAAwC,EAAE;QAD1C,WAAM,GAAN,MAAM,CAAkB;QACxB,YAAO,GAAP,OAAO,CAAmC;QAE3D,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IACrC,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,MAAsB;QACnC,MAAM,EAAE,YAAY,EAAE,kBAAkB,EAAE,GAAG,kBAAkB,CAC7D,MAAM,CAAC,SAAS,CACjB,CAAC;QACF,MAAM,eAAe,GAAG,EAAE,GAAG,MAAM,EAAE,SAAS,EAAE,kBAAkB,EAAE,CAAC;QACrE,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAErC,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC;YACb,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;QAC/C,CAAC;QAED,MAAM,QAAQ,GAAG,GAAG,MAAM,CAAC,IAAI,IAAI,eAAe,CAAC,kBAAkB,CAAC,EAAE,CAAC;QACzE,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACxC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEvB,IAAI,CAAC,YAAY,IAAI,MAAM,IAAI,MAAM,CAAC,SAAS,GAAG,GAAG,EAAE,CAAC;YACtD,OAAO,MAAM,CAAC,KAAK,CAAC;QACtB,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;QAC1D,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC;QAC1D,OAAO,KAAK,CAAC;IACf,CAAC;IAEO,MAAM,CAAC,QAAgB;QAC7B,MAAM,UAAU,GAAG,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACnD,IAAI,UAAU,KAAK,SAAS;YAAE,OAAO,CAAC,CAAC;QAEvC,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,IAAI,UAAU,CAAC;IAC/C,CAAC;CACF"}
|
package/dist/config.d.ts
CHANGED
package/dist/config.js
CHANGED
|
@@ -14,6 +14,15 @@ function parseTimeout(value) {
|
|
|
14
14
|
}
|
|
15
15
|
return timeoutMs;
|
|
16
16
|
}
|
|
17
|
+
function parseCacheTtl(value) {
|
|
18
|
+
if (value === undefined || value.trim() === "")
|
|
19
|
+
return undefined;
|
|
20
|
+
const cacheTtlMs = Number(value);
|
|
21
|
+
if (!Number.isInteger(cacheTtlMs) || cacheTtlMs < 0) {
|
|
22
|
+
throw new ConfigError("OAT_MCP_CACHE_TTL_MS must be a non-negative integer.");
|
|
23
|
+
}
|
|
24
|
+
return cacheTtlMs;
|
|
25
|
+
}
|
|
17
26
|
function parseUrl(value) {
|
|
18
27
|
try {
|
|
19
28
|
return new URL(value ?? DEFAULT_MCP_URL);
|
|
@@ -32,6 +41,7 @@ export function loadConfig(env = process.env) {
|
|
|
32
41
|
token,
|
|
33
42
|
debug: env.OAT_MCP_DEBUG === "1" || env.OAT_MCP_DEBUG === "true",
|
|
34
43
|
timeoutMs: parseTimeout(env.OAT_MCP_TIMEOUT_MS),
|
|
44
|
+
cacheTtlMs: parseCacheTtl(env.OAT_MCP_CACHE_TTL_MS),
|
|
35
45
|
protocolVersion: MCP_PROTOCOL_VERSION,
|
|
36
46
|
userAgent: `${PACKAGE_NAME}/${PACKAGE_VERSION}`,
|
|
37
47
|
};
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,oBAAoB,EACpB,YAAY,EACZ,eAAe,GAChB,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,oBAAoB,EACpB,YAAY,EACZ,eAAe,GAChB,MAAM,gBAAgB,CAAC;AAYxB,MAAM,OAAO,WAAY,SAAQ,KAAK;IACpC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;CACF;AAED,SAAS,YAAY,CAAC,KAAyB;IAC7C,IAAI,CAAC,KAAK;QAAE,OAAO,kBAAkB,CAAC;IAEtC,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAChC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;QACnD,MAAM,IAAI,WAAW,CAAC,gDAAgD,CAAC,CAAC;IAC1E,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,aAAa,CAAC,KAAyB;IAC9C,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,SAAS,CAAC;IAEjE,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IACjC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;QACpD,MAAM,IAAI,WAAW,CACnB,sDAAsD,CACvD,CAAC;IACJ,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAS,QAAQ,CAAC,KAAyB;IACzC,IAAI,CAAC;QACH,OAAO,IAAI,GAAG,CAAC,KAAK,IAAI,eAAe,CAAC,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,WAAW,CAAC,kCAAkC,CAAC,CAAC;IAC5D,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CACxB,MAA0C,OAAO,CAAC,GAAG;IAErD,MAAM,KAAK,GAAG,GAAG,CAAC,aAAa,EAAE,IAAI,EAAE,CAAC;IACxC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,WAAW,CAAC,4BAA4B,CAAC,CAAC;IACtD,CAAC;IAED,OAAO;QACL,GAAG,EAAE,QAAQ,CAAC,GAAG,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;QACnD,KAAK;QACL,KAAK,EAAE,GAAG,CAAC,aAAa,KAAK,GAAG,IAAI,GAAG,CAAC,aAAa,KAAK,MAAM;QAChE,SAAS,EAAE,YAAY,CAAC,GAAG,CAAC,kBAAkB,CAAC;QAC/C,UAAU,EAAE,aAAa,CAAC,GAAG,CAAC,oBAAoB,CAAC;QACnD,eAAe,EAAE,oBAAoB;QACrC,SAAS,EAAE,GAAG,YAAY,IAAI,eAAe,EAAE;KAChD,CAAC;AACJ,CAAC"}
|
package/dist/constants.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare const PACKAGE_NAME = "@oat-app/mcp-bridge";
|
|
2
|
-
export declare const PACKAGE_VERSION = "0.
|
|
2
|
+
export declare const PACKAGE_VERSION = "0.2.0";
|
|
3
3
|
export declare const DEFAULT_MCP_URL = "https://oat-blond.vercel.app/api/mcp";
|
|
4
4
|
export declare const MCP_PROTOCOL_VERSION = "2025-06-18";
|
|
5
5
|
export declare const DEFAULT_TIMEOUT_MS = 30000;
|
package/dist/constants.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export const PACKAGE_NAME = "@oat-app/mcp-bridge";
|
|
2
|
-
export const PACKAGE_VERSION = "0.
|
|
2
|
+
export const PACKAGE_VERSION = "0.2.0";
|
|
3
3
|
export const DEFAULT_MCP_URL = "https://oat-blond.vercel.app/api/mcp";
|
|
4
4
|
export const MCP_PROTOCOL_VERSION = "2025-06-18";
|
|
5
5
|
export const DEFAULT_TIMEOUT_MS = 30_000;
|
package/dist/index.js
CHANGED
|
@@ -14,6 +14,7 @@ Environment:
|
|
|
14
14
|
OAT_MCP_URL Optional endpoint override.
|
|
15
15
|
OAT_MCP_DEBUG Set to 1 for stderr debug logs.
|
|
16
16
|
OAT_MCP_TIMEOUT_MS Optional request timeout in milliseconds.
|
|
17
|
+
OAT_MCP_CACHE_TTL_MS Optional low-risk tool cache TTL. Set 0 to disable.
|
|
17
18
|
`);
|
|
18
19
|
}
|
|
19
20
|
async function main() {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,SAAS,SAAS;IAChB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,YAAY,IAAI,eAAe;;;WAG9C,YAAY
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,SAAS,SAAS;IAChB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,YAAY,IAAI,eAAe;;;WAG9C,YAAY;;;;;;;;CAQtB,CAAC,CAAC;AACH,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAEpC,IAAI,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QACrC,SAAS,EAAE,CAAC;QACZ,OAAO;IACT,CAAC;IAED,IAAI,GAAG,KAAK,WAAW,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QACxC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,eAAe,IAAI,CAAC,CAAC;QAC7C,OAAO;IACT,CAAC;IAED,IAAI,GAAG,EAAE,CAAC;QACR,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAAC;QACnD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC1C,MAAM,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAClC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;IAC9B,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,oBAAoB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAC/E,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
export declare const BRIDGE_TOOL_DEFINITIONS: readonly [{
|
|
2
|
+
readonly name: "get_context";
|
|
3
|
+
readonly description: "현재 oat MCP 연결의 사용자, 가구, 권한, privacy 모델을 조회합니다. 일반적으로 캐시된 값을 사용합니다. 사용자가 방금 MCP 토큰, 가구, 프로필 정보를 변경했고 최신값 확인을 명시한 경우에만 forceRefresh를 true로 설정하세요.";
|
|
4
|
+
readonly inputSchema: {
|
|
5
|
+
readonly type: "object";
|
|
6
|
+
readonly properties: {
|
|
7
|
+
readonly forceRefresh: {
|
|
8
|
+
readonly type: "boolean";
|
|
9
|
+
readonly description: "캐시를 우회해 최신 연결 컨텍스트를 조회합니다. 자동 재시도, polling, 일반 호출에는 사용하지 말고, 사용자가 방금 변경한 값을 다시 확인하라고 요청한 경우에만 true로 설정하세요.";
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
readonly additionalProperties: false;
|
|
13
|
+
};
|
|
14
|
+
}, {
|
|
15
|
+
readonly name: "get_financial_overview";
|
|
16
|
+
readonly description: "이번 달 공용/토큰 소유자 개인 현금흐름과 현재 자산/주식 요약을 함께 조회합니다. 두 현금흐름은 합산하지 않습니다.";
|
|
17
|
+
readonly inputSchema: {
|
|
18
|
+
readonly type: "object";
|
|
19
|
+
readonly properties: {
|
|
20
|
+
readonly from: {
|
|
21
|
+
readonly type: "string";
|
|
22
|
+
readonly description: "YYYY-MM-DD";
|
|
23
|
+
};
|
|
24
|
+
readonly to: {
|
|
25
|
+
readonly type: "string";
|
|
26
|
+
readonly description: "YYYY-MM-DD";
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
readonly additionalProperties: false;
|
|
30
|
+
};
|
|
31
|
+
}, {
|
|
32
|
+
readonly name: "list_references";
|
|
33
|
+
readonly description: "가구원, 카테고리, 계좌, 결제수단 참조 목록을 조회합니다. 일반적으로 캐시된 값을 사용합니다. 사용자가 방금 설정/참조 데이터를 변경했고 최신값 확인을 명시한 경우에만 forceRefresh를 true로 설정하세요.";
|
|
34
|
+
readonly inputSchema: {
|
|
35
|
+
readonly type: "object";
|
|
36
|
+
readonly properties: {
|
|
37
|
+
readonly forceRefresh: {
|
|
38
|
+
readonly type: "boolean";
|
|
39
|
+
readonly description: "캐시를 우회해 최신 참조 데이터를 조회합니다. 자동 재시도, polling, 일반 호출에는 사용하지 말고, 사용자가 방금 변경한 값을 다시 확인하라고 요청한 경우에만 true로 설정하세요.";
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
readonly additionalProperties: false;
|
|
43
|
+
};
|
|
44
|
+
}, {
|
|
45
|
+
readonly name: "get_money_endpoint_detail";
|
|
46
|
+
readonly description: "계좌 또는 결제수단의 현재 잔액과 최근 변동 내역을 조회합니다. timeline에는 가계부 기록, 잔액 조정, 계좌의 경우 주식 거래가 포함될 수 있습니다. 상세 사용자 데이터이므로 일반 연결 확인이나 반복 polling에는 사용하지 마세요.";
|
|
47
|
+
readonly inputSchema: {
|
|
48
|
+
readonly type: "object";
|
|
49
|
+
readonly properties: {
|
|
50
|
+
readonly endpointType: {
|
|
51
|
+
readonly type: "string";
|
|
52
|
+
readonly enum: readonly ["account", "paymentMethod"];
|
|
53
|
+
readonly description: "조회할 Money Endpoint 유형";
|
|
54
|
+
};
|
|
55
|
+
readonly endpointId: {
|
|
56
|
+
readonly type: "string";
|
|
57
|
+
readonly description: "조회할 계좌 또는 결제수단 ID";
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
readonly required: readonly ["endpointType", "endpointId"];
|
|
61
|
+
readonly additionalProperties: false;
|
|
62
|
+
};
|
|
63
|
+
}, {
|
|
64
|
+
readonly name: "search_ledger_entries";
|
|
65
|
+
readonly description: "가계부 상세 내역을 조회합니다. source/destination은 account 또는 paymentMethod 기반 Money Endpoint이며, 파트너 개인 지출 상세는 제외됩니다.";
|
|
66
|
+
readonly inputSchema: {
|
|
67
|
+
readonly type: "object";
|
|
68
|
+
readonly properties: {
|
|
69
|
+
readonly from: {
|
|
70
|
+
readonly type: "string";
|
|
71
|
+
readonly description: "YYYY-MM-DD";
|
|
72
|
+
};
|
|
73
|
+
readonly to: {
|
|
74
|
+
readonly type: "string";
|
|
75
|
+
readonly description: "YYYY-MM-DD";
|
|
76
|
+
};
|
|
77
|
+
readonly query: {
|
|
78
|
+
readonly type: "string";
|
|
79
|
+
};
|
|
80
|
+
readonly types: {
|
|
81
|
+
readonly type: "array";
|
|
82
|
+
readonly items: {
|
|
83
|
+
readonly type: "string";
|
|
84
|
+
readonly enum: readonly ["expense", "income", "transfer"];
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
readonly categoryIds: {
|
|
88
|
+
readonly type: "array";
|
|
89
|
+
readonly items: {
|
|
90
|
+
readonly type: "string";
|
|
91
|
+
};
|
|
92
|
+
};
|
|
93
|
+
readonly endpointIds: {
|
|
94
|
+
readonly type: "array";
|
|
95
|
+
readonly items: {
|
|
96
|
+
readonly type: "string";
|
|
97
|
+
};
|
|
98
|
+
};
|
|
99
|
+
readonly endpointTypes: {
|
|
100
|
+
readonly type: "array";
|
|
101
|
+
readonly items: {
|
|
102
|
+
readonly type: "string";
|
|
103
|
+
readonly enum: readonly ["account", "paymentMethod"];
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
readonly ownerIds: {
|
|
107
|
+
readonly type: "array";
|
|
108
|
+
readonly items: {
|
|
109
|
+
readonly type: "string";
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
readonly isShared: {
|
|
113
|
+
readonly type: "boolean";
|
|
114
|
+
};
|
|
115
|
+
readonly limit: {
|
|
116
|
+
readonly type: "number";
|
|
117
|
+
readonly minimum: 1;
|
|
118
|
+
readonly maximum: 100;
|
|
119
|
+
};
|
|
120
|
+
};
|
|
121
|
+
readonly additionalProperties: false;
|
|
122
|
+
};
|
|
123
|
+
}, {
|
|
124
|
+
readonly name: "get_ledger_stats";
|
|
125
|
+
readonly description: "가계부 요약, 멤버별, 카테고리별, Money Endpoint별 집계를 조회합니다. 현금흐름 summary는 공용/토큰 소유자 개인 장부를 분리하고 이체를 제외합니다.";
|
|
126
|
+
readonly inputSchema: {
|
|
127
|
+
readonly type: "object";
|
|
128
|
+
readonly properties: {
|
|
129
|
+
readonly year: {
|
|
130
|
+
readonly type: "number";
|
|
131
|
+
};
|
|
132
|
+
readonly month: {
|
|
133
|
+
readonly type: "number";
|
|
134
|
+
};
|
|
135
|
+
readonly months: {
|
|
136
|
+
readonly type: "number";
|
|
137
|
+
readonly minimum: 1;
|
|
138
|
+
readonly maximum: 12;
|
|
139
|
+
};
|
|
140
|
+
};
|
|
141
|
+
readonly additionalProperties: false;
|
|
142
|
+
};
|
|
143
|
+
}, {
|
|
144
|
+
readonly name: "get_asset_snapshot";
|
|
145
|
+
readonly description: "총자산, 주식 보유, 자산 배분과 수익률 snapshot을 조회합니다.";
|
|
146
|
+
readonly inputSchema: {
|
|
147
|
+
readonly type: "object";
|
|
148
|
+
readonly properties: {
|
|
149
|
+
readonly includeHoldings: {
|
|
150
|
+
readonly type: "boolean";
|
|
151
|
+
};
|
|
152
|
+
readonly includeAllocation: {
|
|
153
|
+
readonly type: "boolean";
|
|
154
|
+
};
|
|
155
|
+
};
|
|
156
|
+
readonly additionalProperties: false;
|
|
157
|
+
};
|
|
158
|
+
}];
|
package/dist/manifest.js
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
export const BRIDGE_TOOL_DEFINITIONS = [
|
|
2
|
+
{
|
|
3
|
+
name: "get_context",
|
|
4
|
+
description: "현재 oat MCP 연결의 사용자, 가구, 권한, privacy 모델을 조회합니다. 일반적으로 캐시된 값을 사용합니다. 사용자가 방금 MCP 토큰, 가구, 프로필 정보를 변경했고 최신값 확인을 명시한 경우에만 forceRefresh를 true로 설정하세요.",
|
|
5
|
+
inputSchema: {
|
|
6
|
+
type: "object",
|
|
7
|
+
properties: {
|
|
8
|
+
forceRefresh: {
|
|
9
|
+
type: "boolean",
|
|
10
|
+
description: "캐시를 우회해 최신 연결 컨텍스트를 조회합니다. 자동 재시도, polling, 일반 호출에는 사용하지 말고, 사용자가 방금 변경한 값을 다시 확인하라고 요청한 경우에만 true로 설정하세요.",
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
additionalProperties: false,
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
name: "get_financial_overview",
|
|
18
|
+
description: "이번 달 공용/토큰 소유자 개인 현금흐름과 현재 자산/주식 요약을 함께 조회합니다. 두 현금흐름은 합산하지 않습니다.",
|
|
19
|
+
inputSchema: {
|
|
20
|
+
type: "object",
|
|
21
|
+
properties: {
|
|
22
|
+
from: { type: "string", description: "YYYY-MM-DD" },
|
|
23
|
+
to: { type: "string", description: "YYYY-MM-DD" },
|
|
24
|
+
},
|
|
25
|
+
additionalProperties: false,
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
name: "list_references",
|
|
30
|
+
description: "가구원, 카테고리, 계좌, 결제수단 참조 목록을 조회합니다. 일반적으로 캐시된 값을 사용합니다. 사용자가 방금 설정/참조 데이터를 변경했고 최신값 확인을 명시한 경우에만 forceRefresh를 true로 설정하세요.",
|
|
31
|
+
inputSchema: {
|
|
32
|
+
type: "object",
|
|
33
|
+
properties: {
|
|
34
|
+
forceRefresh: {
|
|
35
|
+
type: "boolean",
|
|
36
|
+
description: "캐시를 우회해 최신 참조 데이터를 조회합니다. 자동 재시도, polling, 일반 호출에는 사용하지 말고, 사용자가 방금 변경한 값을 다시 확인하라고 요청한 경우에만 true로 설정하세요.",
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
additionalProperties: false,
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: "get_money_endpoint_detail",
|
|
44
|
+
description: "계좌 또는 결제수단의 현재 잔액과 최근 변동 내역을 조회합니다. timeline에는 가계부 기록, 잔액 조정, 계좌의 경우 주식 거래가 포함될 수 있습니다. 상세 사용자 데이터이므로 일반 연결 확인이나 반복 polling에는 사용하지 마세요.",
|
|
45
|
+
inputSchema: {
|
|
46
|
+
type: "object",
|
|
47
|
+
properties: {
|
|
48
|
+
endpointType: {
|
|
49
|
+
type: "string",
|
|
50
|
+
enum: ["account", "paymentMethod"],
|
|
51
|
+
description: "조회할 Money Endpoint 유형",
|
|
52
|
+
},
|
|
53
|
+
endpointId: {
|
|
54
|
+
type: "string",
|
|
55
|
+
description: "조회할 계좌 또는 결제수단 ID",
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
required: ["endpointType", "endpointId"],
|
|
59
|
+
additionalProperties: false,
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
name: "search_ledger_entries",
|
|
64
|
+
description: "가계부 상세 내역을 조회합니다. source/destination은 account 또는 paymentMethod 기반 Money Endpoint이며, 파트너 개인 지출 상세는 제외됩니다.",
|
|
65
|
+
inputSchema: {
|
|
66
|
+
type: "object",
|
|
67
|
+
properties: {
|
|
68
|
+
from: { type: "string", description: "YYYY-MM-DD" },
|
|
69
|
+
to: { type: "string", description: "YYYY-MM-DD" },
|
|
70
|
+
query: { type: "string" },
|
|
71
|
+
types: {
|
|
72
|
+
type: "array",
|
|
73
|
+
items: { type: "string", enum: ["expense", "income", "transfer"] },
|
|
74
|
+
},
|
|
75
|
+
categoryIds: { type: "array", items: { type: "string" } },
|
|
76
|
+
endpointIds: { type: "array", items: { type: "string" } },
|
|
77
|
+
endpointTypes: {
|
|
78
|
+
type: "array",
|
|
79
|
+
items: { type: "string", enum: ["account", "paymentMethod"] },
|
|
80
|
+
},
|
|
81
|
+
ownerIds: { type: "array", items: { type: "string" } },
|
|
82
|
+
isShared: { type: "boolean" },
|
|
83
|
+
limit: { type: "number", minimum: 1, maximum: 100 },
|
|
84
|
+
},
|
|
85
|
+
additionalProperties: false,
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
name: "get_ledger_stats",
|
|
90
|
+
description: "가계부 요약, 멤버별, 카테고리별, Money Endpoint별 집계를 조회합니다. 현금흐름 summary는 공용/토큰 소유자 개인 장부를 분리하고 이체를 제외합니다.",
|
|
91
|
+
inputSchema: {
|
|
92
|
+
type: "object",
|
|
93
|
+
properties: {
|
|
94
|
+
year: { type: "number" },
|
|
95
|
+
month: { type: "number" },
|
|
96
|
+
months: { type: "number", minimum: 1, maximum: 12 },
|
|
97
|
+
},
|
|
98
|
+
additionalProperties: false,
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
name: "get_asset_snapshot",
|
|
103
|
+
description: "총자산, 주식 보유, 자산 배분과 수익률 snapshot을 조회합니다.",
|
|
104
|
+
inputSchema: {
|
|
105
|
+
type: "object",
|
|
106
|
+
properties: {
|
|
107
|
+
includeHoldings: { type: "boolean" },
|
|
108
|
+
includeAllocation: { type: "boolean" },
|
|
109
|
+
},
|
|
110
|
+
additionalProperties: false,
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
];
|
|
114
|
+
//# sourceMappingURL=manifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"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"}
|