@intentface/latch-mcp 0.13.0 → 0.13.2
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/dist/oauth-fetch.d.ts +3 -1
- package/dist/oauth-fetch.d.ts.map +1 -1
- package/dist/oauth-fetch.js +7 -2
- package/dist/oauth-fetch.js.map +1 -1
- package/dist/oauth-fetch.test.d.ts +2 -0
- package/dist/oauth-fetch.test.d.ts.map +1 -0
- package/dist/oauth-fetch.test.js +25 -0
- package/dist/oauth-fetch.test.js.map +1 -0
- package/package.json +3 -3
package/dist/oauth-fetch.d.ts
CHANGED
|
@@ -32,7 +32,9 @@ export interface OAuthDiscoveryFetchOptions {
|
|
|
32
32
|
* Force this scheme on the URLs inside discovery documents (issuer,
|
|
33
33
|
* authorization/token/registration endpoints, advertised resource and
|
|
34
34
|
* authorization servers). Use `"https"` for the common proxied-http case.
|
|
35
|
-
* Omit to leave schemes as published.
|
|
35
|
+
* Omit to leave schemes as published. Never applied to loopback hosts
|
|
36
|
+
* (`localhost`, `127.0.0.1`, `[::1]`): no TLS proxy fronts those, and
|
|
37
|
+
* forcing https on a local http server breaks the SDK's resource check.
|
|
36
38
|
*/
|
|
37
39
|
forceScheme?: "https" | "http";
|
|
38
40
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth-fetch.d.ts","sourceRoot":"","sources":["../src/oauth-fetch.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,CAC1B,KAAK,EAAE,WAAW,GAAG,GAAG,EACxB,IAAI,CAAC,EAAE,WAAW,KACf,OAAO,CAAC,QAAQ,CAAC,CAAC;AAEvB;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,0BAA0B;IACzC,qDAAqD;IACrD,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B
|
|
1
|
+
{"version":3,"file":"oauth-fetch.d.ts","sourceRoot":"","sources":["../src/oauth-fetch.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,CAC1B,KAAK,EAAE,WAAW,GAAG,GAAG,EACxB,IAAI,CAAC,EAAE,WAAW,KACf,OAAO,CAAC,QAAQ,CAAC,CAAC;AAEvB;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,0BAA0B;IACzC,qDAAqD;IACrD,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC/B;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AAwED,wBAAgB,yBAAyB,CACvC,OAAO,GAAE,0BAA+B,GACvC,aAAa,CAqDf"}
|
package/dist/oauth-fetch.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/** No TLS-terminating proxy sits in front of these, so their schemes are left as published. */
|
|
2
|
+
const LOOPBACK = new Set(["localhost", "127.0.0.1", "[::1]"]);
|
|
1
3
|
/** Well-known suffixes for the two discovery document kinds we touch. */
|
|
2
4
|
const PROTECTED_RESOURCE = "oauth-protected-resource";
|
|
3
5
|
const AUTH_SERVER = "oauth-authorization-server";
|
|
@@ -90,9 +92,12 @@ export function createOAuthDiscoveryFetch(options = {}) {
|
|
|
90
92
|
}
|
|
91
93
|
if (typeof doc !== "object" || doc === null)
|
|
92
94
|
return response;
|
|
95
|
+
// Trailing-slash cleanup applies everywhere; the forced scheme does not
|
|
96
|
+
// reach a local server, whose http address is exactly what it serves.
|
|
97
|
+
const scheme = LOOPBACK.has(url.hostname.toLowerCase()) ? undefined : options.forceScheme;
|
|
93
98
|
const normalized = isProtectedResource
|
|
94
|
-
? normalizeProtectedResource(doc,
|
|
95
|
-
: normalizeAuthorizationServer(doc,
|
|
99
|
+
? normalizeProtectedResource(doc, scheme)
|
|
100
|
+
: normalizeAuthorizationServer(doc, scheme);
|
|
96
101
|
// Preserve status/headers; replace only the body.
|
|
97
102
|
const headers = new Headers(response.headers);
|
|
98
103
|
headers.delete("content-length");
|
package/dist/oauth-fetch.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth-fetch.js","sourceRoot":"","sources":["../src/oauth-fetch.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"oauth-fetch.js","sourceRoot":"","sources":["../src/oauth-fetch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-fetch.test.d.ts","sourceRoot":"","sources":["../src/oauth-fetch.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { createOAuthDiscoveryFetch } from "./oauth-fetch.js";
|
|
3
|
+
/** A fetch that serves one discovery document for every URL. */
|
|
4
|
+
const serving = (doc) => async () => new Response(JSON.stringify(doc), { status: 200, headers: { "content-type": "application/json" } });
|
|
5
|
+
describe("createOAuthDiscoveryFetch", () => {
|
|
6
|
+
it("forces https on a proxied server's discovery, and strips the issuer's trailing slash", async () => {
|
|
7
|
+
const f = createOAuthDiscoveryFetch({
|
|
8
|
+
forceScheme: "https",
|
|
9
|
+
baseFetch: serving({ issuer: "http://mcp.example.com/", token_endpoint: "http://mcp.example.com/token" }),
|
|
10
|
+
});
|
|
11
|
+
const doc = await (await f("https://mcp.example.com/.well-known/oauth-authorization-server")).json();
|
|
12
|
+
expect(doc).toMatchObject({ issuer: "https://mcp.example.com", token_endpoint: "https://mcp.example.com/token" });
|
|
13
|
+
});
|
|
14
|
+
it.each(["localhost", "127.0.0.1", "[::1]"])("leaves a local server's http scheme alone (%s)", async (host) => {
|
|
15
|
+
const f = createOAuthDiscoveryFetch({
|
|
16
|
+
forceScheme: "https",
|
|
17
|
+
baseFetch: serving({ resource: `http://${host}:3011/mcp`, authorization_servers: [`http://${host}:3011/api/auth/`] }),
|
|
18
|
+
});
|
|
19
|
+
const doc = await (await f(`http://${host}:3011/.well-known/oauth-protected-resource/mcp`)).json();
|
|
20
|
+
// The SDK compares `resource` with the URL it connected to; https here broke every local server.
|
|
21
|
+
expect(doc.resource).toBe(`http://${host}:3011/mcp`);
|
|
22
|
+
expect(doc.authorization_servers[0]).toMatch(/^http:\/\//);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
//# sourceMappingURL=oauth-fetch.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-fetch.test.js","sourceRoot":"","sources":["../src/oauth-fetch.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAE7D,gEAAgE;AAChE,MAAM,OAAO,GAAG,CAAC,GAAY,EAAE,EAAE,CAAC,KAAK,IAAI,EAAE,CAC3C,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,EAAE,CAAC,CAAC;AAEtG,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;IACzC,EAAE,CAAC,sFAAsF,EAAE,KAAK,IAAI,EAAE;QACpG,MAAM,CAAC,GAAG,yBAAyB,CAAC;YAClC,WAAW,EAAE,OAAO;YACpB,SAAS,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,yBAAyB,EAAE,cAAc,EAAE,8BAA8B,EAAE,CAAC;SAC1G,CAAC,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,gEAAgE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACrG,MAAM,CAAC,GAAG,CAAC,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,yBAAyB,EAAE,cAAc,EAAE,+BAA+B,EAAE,CAAC,CAAC;IACpH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC,gDAAgD,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QAC5G,MAAM,CAAC,GAAG,yBAAyB,CAAC;YAClC,WAAW,EAAE,OAAO;YACpB,SAAS,EAAE,OAAO,CAAC,EAAE,QAAQ,EAAE,UAAU,IAAI,WAAW,EAAE,qBAAqB,EAAE,CAAC,UAAU,IAAI,iBAAiB,CAAC,EAAE,CAAC;SACtH,CAAC,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,UAAU,IAAI,gDAAgD,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACnG,iGAAiG;QACjG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,UAAU,IAAI,WAAW,CAAC,CAAC;QACrD,MAAM,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intentface/latch-mcp",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.2",
|
|
4
4
|
"description": "Latch MCP host — connect to MCP servers as tools, with a per-tenant SSRF allowlist and vault-brokered auth.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
"registry": "https://registry.npmjs.org"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@intentface/latch-core": "^0.13.
|
|
35
|
-
"@intentface/latch-net": "^0.13.
|
|
34
|
+
"@intentface/latch-core": "^0.13.2",
|
|
35
|
+
"@intentface/latch-net": "^0.13.2"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"@ai-sdk/mcp": ">=2.0.0",
|