@aauth/proxy 0.1.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.
Files changed (54) hide show
  1. package/README.md +75 -0
  2. package/dist/agent.d.ts +37 -0
  3. package/dist/agent.d.ts.map +1 -0
  4. package/dist/agent.js +220 -0
  5. package/dist/agent.js.map +1 -0
  6. package/dist/host.d.ts +6 -0
  7. package/dist/host.d.ts.map +1 -0
  8. package/dist/host.js +27 -0
  9. package/dist/host.js.map +1 -0
  10. package/dist/identity-local.d.ts +10 -0
  11. package/dist/identity-local.d.ts.map +1 -0
  12. package/dist/identity-local.js +70 -0
  13. package/dist/identity-local.js.map +1 -0
  14. package/dist/identity.d.ts +13 -0
  15. package/dist/identity.d.ts.map +1 -0
  16. package/dist/identity.js +11 -0
  17. package/dist/identity.js.map +1 -0
  18. package/dist/index.d.ts +15 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +13 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/registry.d.ts +34 -0
  23. package/dist/registry.d.ts.map +1 -0
  24. package/dist/registry.js +60 -0
  25. package/dist/registry.js.map +1 -0
  26. package/dist/resource.d.ts +38 -0
  27. package/dist/resource.d.ts.map +1 -0
  28. package/dist/resource.js +159 -0
  29. package/dist/resource.js.map +1 -0
  30. package/dist/server.d.ts +3 -0
  31. package/dist/server.d.ts.map +1 -0
  32. package/dist/server.js +119 -0
  33. package/dist/server.js.map +1 -0
  34. package/dist/store.d.ts +28 -0
  35. package/dist/store.d.ts.map +1 -0
  36. package/dist/store.js +64 -0
  37. package/dist/store.js.map +1 -0
  38. package/dist/tools.d.ts +28 -0
  39. package/dist/tools.d.ts.map +1 -0
  40. package/dist/tools.js +253 -0
  41. package/dist/tools.js.map +1 -0
  42. package/dist/vocab/index.d.ts +6 -0
  43. package/dist/vocab/index.d.ts.map +1 -0
  44. package/dist/vocab/index.js +19 -0
  45. package/dist/vocab/index.js.map +1 -0
  46. package/dist/vocab/openapi.d.ts +43 -0
  47. package/dist/vocab/openapi.d.ts.map +1 -0
  48. package/dist/vocab/openapi.js +113 -0
  49. package/dist/vocab/openapi.js.map +1 -0
  50. package/dist/vocab/types.d.ts +47 -0
  51. package/dist/vocab/types.d.ts.map +1 -0
  52. package/dist/vocab/types.js +11 -0
  53. package/dist/vocab/types.js.map +1 -0
  54. package/package.json +59 -0
@@ -0,0 +1,60 @@
1
+ // Registry client: signed GET registry.aauth.dev/resources with ETag cache.
2
+ //
3
+ // The registry is an AAuth resource itself (access_mode: agent-token), so
4
+ // listing requires the agent proxy's agent token + HTTP signature — the same path used
5
+ // for any other agent-token resource. The ETag cache is injected via
6
+ // RegistryCache; the stdio server uses the filesystem default
7
+ // (createFsRegistryCache), backed by ~/.aauth/proxy/catalog/registry.json.
8
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
9
+ import { homedir } from 'node:os';
10
+ import { dirname, join } from 'node:path';
11
+ import { fetch as signedFetch } from '@hellocoop/httpsig';
12
+ export function registryUrl() {
13
+ return (process.env.PROXY_REGISTRY_URL ?? 'https://registry.aauth.dev').replace(/\/+$/, '');
14
+ }
15
+ // Filesystem-backed RegistryCache — the default for the stdio server. `dir`
16
+ // overrides the state directory (default ~/.aauth/proxy).
17
+ export function createFsRegistryCache(opts = {}) {
18
+ const cachePath = join(opts.dir ?? join(homedir(), '.aauth', 'proxy'), 'catalog', 'registry.json');
19
+ return {
20
+ async read() {
21
+ if (!existsSync(cachePath))
22
+ return undefined;
23
+ try {
24
+ return JSON.parse(readFileSync(cachePath, 'utf8'));
25
+ }
26
+ catch {
27
+ return undefined;
28
+ }
29
+ },
30
+ async write(c) {
31
+ mkdirSync(dirname(cachePath), { recursive: true });
32
+ writeFileSync(cachePath, JSON.stringify(c, null, 2));
33
+ },
34
+ };
35
+ }
36
+ // Fetch the registry's /resources, signed with the agent token. Honors
37
+ // If-None-Match against the cached ETag — on 304 returns the cached index;
38
+ // on 200 updates the cache.
39
+ export async function fetchRegistry(cfg, cache) {
40
+ const url = `${registryUrl()}/resources`;
41
+ const cached = await cache.read();
42
+ const headers = { accept: 'application/json' };
43
+ if (cached?.etag)
44
+ headers['if-none-match'] = cached.etag;
45
+ const res = await signedFetch(url, {
46
+ method: 'GET',
47
+ headers,
48
+ signingKey: cfg.agentPrivateJwk,
49
+ signatureKey: { type: 'jwt', jwt: cfg.agentToken },
50
+ });
51
+ if (res.status === 304 && cached)
52
+ return cached.index;
53
+ if (!res.ok)
54
+ throw new Error(`registry ${url}: ${res.status}`);
55
+ const index = (await res.json());
56
+ const etag = res.headers.get('etag') ?? undefined;
57
+ await cache.write({ ...(etag ? { etag } : {}), fetched: new Date().toISOString(), index });
58
+ return index;
59
+ }
60
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import type { AccessMode, L1Entry } from './store.js';
2
+ import type { InvocationPlan, InvokeArgs, OpDetail, OpSummary, VocabAdapter } from './vocab/index.js';
3
+ export interface AAuthResourceMeta {
4
+ issuer: string;
5
+ client_name?: string;
6
+ description?: string;
7
+ access_mode?: AccessMode;
8
+ logo_uri?: string;
9
+ authorization_endpoint?: string;
10
+ r3_vocabularies?: Record<string, string>;
11
+ jwks_uri?: string;
12
+ }
13
+ export interface PickedVocab {
14
+ vocabUri: string;
15
+ docUrl: string;
16
+ adapter: VocabAdapter;
17
+ }
18
+ export interface FetchedResource {
19
+ host: string;
20
+ origin: string;
21
+ meta: AAuthResourceMeta;
22
+ pickedVocabs: PickedVocab[];
23
+ }
24
+ export declare function fetchResource(hostOrUrl: string): Promise<FetchedResource>;
25
+ export interface DocCache {
26
+ get(key: string): Promise<unknown | undefined>;
27
+ set(key: string, doc: unknown): Promise<void>;
28
+ }
29
+ export declare function createMemoryDocCache(): DocCache;
30
+ export declare function listOperationsForResource(l1: L1Entry, query?: string, docCache?: DocCache): Promise<OpSummary[]>;
31
+ export declare function getOperationsForResource(l1: L1Entry, opIds: string[], docCache?: DocCache): Promise<OpDetail[]>;
32
+ export interface RoutedOperation {
33
+ adapter: VocabAdapter;
34
+ plan: InvocationPlan;
35
+ }
36
+ export declare function routeOperation(l1: L1Entry, opId: string, args: InvokeArgs, docCache?: DocCache): Promise<RoutedOperation>;
37
+ export declare function toL1Entry(r: FetchedResource): L1Entry;
38
+ //# sourceMappingURL=resource.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource.d.ts","sourceRoot":"","sources":["../src/resource.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AACrD,OAAO,KAAK,EACV,cAAc,EACd,UAAU,EACV,QAAQ,EACR,SAAS,EACT,YAAY,EACb,MAAM,kBAAkB,CAAA;AAEzB,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,WAAW,CAAC,EAAE,UAAU,CAAA;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAC/B,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,YAAY,CAAA;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,iBAAiB,CAAA;IACvB,YAAY,EAAE,WAAW,EAAE,CAAA;CAC5B;AAED,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAwB/E;AAuCD,MAAM,WAAW,QAAQ;IACvB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,CAAA;IAC9C,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAC9C;AAED,wBAAgB,oBAAoB,IAAI,QAAQ,CAU/C;AA+BD,wBAAsB,yBAAyB,CAC7C,EAAE,EAAE,OAAO,EACX,KAAK,CAAC,EAAE,MAAM,EACd,QAAQ,GAAE,QAA0B,GACnC,OAAO,CAAC,SAAS,EAAE,CAAC,CAStB;AAED,wBAAsB,wBAAwB,CAC5C,EAAE,EAAE,OAAO,EACX,KAAK,EAAE,MAAM,EAAE,EACf,QAAQ,GAAE,QAA0B,GACnC,OAAO,CAAC,QAAQ,EAAE,CAAC,CASrB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,YAAY,CAAA;IACrB,IAAI,EAAE,cAAc,CAAA;CACrB;AAMD,wBAAsB,cAAc,CAClC,EAAE,EAAE,OAAO,EACX,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,EAChB,QAAQ,GAAE,QAA0B,GACnC,OAAO,CAAC,eAAe,CAAC,CAW1B;AAQD,wBAAgB,SAAS,CAAC,CAAC,EAAE,eAAe,GAAG,OAAO,CAiBrD"}
@@ -0,0 +1,159 @@
1
+ // Fetch + validate a resource's well-known doc; pick vocabulary adapters
2
+ // the agent proxy supports. The caller (add_resource) decides what to do with the
3
+ // FetchedResource — typically convert to an L1Entry and store.
4
+ //
5
+ // Mirrors registry/validate.ts:fetchResourceMetadata in spirit: manual
6
+ // redirect, basic shape validation, issuer === origin anti-spoof. The SSRF
7
+ // guards the registry applies (no localhost, no IPs, no non-default ports)
8
+ // are not enforced here because the agent proxy runs on the user's machine, and the
9
+ // user explicitly typed the host they want to add.
10
+ import { canonicalizeHost } from './host.js';
11
+ import { getAdapter, supportedVocabUris } from './vocab/index.js';
12
+ export async function fetchResource(hostOrUrl) {
13
+ const canonical = canonicalizeHost(hostOrUrl);
14
+ if (!canonical)
15
+ throw new Error(`invalid host: ${hostOrUrl}`);
16
+ const { host, origin } = canonical;
17
+ const url = `${origin}/.well-known/aauth-resource.json`;
18
+ const res = await fetch(url, {
19
+ redirect: 'manual',
20
+ headers: { accept: 'application/json' },
21
+ });
22
+ if (res.status >= 300 && res.status < 400) {
23
+ throw new Error(`resource ${host}: unexpected redirect`);
24
+ }
25
+ if (!res.ok)
26
+ throw new Error(`resource ${host}: well-known ${res.status}`);
27
+ const meta = (await res.json());
28
+ validate(meta, host, origin);
29
+ return {
30
+ host,
31
+ origin,
32
+ meta,
33
+ pickedVocabs: pickVocabs(meta.r3_vocabularies ?? {}),
34
+ };
35
+ }
36
+ function validate(meta, host, origin) {
37
+ if (!meta.issuer)
38
+ throw new Error(`resource ${host}: missing issuer`);
39
+ if (meta.issuer.replace(/\/+$/, '') !== origin) {
40
+ throw new Error(`resource ${host}: issuer mismatch (got ${meta.issuer}, expected ${origin})`);
41
+ }
42
+ if (meta.access_mode !== undefined &&
43
+ !['agent-token', 'aauth-access-token', 'auth-token'].includes(meta.access_mode)) {
44
+ throw new Error(`resource ${host}: invalid access_mode ${meta.access_mode}`);
45
+ }
46
+ // description is enforced at the registry on submit; agent-proxy-side is lenient
47
+ // so direct-URL adds of resources without a description still work.
48
+ }
49
+ function pickVocabs(advertised) {
50
+ const out = [];
51
+ for (const uri of supportedVocabUris()) {
52
+ const docUrl = advertised[uri];
53
+ if (!docUrl)
54
+ continue;
55
+ const adapter = getAdapter(uri);
56
+ if (!adapter)
57
+ continue;
58
+ out.push({ vocabUri: uri, docUrl, adapter });
59
+ }
60
+ return out;
61
+ }
62
+ export function createMemoryDocCache() {
63
+ const m = new Map();
64
+ return {
65
+ async get(key) {
66
+ return m.get(key);
67
+ },
68
+ async set(key, doc) {
69
+ m.set(key, doc);
70
+ },
71
+ };
72
+ }
73
+ // Process-wide default so callers that don't inject a cache (e.g. agent.ts's
74
+ // invoke path) still share one cache for the process lifetime — unchanged
75
+ // behavior from the previous module-level Map.
76
+ const defaultDocCache = createMemoryDocCache();
77
+ function cacheKey(host, vocabUri) {
78
+ return `${host}|${vocabUri}`;
79
+ }
80
+ async function loadDoc(host, vocab, cache) {
81
+ const key = cacheKey(host, vocab.vocabUri);
82
+ let doc = await cache.get(key);
83
+ if (doc === undefined) {
84
+ doc = await vocab.adapter.load(vocab.docUrl);
85
+ await cache.set(key, doc);
86
+ }
87
+ return doc;
88
+ }
89
+ function rehydrate(picked) {
90
+ const out = [];
91
+ for (const v of picked) {
92
+ const adapter = getAdapter(v.vocabUri);
93
+ if (!adapter)
94
+ continue;
95
+ out.push({ vocabUri: v.vocabUri, docUrl: v.docUrl, adapter });
96
+ }
97
+ return out;
98
+ }
99
+ export async function listOperationsForResource(l1, query, docCache = defaultDocCache) {
100
+ const out = [];
101
+ for (const v of rehydrate(l1.picked_vocabs)) {
102
+ const doc = await loadDoc(l1.resource, v, docCache);
103
+ for (const summary of v.adapter.listOperations(doc, query)) {
104
+ out.push(summary);
105
+ }
106
+ }
107
+ return out;
108
+ }
109
+ export async function getOperationsForResource(l1, opIds, docCache = defaultDocCache) {
110
+ const out = [];
111
+ for (const v of rehydrate(l1.picked_vocabs)) {
112
+ const doc = await loadDoc(l1.resource, v, docCache);
113
+ for (const detail of v.adapter.getOperations(doc, opIds)) {
114
+ out.push(detail);
115
+ }
116
+ }
117
+ return out;
118
+ }
119
+ // Resolve an opId on a resource by trying each picked vocab in order. First
120
+ // adapter that builds a plan wins. v1 has a single adapter (OpenAPI), so
121
+ // "first wins" is unambiguous; the collision-prefix rule for multi-adapter
122
+ // resources is an agent-proxy-side concern at list time, not invoke time.
123
+ export async function routeOperation(l1, opId, args, docCache = defaultDocCache) {
124
+ for (const v of rehydrate(l1.picked_vocabs)) {
125
+ const doc = await loadDoc(l1.resource, v, docCache);
126
+ try {
127
+ const plan = v.adapter.buildInvocation(doc, opId, args);
128
+ return { adapter: v.adapter, plan };
129
+ }
130
+ catch {
131
+ // try the next adapter
132
+ }
133
+ }
134
+ throw new Error(`unknown operation ${opId} on resource ${l1.resource}`);
135
+ }
136
+ // Convert a FetchedResource into the persisted L1 shape.
137
+ //
138
+ // access_mode default: if the resource advertises an authorization_endpoint
139
+ // but no access_mode, infer aauth-access-token (the R3 flow is the only thing
140
+ // authorization_endpoint exists for). Absent both, default to agent-token
141
+ // (resource accepts agent-signed requests directly — the registry's own mode).
142
+ export function toL1Entry(r) {
143
+ const inferredMode = r.meta.access_mode ?? (r.meta.authorization_endpoint ? 'aauth-access-token' : 'agent-token');
144
+ return {
145
+ resource: r.host,
146
+ origin: r.origin,
147
+ issuer: r.meta.issuer.replace(/\/+$/, ''),
148
+ name: r.meta.client_name?.trim() || r.host,
149
+ description: r.meta.description ?? '',
150
+ access_mode: inferredMode,
151
+ ...(r.meta.logo_uri ? { logo_uri: r.meta.logo_uri } : {}),
152
+ ...(r.meta.authorization_endpoint
153
+ ? { authorization_endpoint: r.meta.authorization_endpoint }
154
+ : {}),
155
+ picked_vocabs: r.pickedVocabs.map((v) => ({ vocabUri: v.vocabUri, docUrl: v.docUrl })),
156
+ added: new Date().toISOString(),
157
+ };
158
+ }
159
+ //# sourceMappingURL=resource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource.js","sourceRoot":"","sources":["../src/resource.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":""}
package/dist/server.js ADDED
@@ -0,0 +1,119 @@
1
+ #!/usr/bin/env node
2
+ // the agent proxy as an MCP stdio server: wires the transport-agnostic eight-tool surface
3
+ // (buildProxyTools) to filesystem-backed state and @aauth/local-keys identity,
4
+ // adds an OS-browser interaction launcher, and connects over stdio. The tool
5
+ // logic itself lives in tools.ts so an HTTP host can reuse it unchanged.
6
+ import { spawn } from 'node:child_process';
7
+ import { createWriteStream, mkdirSync } from 'node:fs';
8
+ import { createRequire } from 'node:module';
9
+ import { homedir } from 'node:os';
10
+ import { join } from 'node:path';
11
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
12
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
13
+ import { createLocalKeysIdentityProvider } from './identity-local.js';
14
+ import { createFsRegistryCache } from './registry.js';
15
+ import { createFsL1Store } from './store.js';
16
+ import { buildProxyTools } from './tools.js';
17
+ // Layer 2 of the interaction-driver hierarchy: when the PS couldn't reach the
18
+ // user via its own channels (AAuth#34 interaction_unavailable), the agent proxy runs on
19
+ // the user's machine and can spawn the OS's default-browser launcher. Best
20
+ // effort — silently no-ops on unsupported platforms or when the binary is
21
+ // missing. The text fallback (layer 3) is still emitted by buildProxyTools so a
22
+ // remote MCP or headless caller can surface the URL.
23
+ function tryOpenBrowser(url) {
24
+ const cmd = process.platform === 'darwin'
25
+ ? 'open'
26
+ : process.platform === 'win32'
27
+ ? 'cmd'
28
+ : 'xdg-open';
29
+ const args = process.platform === 'win32' ? ['/c', 'start', '""', url] : [url];
30
+ try {
31
+ const child = spawn(cmd, args, { detached: true, stdio: 'ignore' });
32
+ child.on('error', () => { });
33
+ child.unref();
34
+ }
35
+ catch {
36
+ // platform / binary missing — text fallback covers it
37
+ }
38
+ }
39
+ function slugifyClientName(name) {
40
+ if (!name)
41
+ return 'mcp-stdio-unknown';
42
+ const slug = name
43
+ .toLowerCase()
44
+ .replace(/[^a-z0-9]+/g, '-')
45
+ .replace(/^-+|-+$/g, '')
46
+ .slice(0, 32);
47
+ return slug || 'mcp-stdio-unknown';
48
+ }
49
+ const { version: PKG_VERSION } = createRequire(import.meta.url)('../package.json');
50
+ const server = new McpServer({ name: 'aauth-proxy', version: PKG_VERSION });
51
+ // `--log` tees stdio JSON-RPC frames to ~/.aauth/proxy/logs/<ISO>.jsonl as
52
+ // `{ts, dir, frame}` lines (same shape reloaderoo writes). Opt-in; best-effort —
53
+ // silently no-ops if the log directory can't be created or a line isn't JSON.
54
+ function setupFrameLog() {
55
+ if (!process.argv.includes('--log'))
56
+ return;
57
+ const dir = join(homedir(), '.aauth', 'proxy', 'logs');
58
+ let stream;
59
+ try {
60
+ mkdirSync(dir, { recursive: true });
61
+ const stamp = new Date().toISOString().replace(/[:.]/g, '-').replace(/-\d{3}Z$/, 'Z');
62
+ stream = createWriteStream(join(dir, `${stamp}.jsonl`), { flags: 'a' });
63
+ }
64
+ catch {
65
+ return;
66
+ }
67
+ const emit = (direction, line) => {
68
+ const t = line.trim();
69
+ if (!t)
70
+ return;
71
+ try {
72
+ stream.write(`${JSON.stringify({ ts: new Date().toISOString(), dir: direction, frame: JSON.parse(t) })}\n`);
73
+ }
74
+ catch {
75
+ // Non-JSON output on this transport would be a protocol bug; drop silently.
76
+ }
77
+ };
78
+ // Tee stdout (server->client). Patch before connect so the initialize reply
79
+ // is captured. Buffer partial lines across writes — the SDK may flush a frame
80
+ // in multiple chunks.
81
+ const origWrite = process.stdout.write.bind(process.stdout);
82
+ let outBuf = '';
83
+ process.stdout.write = ((chunk, ...rest) => {
84
+ const text = typeof chunk === 'string'
85
+ ? chunk
86
+ : Buffer.isBuffer(chunk)
87
+ ? chunk.toString('utf8')
88
+ : String(chunk);
89
+ outBuf += text;
90
+ let nl;
91
+ while ((nl = outBuf.indexOf('\n')) !== -1) {
92
+ emit('server->client', outBuf.slice(0, nl));
93
+ outBuf = outBuf.slice(nl + 1);
94
+ }
95
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
96
+ return origWrite(chunk, ...rest);
97
+ });
98
+ // Tee stdin (client->server). Added as a peer listener — Node fans each data
99
+ // event out to all listeners, so the SDK still receives every byte.
100
+ let inBuf = '';
101
+ process.stdin.on('data', (chunk) => {
102
+ inBuf += chunk.toString('utf8');
103
+ let nl;
104
+ while ((nl = inBuf.indexOf('\n')) !== -1) {
105
+ emit('client->server', inBuf.slice(0, nl));
106
+ inBuf = inBuf.slice(nl + 1);
107
+ }
108
+ });
109
+ }
110
+ setupFrameLog();
111
+ await buildProxyTools(server, {
112
+ l1: createFsL1Store(),
113
+ registryCache: createFsRegistryCache(),
114
+ identity: createLocalKeysIdentityProvider(),
115
+ onInteraction: (url, code) => tryOpenBrowser(`${url}?code=${code}`),
116
+ agentLocal: () => slugifyClientName(server.server.getClientVersion()?.name),
117
+ });
118
+ await server.connect(new StdioServerTransport());
119
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ export type AccessMode = 'agent-token' | 'aauth-access-token' | 'auth-token';
2
+ export interface L1Entry {
3
+ resource: string;
4
+ origin: string;
5
+ issuer: string;
6
+ name: string;
7
+ description: string;
8
+ access_mode: AccessMode;
9
+ logo_uri?: string;
10
+ authorization_endpoint?: string;
11
+ picked_vocabs: Array<{
12
+ vocabUri: string;
13
+ docUrl: string;
14
+ }>;
15
+ added: string;
16
+ last_used?: string;
17
+ }
18
+ export interface L1Store {
19
+ list(): Promise<L1Entry[]>;
20
+ get(host: string): Promise<L1Entry | undefined>;
21
+ upsert(entry: L1Entry): Promise<void>;
22
+ remove(host: string): Promise<boolean>;
23
+ touch(host: string): Promise<void>;
24
+ }
25
+ export declare function createFsL1Store(opts?: {
26
+ dir?: string;
27
+ }): L1Store;
28
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAYA,MAAM,MAAM,UAAU,GAAG,aAAa,GAAG,oBAAoB,GAAG,YAAY,CAAA;AAE5E,MAAM,WAAW,OAAO;IACtB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,UAAU,CAAA;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAC/B,aAAa,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC1D,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAKD,MAAM,WAAW,OAAO;IACtB,IAAI,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAAA;IAC1B,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,CAAA;IAC/C,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACrC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IACtC,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACnC;AAQD,wBAAgB,eAAe,CAAC,IAAI,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CA+CpE"}
package/dist/store.js ADDED
@@ -0,0 +1,64 @@
1
+ // L1 — added resources. The L1Store interface lets a host inject its own
2
+ // backend; the stdio server uses the filesystem default (createFsL1Store),
3
+ // backed by ~/.aauth/proxy/resources.json.
4
+ //
5
+ // The agent proxy writes here on add_resource (always), on first successful auth at a
6
+ // resource (touches last_used), and on remove_resource. No PS-side state is
7
+ // mutated by this module; remove is agent-proxy-local only.
8
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
9
+ import { homedir } from 'node:os';
10
+ import { dirname, join } from 'node:path';
11
+ // Filesystem-backed L1Store — the default for the stdio server. `dir` overrides
12
+ // the state directory (default ~/.aauth/proxy).
13
+ export function createFsL1Store(opts = {}) {
14
+ const stateDir = opts.dir ?? join(homedir(), '.aauth', 'proxy');
15
+ const l1Path = join(stateDir, 'resources.json');
16
+ function load() {
17
+ if (!existsSync(l1Path))
18
+ return { resources: [] };
19
+ try {
20
+ return JSON.parse(readFileSync(l1Path, 'utf8'));
21
+ }
22
+ catch {
23
+ return { resources: [] };
24
+ }
25
+ }
26
+ function save(file) {
27
+ mkdirSync(dirname(l1Path), { recursive: true });
28
+ writeFileSync(l1Path, JSON.stringify(file, null, 2));
29
+ }
30
+ return {
31
+ async list() {
32
+ return load().resources;
33
+ },
34
+ async get(host) {
35
+ return load().resources.find((r) => r.resource === host);
36
+ },
37
+ async upsert(entry) {
38
+ const file = load();
39
+ const idx = file.resources.findIndex((r) => r.resource === entry.resource);
40
+ if (idx >= 0)
41
+ file.resources[idx] = entry;
42
+ else
43
+ file.resources.push(entry);
44
+ save(file);
45
+ },
46
+ async remove(host) {
47
+ const file = load();
48
+ const next = file.resources.filter((r) => r.resource !== host);
49
+ if (next.length === file.resources.length)
50
+ return false;
51
+ save({ resources: next });
52
+ return true;
53
+ },
54
+ async touch(host) {
55
+ const file = load();
56
+ const entry = file.resources.find((r) => r.resource === host);
57
+ if (!entry)
58
+ return;
59
+ entry.last_used = new Date().toISOString();
60
+ save(file);
61
+ },
62
+ };
63
+ }
64
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { IdentityProvider } from './identity.js';
3
+ import type { RegistryCache } from './registry.js';
4
+ import type { DocCache } from './resource.js';
5
+ import type { L1Store } from './store.js';
6
+ export interface ProxyDeps {
7
+ l1: L1Store;
8
+ registryCache: RegistryCache;
9
+ identity: IdentityProvider;
10
+ docCache?: DocCache;
11
+ onInteraction?: (url: string, code: string) => void;
12
+ agentLocal?: () => string | undefined;
13
+ interaction?: {
14
+ mode?: 'surface' | 'await';
15
+ onInteraction?: (url: string, code: string, ctx: InteractionContext) => void | Promise<void>;
16
+ onPoll?: (elapsedMs: number, ctx: InteractionContext) => void | Promise<void>;
17
+ pollTimeoutMs?: number;
18
+ };
19
+ }
20
+ export interface InteractionContext {
21
+ sendNotification: (n: {
22
+ method: string;
23
+ params?: Record<string, unknown>;
24
+ }) => Promise<void>;
25
+ progressToken?: string | number;
26
+ }
27
+ export declare function buildProxyTools(server: McpServer, deps: ProxyDeps): Promise<void>;
28
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAKxE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAErD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAOlD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAC7C,OAAO,KAAK,EAAW,OAAO,EAAE,MAAM,YAAY,CAAA;AAElD,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,OAAO,CAAA;IACX,aAAa,EAAE,aAAa,CAAA;IAC5B,QAAQ,EAAE,gBAAgB,CAAA;IAG1B,QAAQ,CAAC,EAAE,QAAQ,CAAA;IAGnB,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAGnD,UAAU,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAA;IAWrC,WAAW,CAAC,EAAE;QACZ,IAAI,CAAC,EAAE,SAAS,GAAG,OAAO,CAAA;QAC1B,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,kBAAkB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;QAC5F,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,kBAAkB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;QAC7E,aAAa,CAAC,EAAE,MAAM,CAAA;KACvB,CAAA;CACF;AAMD,MAAM,WAAW,kBAAkB;IACjC,gBAAgB,EAAE,CAAC,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC5F,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;CAChC;AAqBD,wBAAsB,eAAe,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAyRvF"}