@aauth/mcp-openclaw
Advanced tools
+5
-1
@@ -5,2 +5,6 @@ export interface PluginConfig { | ||
| token_lifetime?: number; | ||
| /** Person server. Defaults to the one in the agent's local config. */ | ||
| person_server?: string; | ||
| /** Mission the agent is operating under; stamped into person tokens. */ | ||
| mission_s256?: string; | ||
| mcp_servers: Record<string, string>; | ||
@@ -16,3 +20,3 @@ } | ||
| export { ServerManager } from './server-manager.js'; | ||
| export type { ServerManagerOptions } from './server-manager.js'; | ||
| export type { ServerManagerOptions, PersonServerMetadata, SkippedServer, } from './server-manager.js'; | ||
| //# sourceMappingURL=index.d.ts.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,YAAY;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACpC;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,IAAI,YAAY,CAAA;IACzB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,CAAA;IAC9F,UAAU,CAAC,EAAE,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;CAC1C;AAED,eAAO,MAAM,EAAE,cAAc,CAAA;AAE7B,wBAAgB,QAAQ,CAAC,GAAG,EAAE,iBAAiB,GAAG,IAAI,CA0BrD;AAED,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,YAAY,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA"} | ||
| {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,YAAY;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,sEAAsE;IACtE,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,wEAAwE;IACxE,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACpC;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,IAAI,YAAY,CAAA;IACzB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,CAAA;IAC9F,UAAU,CAAC,EAAE,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;CAC1C;AAED,eAAO,MAAM,EAAE,cAAc,CAAA;AAE7B,wBAAgB,QAAQ,CAAC,GAAG,EAAE,iBAAiB,GAAG,IAAI,CAsCrD;AAED,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,YAAY,EACV,oBAAoB,EACpB,oBAAoB,EACpB,aAAa,GACd,MAAM,qBAAqB,CAAA"} |
+9
-1
@@ -6,3 +6,3 @@ import { createAgentToken } from '@aauth/local-keys'; | ||
| const config = api.getConfig(); | ||
| const { agent_url, local, token_lifetime, mcp_servers } = config; | ||
| const { agent_url, local, token_lifetime, person_server, mission_s256, mcp_servers } = config; | ||
| const getKeyMaterial = () => createAgentToken({ | ||
@@ -12,2 +12,3 @@ agentUrl: agent_url, | ||
| tokenLifetime: token_lifetime, | ||
| personServerUrl: person_server, | ||
| }); | ||
@@ -17,4 +18,9 @@ const manager = new ServerManager({ | ||
| getKeyMaterial, | ||
| personServerUrl: person_server, | ||
| missionS256: mission_s256, | ||
| }); | ||
| manager.connectAll().then(() => { | ||
| for (const skipped of manager.getSkippedServers()) { | ||
| console.warn(`[aauth] skipping MCP server ${skipped.name} (${skipped.url}): ${skipped.reason}`); | ||
| } | ||
| const tools = manager.getTools(); | ||
@@ -24,2 +30,4 @@ for (const tool of tools) { | ||
| } | ||
| }).catch((error) => { | ||
| console.error(`[aauth] failed to connect MCP servers: ${error instanceof Error ? error.message : String(error)}`); | ||
| }); | ||
@@ -26,0 +34,0 @@ api.onShutdown(() => manager.shutdown()); |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAenD,MAAM,CAAC,MAAM,EAAE,GAAG,WAAW,CAAA;AAE7B,MAAM,UAAU,QAAQ,CAAC,GAAsB;IAC7C,MAAM,MAAM,GAAG,GAAG,CAAC,SAAS,EAAE,CAAA;IAC9B,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,GAAG,MAAM,CAAA;IAEhE,MAAM,cAAc,GAAG,GAAG,EAAE,CAC1B,gBAAgB,CAAC;QACf,QAAQ,EAAE,SAAS;QACnB,KAAK,EAAE,KAAK,IAAI,UAAU;QAC1B,aAAa,EAAE,cAAc;KAC9B,CAAC,CAAA;IAEJ,MAAM,OAAO,GAAG,IAAI,aAAa,CAAC;QAChC,OAAO,EAAE,WAAW;QACpB,cAAc;KACf,CAAC,CAAA;IAEF,OAAO,CAAC,UAAU,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;QAC7B,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAA;QAChC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE,CAC3C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,CAC1C,CAAA;QACH,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAA;AAC1C,CAAC;AAED,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA"} | ||
| {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAmBnD,MAAM,CAAC,MAAM,EAAE,GAAG,WAAW,CAAA;AAE7B,MAAM,UAAU,QAAQ,CAAC,GAAsB;IAC7C,MAAM,MAAM,GAAG,GAAG,CAAC,SAAS,EAAE,CAAA;IAC9B,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,EAAE,WAAW,EAAE,GAAG,MAAM,CAAA;IAE7F,MAAM,cAAc,GAAG,GAAG,EAAE,CAC1B,gBAAgB,CAAC;QACf,QAAQ,EAAE,SAAS;QACnB,KAAK,EAAE,KAAK,IAAI,UAAU;QAC1B,aAAa,EAAE,cAAc;QAC7B,eAAe,EAAE,aAAa;KAC/B,CAAC,CAAA;IAEJ,MAAM,OAAO,GAAG,IAAI,aAAa,CAAC;QAChC,OAAO,EAAE,WAAW;QACpB,cAAc;QACd,eAAe,EAAE,aAAa;QAC9B,WAAW,EAAE,YAAY;KAC1B,CAAC,CAAA;IAEF,OAAO,CAAC,UAAU,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;QAC7B,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC;YAClD,OAAO,CAAC,IAAI,CACV,+BAA+B,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC,MAAM,EAAE,CAClF,CAAA;QACH,CAAC;QACD,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAA;QAChC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE,CAC3C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,CAC1C,CAAA;QACH,CAAC;IACH,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;QAC1B,OAAO,CAAC,KAAK,CACX,0CAA0C,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CACnG,CAAA;IACH,CAAC,CAAC,CAAA;IAEF,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAA;AAC1C,CAAC;AAED,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA"} |
@@ -1,5 +0,35 @@ | ||
| import type { GetKeyMaterial } from '@aauth/mcp-agent'; | ||
| import type { PersonServerMetadata as AgentPersonServerMetadata, GetKeyMaterial } from '@aauth/agent'; | ||
| /** | ||
| * Person server metadata, `/.well-known/aauth-person.json`. | ||
| * | ||
| * `auth_token_endpoint` is the -11 name for what was `token_endpoint`; | ||
| * `person_token_endpoint` is new and REQUIRED — it is where the agent obtains | ||
| * the person token a resource must have verified before it will issue a | ||
| * resource token. | ||
| * | ||
| * `@aauth/agent` owns this shape. Re-exported here so a consumer of this | ||
| * package needs one import, not two. | ||
| */ | ||
| export type PersonServerMetadata = AgentPersonServerMetadata; | ||
| /** A configured server this agent's setup cannot use, and why. */ | ||
| export interface SkippedServer { | ||
| name: string; | ||
| url: string; | ||
| /** The `access_mode` the resource declared. */ | ||
| mode: string; | ||
| reason: string; | ||
| } | ||
| export interface ServerManagerOptions { | ||
| servers: Record<string, string>; | ||
| getKeyMaterial: GetKeyMaterial; | ||
| /** Person server URL. Defaults to the `ps` claim of the agent token. */ | ||
| personServerUrl?: string; | ||
| /** Cached PS metadata; when provided the person token request skips the | ||
| * /.well-known fetch. */ | ||
| personServerMetadata?: PersonServerMetadata; | ||
| /** Called with freshly-fetched PS metadata so the caller can persist it. */ | ||
| onPersonServerMetadata?: (metadata: PersonServerMetadata) => void; | ||
| /** Mission the agent is operating under; stamped into the person token. */ | ||
| missionS256?: string; | ||
| onInteraction?: (url: string, code: string) => void; | ||
| } | ||
@@ -9,5 +39,29 @@ export declare class ServerManager { | ||
| private servers; | ||
| /** server name → person token for that server's resource. */ | ||
| private personTokens; | ||
| private skipped; | ||
| private personServerMetadata?; | ||
| /** Signs with the agent token — used to talk to the person server. */ | ||
| private agentSignedFetch; | ||
| constructor(options: ServerManagerOptions); | ||
| connectAll(): Promise<void>; | ||
| private connect; | ||
| /** | ||
| * A signed fetch for one resource that satisfies a person-token challenge. | ||
| * | ||
| * The key material getter picks up the person token as soon as there is one, | ||
| * so a retry after `requirement=person-token` presents it via Signature-Key | ||
| * in place of the agent token. | ||
| */ | ||
| private createResourceFetch; | ||
| /** The agent token, or the person token for `name` once there is one. */ | ||
| private keyMaterialFor; | ||
| private ensurePersonToken; | ||
| /** Configured person server, else the agent token's `ps` claim. */ | ||
| private personServer; | ||
| /** | ||
| * The resource's declared `access_mode`, or undefined when it publishes no | ||
| * metadata — planAccessMode treats that as undeclared, never an error. | ||
| */ | ||
| private fetchAccessMode; | ||
| getTools(): Array<{ | ||
@@ -19,2 +73,4 @@ prefixedName: string; | ||
| }>; | ||
| /** Servers not connected because this agent cannot satisfy their access mode. */ | ||
| getSkippedServers(): SkippedServer[]; | ||
| callTool(prefixedName: string, args: Record<string, unknown>): Promise<unknown>; | ||
@@ -21,0 +77,0 @@ shutdown(): Promise<void>; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"server-manager.d.ts","sourceRoot":"","sources":["../src/server-manager.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAUtD,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B,cAAc,EAAE,cAAc,CAAA;CAC/B;AAED,qBAAa,aAAa;IAGZ,OAAO,CAAC,OAAO;IAF3B,OAAO,CAAC,OAAO,CAAmC;gBAE9B,OAAO,EAAE,oBAAoB;IAE3C,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;YAKnB,OAAO;IAkBrB,QAAQ,IAAI,KAAK,CAAC;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAcrG,QAAQ,CACZ,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC,OAAO,CAAC;IAUb,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAOhC"} | ||
| {"version":3,"file":"server-manager.d.ts","sourceRoot":"","sources":["../src/server-manager.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,oBAAoB,IAAI,yBAAyB,EAAa,cAAc,EAAe,MAAM,cAAc,CAAA;AAY7H;;;;;;;;;;GAUG;AACH,MAAM,MAAM,oBAAoB,GAAG,yBAAyB,CAAA;AAE5D,kEAAkE;AAClE,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B,cAAc,EAAE,cAAc,CAAA;IAC9B,wEAAwE;IACxE,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB;8BAC0B;IAC1B,oBAAoB,CAAC,EAAE,oBAAoB,CAAA;IAC3C,4EAA4E;IAC5E,sBAAsB,CAAC,EAAE,CAAC,QAAQ,EAAE,oBAAoB,KAAK,IAAI,CAAA;IACjE,2EAA2E;IAC3E,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CACpD;AAUD,qBAAa,aAAa;IASZ,OAAO,CAAC,OAAO;IAR3B,OAAO,CAAC,OAAO,CAAmC;IAClD,6DAA6D;IAC7D,OAAO,CAAC,YAAY,CAAuC;IAC3D,OAAO,CAAC,OAAO,CAAmC;IAClD,OAAO,CAAC,oBAAoB,CAAC,CAAsB;IACnD,sEAAsE;IACtE,OAAO,CAAC,gBAAgB,CAAW;gBAEf,OAAO,EAAE,oBAAoB;IAK3C,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;YAKnB,OAAO;IAqCrB;;;;;;OAMG;IACH,OAAO,CAAC,mBAAmB;IAwB3B,yEAAyE;YAC3D,cAAc;YAYd,iBAAiB;IAkC/B,mEAAmE;YACrD,YAAY;IAQ1B;;;OAGG;YACW,eAAe;IAW7B,QAAQ,IAAI,KAAK,CAAC;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAc3G,iFAAiF;IACjF,iBAAiB,IAAI,aAAa,EAAE;IAI9B,QAAQ,CACZ,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC,OAAO,CAAC;IAUb,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAShC"} |
+133
-4
| import { Client } from '@modelcontextprotocol/sdk/client/index.js'; | ||
| import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js'; | ||
| import { createSignedFetch } from '@aauth/mcp-agent'; | ||
| import { createSignedFetch, requestPersonToken } from '@aauth/agent'; | ||
| import { decodeJwtPayload, parseRequirementHeader, planAccessMode } from '@aauth/protocol'; | ||
| /** Refresh a person token this far before it expires. */ | ||
| const PERSON_TOKEN_SKEW_MS = 60_000; | ||
| export class ServerManager { | ||
| options; | ||
| servers = new Map(); | ||
| /** server name → person token for that server's resource. */ | ||
| personTokens = new Map(); | ||
| skipped = new Map(); | ||
| personServerMetadata; | ||
| /** Signs with the agent token — used to talk to the person server. */ | ||
| agentSignedFetch; | ||
| constructor(options) { | ||
| this.options = options; | ||
| this.agentSignedFetch = createSignedFetch(options.getKeyMaterial); | ||
| this.personServerMetadata = options.personServerMetadata; | ||
| } | ||
@@ -15,5 +26,21 @@ async connectAll() { | ||
| async connect(name, url) { | ||
| const signedFetch = createSignedFetch(this.options.getKeyMaterial); | ||
| // The resource identifier is the origin — the `resource` the person token | ||
| // is requested for and the token's `aud`. | ||
| const resource = new URL(url).origin; | ||
| const plan = planAccessMode(await this.fetchAccessMode(resource), { | ||
| hasPersonServer: (await this.personServer()) !== undefined, | ||
| }); | ||
| if (plan.kind === 'unsatisfiable') { | ||
| this.skipped.set(name, { name, url, mode: plan.mode, reason: plan.reason }); | ||
| return; | ||
| } | ||
| // `person-token` and `auth-token` both put a person token on the wire from | ||
| // the first call: a resource MUST have verified one before it issues a | ||
| // resource token. Every other mode starts on the agent token and upgrades | ||
| // if the resource challenges with requirement=person-token. | ||
| if (plan.kind === 'satisfiable' && (plan.mode === 'person-token' || plan.mode === 'auth-token')) { | ||
| await this.ensurePersonToken(name, resource); | ||
| } | ||
| const transport = new StreamableHTTPClientTransport(new URL(url), { | ||
| fetch: signedFetch, | ||
| fetch: this.createResourceFetch(name, resource), | ||
| }); | ||
@@ -27,4 +54,100 @@ const client = new Client({ name: `aauth-${name}`, version: '0.0.1' }); | ||
| } | ||
| this.servers.set(name, { name, client, transport, tools: toolMap }); | ||
| this.servers.set(name, { name, url, client, transport, tools: toolMap }); | ||
| } | ||
| /** | ||
| * A signed fetch for one resource that satisfies a person-token challenge. | ||
| * | ||
| * The key material getter picks up the person token as soon as there is one, | ||
| * so a retry after `requirement=person-token` presents it via Signature-Key | ||
| * in place of the agent token. | ||
| */ | ||
| createResourceFetch(name, resource) { | ||
| const signedFetch = createSignedFetch(() => this.keyMaterialFor(name)); | ||
| return async (url, init) => { | ||
| const response = await signedFetch(url, init); | ||
| if (response.status !== 401) | ||
| return response; | ||
| const header = response.headers.get('aauth-requirement'); | ||
| if (!header) | ||
| return response; | ||
| // A requirement value this agent does not recognize throws | ||
| // UnsupportedRequirementError out of parseRequirementHeader — the | ||
| // response is not satisfiable and the error reaches the caller. | ||
| const challenge = parseRequirementHeader(header); | ||
| if (challenge.requirement !== 'person-token') | ||
| return response; | ||
| // Only retry when the request body can be sent again. | ||
| if (init?.body != null && typeof init.body !== 'string') | ||
| return response; | ||
| this.personTokens.delete(name); | ||
| await this.ensurePersonToken(name, resource); | ||
| return signedFetch(url, init); | ||
| }; | ||
| } | ||
| /** The agent token, or the person token for `name` once there is one. */ | ||
| async keyMaterialFor(name) { | ||
| const keyMaterial = await this.options.getKeyMaterial(); | ||
| const cached = this.personTokens.get(name); | ||
| if (!cached || cached.expiresAt <= Date.now() + PERSON_TOKEN_SKEW_MS) { | ||
| return keyMaterial; | ||
| } | ||
| return { | ||
| signingKey: keyMaterial.signingKey, | ||
| signatureKey: { type: 'jwt', jwt: cached.token }, | ||
| }; | ||
| } | ||
| async ensurePersonToken(name, resource) { | ||
| const cached = this.personTokens.get(name); | ||
| if (cached && cached.expiresAt > Date.now() + PERSON_TOKEN_SKEW_MS) { | ||
| return cached.token; | ||
| } | ||
| const personServerUrl = await this.personServer(); | ||
| if (!personServerUrl) { | ||
| throw new Error(`${resource} requires a person token and this agent has no person server ` | ||
| + '(no "ps" claim in its agent token)'); | ||
| } | ||
| const result = await requestPersonToken({ | ||
| signedFetch: this.agentSignedFetch, | ||
| personServerUrl, | ||
| personServerMetadata: this.personServerMetadata, | ||
| onMetadata: (metadata) => { | ||
| this.personServerMetadata = metadata; | ||
| this.options.onPersonServerMetadata?.(metadata); | ||
| }, | ||
| resource, | ||
| missionS256: this.options.missionS256, | ||
| onInteraction: this.options.onInteraction, | ||
| }); | ||
| this.personTokens.set(name, { | ||
| token: result.personToken, | ||
| expiresAt: Date.now() + result.expiresIn * 1000, | ||
| }); | ||
| return result.personToken; | ||
| } | ||
| /** Configured person server, else the agent token's `ps` claim. */ | ||
| async personServer() { | ||
| if (this.options.personServerUrl) | ||
| return this.options.personServerUrl; | ||
| const { signatureKey } = await this.options.getKeyMaterial(); | ||
| if (signatureKey.type === 'hwk') | ||
| return undefined; | ||
| const ps = decodeJwtPayload(signatureKey.jwt).ps; | ||
| return typeof ps === 'string' ? ps : undefined; | ||
| } | ||
| /** | ||
| * The resource's declared `access_mode`, or undefined when it publishes no | ||
| * metadata — planAccessMode treats that as undeclared, never an error. | ||
| */ | ||
| async fetchAccessMode(resource) { | ||
| try { | ||
| const response = await fetch(`${resource}/.well-known/aauth-resource.json`); | ||
| if (!response.ok) | ||
| return undefined; | ||
| const metadata = await response.json(); | ||
| return typeof metadata.access_mode === 'string' ? metadata.access_mode : undefined; | ||
| } | ||
| catch { | ||
| return undefined; | ||
| } | ||
| } | ||
| getTools() { | ||
@@ -43,2 +166,6 @@ const result = []; | ||
| } | ||
| /** Servers not connected because this agent cannot satisfy their access mode. */ | ||
| getSkippedServers() { | ||
| return Array.from(this.skipped.values()); | ||
| } | ||
| async callTool(prefixedName, args) { | ||
@@ -57,4 +184,6 @@ for (const [, server] of this.servers) { | ||
| this.servers.clear(); | ||
| this.personTokens.clear(); | ||
| this.skipped.clear(); | ||
| } | ||
| } | ||
| //# sourceMappingURL=server-manager.js.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"server-manager.js","sourceRoot":"","sources":["../src/server-manager.ts"],"names":[],"mappings":"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"} | ||
| {"version":3,"file":"server-manager.js","sourceRoot":"","sources":["../src/server-manager.ts"],"names":[],"mappings":"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"} |
@@ -1,3 +0,4 @@ | ||
| import { describe, it, expect, vi, beforeEach } from 'vitest'; | ||
| const { mockConnect, mockListTools, mockCallTool, MockClient, mockTransportClose, MockStreamableHTTPClientTransport, mockCreateSignedFetch, } = vi.hoisted(() => { | ||
| import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; | ||
| import { UnsupportedRequirementError } from '@aauth/protocol'; | ||
| const { mockConnect, mockListTools, mockCallTool, MockClient, mockTransportClose, MockStreamableHTTPClientTransport, mockCreateSignedFetch, mockRequestPersonToken, signedRequests, responseQueue, } = vi.hoisted(() => { | ||
| const mockConnect = vi.fn().mockResolvedValue(undefined); | ||
@@ -15,4 +16,17 @@ const mockListTools = vi.fn(); | ||
| }); | ||
| const mockCreateSignedFetch = vi.fn().mockReturnValue(vi.fn()); | ||
| return { mockConnect, mockListTools, mockCallTool, MockClient, mockTransportClose, MockStreamableHTTPClientTransport, mockCreateSignedFetch }; | ||
| // Every signed request made through a mocked createSignedFetch, with the key | ||
| // material that would have gone into its Signature-Key header. | ||
| const signedRequests = []; | ||
| const responseQueue = []; | ||
| const mockCreateSignedFetch = vi.fn((getKeyMaterial) => vi.fn(async (url) => { | ||
| const { signatureKey } = await getKeyMaterial(); | ||
| signedRequests.push({ url: String(url), signatureKey }); | ||
| return responseQueue.shift() ?? new Response(null, { status: 200 }); | ||
| })); | ||
| const mockRequestPersonToken = vi.fn(); | ||
| return { | ||
| mockConnect, mockListTools, mockCallTool, MockClient, | ||
| mockTransportClose, MockStreamableHTTPClientTransport, | ||
| mockCreateSignedFetch, mockRequestPersonToken, signedRequests, responseQueue, | ||
| }; | ||
| }); | ||
@@ -25,14 +39,52 @@ vi.mock('@modelcontextprotocol/sdk/client/index.js', () => ({ | ||
| })); | ||
| vi.mock('@aauth/mcp-agent', () => ({ | ||
| vi.mock('@aauth/agent', () => ({ | ||
| createSignedFetch: mockCreateSignedFetch, | ||
| requestPersonToken: mockRequestPersonToken, | ||
| })); | ||
| import { ServerManager } from './server-manager.js'; | ||
| function b64u(value) { | ||
| return Buffer.from(JSON.stringify(value)).toString('base64url'); | ||
| } | ||
| function jwt(payload) { | ||
| return `${b64u({ alg: 'Ed25519', typ: 'aa-agent+jwt' })}.${b64u(payload)}.sig`; | ||
| } | ||
| const AGENT_TOKEN = jwt({ sub: 'aauth:openclaw@example.com', ps: 'https://ps.example' }); | ||
| const PS_LESS_AGENT_TOKEN = jwt({ sub: 'aauth:openclaw@example.com' }); | ||
| const PERSON_TOKEN = jwt({ aud: 'https://files.example.com' }); | ||
| /** Key material getter for an agent token with the given payload. */ | ||
| function keyMaterial(agentToken = AGENT_TOKEN) { | ||
| return vi.fn().mockResolvedValue({ | ||
| signingKey: { kty: 'OKP', crv: 'Ed25519' }, | ||
| signatureKey: { type: 'jwt', jwt: agentToken }, | ||
| }); | ||
| } | ||
| /** Stub the resource-metadata fetch with a declared `access_mode`. */ | ||
| function stubResourceMetadata(accessMode) { | ||
| vi.stubGlobal('fetch', vi.fn(async () => (accessMode === undefined | ||
| ? new Response(null, { status: 404 }) | ||
| : new Response(JSON.stringify({ access_mode: accessMode }), { status: 200 })))); | ||
| } | ||
| /** The `fetch` the transport was constructed with, for the nth server. */ | ||
| function transportFetch(index = 0) { | ||
| return MockStreamableHTTPClientTransport.mock.calls[index][1].fetch; | ||
| } | ||
| describe('ServerManager', () => { | ||
| const getKeyMaterial = vi.fn(); | ||
| let getKeyMaterial; | ||
| beforeEach(() => { | ||
| vi.clearAllMocks(); | ||
| signedRequests.length = 0; | ||
| responseQueue.length = 0; | ||
| getKeyMaterial = keyMaterial(); | ||
| stubResourceMetadata(); | ||
| mockListTools.mockResolvedValue({ | ||
| tools: [{ name: 'read_file' }, { name: 'write_file' }], | ||
| }); | ||
| mockRequestPersonToken.mockResolvedValue({ | ||
| personToken: PERSON_TOKEN, | ||
| expiresIn: 3600, | ||
| }); | ||
| }); | ||
| afterEach(() => { | ||
| vi.unstubAllGlobals(); | ||
| }); | ||
| it('connectAll creates transport and client per server', async () => { | ||
@@ -44,2 +96,3 @@ const manager = new ServerManager({ | ||
| await manager.connectAll(); | ||
| // The agent-token fetch (person server) is built from getKeyMaterial itself. | ||
| expect(mockCreateSignedFetch).toHaveBeenCalledWith(getKeyMaterial); | ||
@@ -115,3 +168,186 @@ expect(MockStreamableHTTPClientTransport).toHaveBeenCalledOnce(); | ||
| }); | ||
| describe('person token', () => { | ||
| it('is not requested when the resource declares agent-token access', async () => { | ||
| stubResourceMetadata('agent-token'); | ||
| const manager = new ServerManager({ | ||
| servers: { myfiles: 'https://files.example.com/mcp' }, | ||
| getKeyMaterial, | ||
| }); | ||
| await manager.connectAll(); | ||
| await transportFetch()('https://files.example.com/mcp'); | ||
| expect(mockRequestPersonToken).not.toHaveBeenCalled(); | ||
| expect(signedRequests.at(-1)?.signatureKey).toEqual({ type: 'jwt', jwt: AGENT_TOKEN }); | ||
| }); | ||
| it('is obtained up front when the resource declares person-token access', async () => { | ||
| stubResourceMetadata('person-token'); | ||
| const manager = new ServerManager({ | ||
| servers: { myfiles: 'https://files.example.com/mcp' }, | ||
| getKeyMaterial, | ||
| missionS256: 'dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk', | ||
| }); | ||
| await manager.connectAll(); | ||
| expect(mockRequestPersonToken).toHaveBeenCalledOnce(); | ||
| expect(mockRequestPersonToken.mock.calls[0][0]).toMatchObject({ | ||
| // The PS comes from the agent token's `ps` claim, the resource is the | ||
| // MCP server's origin — it becomes the person token's `aud`. | ||
| personServerUrl: 'https://ps.example', | ||
| resource: 'https://files.example.com', | ||
| missionS256: 'dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk', | ||
| }); | ||
| }); | ||
| it('is obtained up front when the resource declares auth-token access', async () => { | ||
| stubResourceMetadata('auth-token'); | ||
| const manager = new ServerManager({ | ||
| servers: { myfiles: 'https://files.example.com/mcp' }, | ||
| getKeyMaterial, | ||
| }); | ||
| await manager.connectAll(); | ||
| expect(mockRequestPersonToken).toHaveBeenCalledOnce(); | ||
| }); | ||
| it('replaces the agent token in the signature key once held', async () => { | ||
| stubResourceMetadata('person-token'); | ||
| const manager = new ServerManager({ | ||
| servers: { myfiles: 'https://files.example.com/mcp' }, | ||
| getKeyMaterial, | ||
| }); | ||
| await manager.connectAll(); | ||
| await transportFetch()('https://files.example.com/mcp'); | ||
| expect(signedRequests.at(-1)?.signatureKey).toEqual({ type: 'jwt', jwt: PERSON_TOKEN }); | ||
| }); | ||
| it('uses the configured person server over the agent token ps claim', async () => { | ||
| stubResourceMetadata('person-token'); | ||
| const manager = new ServerManager({ | ||
| servers: { myfiles: 'https://files.example.com/mcp' }, | ||
| getKeyMaterial, | ||
| personServerUrl: 'https://other-ps.example', | ||
| }); | ||
| await manager.connectAll(); | ||
| expect(mockRequestPersonToken.mock.calls[0][0]).toMatchObject({ | ||
| personServerUrl: 'https://other-ps.example', | ||
| }); | ||
| }); | ||
| it('caches PS metadata from the first request and reports it', async () => { | ||
| // -11 renamed `token_endpoint` to `auth_token_endpoint` and added the | ||
| // REQUIRED `person_token_endpoint`. | ||
| const metadata = { | ||
| auth_token_endpoint: 'https://ps.example/aauth/token/auth', | ||
| person_token_endpoint: 'https://ps.example/aauth/token/person', | ||
| }; | ||
| const onPersonServerMetadata = vi.fn(); | ||
| mockRequestPersonToken.mockImplementation(async (options) => { | ||
| options.onMetadata?.(metadata); | ||
| return { personToken: PERSON_TOKEN, expiresIn: 3600 }; | ||
| }); | ||
| stubResourceMetadata('person-token'); | ||
| const manager = new ServerManager({ | ||
| servers: { myfiles: 'https://files.example.com/mcp' }, | ||
| getKeyMaterial, | ||
| onPersonServerMetadata, | ||
| }); | ||
| await manager.connectAll(); | ||
| expect(onPersonServerMetadata).toHaveBeenCalledWith(metadata); | ||
| expect(mockRequestPersonToken.mock.calls[0][0].personServerMetadata).toBeUndefined(); | ||
| // A later person token request reuses the cached copy — no second | ||
| // /.well-known fetch at the PS. | ||
| responseQueue.push(new Response(null, { | ||
| status: 401, | ||
| headers: { 'AAuth-Requirement': 'requirement=person-token' }, | ||
| }), new Response('{}', { status: 200 })); | ||
| await transportFetch()('https://files.example.com/mcp'); | ||
| expect(mockRequestPersonToken).toHaveBeenCalledTimes(2); | ||
| expect(mockRequestPersonToken.mock.calls[1][0].personServerMetadata).toEqual(metadata); | ||
| }); | ||
| }); | ||
| describe('AAuth-Requirement challenges', () => { | ||
| it('obtains a person token and retries on requirement=person-token', async () => { | ||
| const manager = new ServerManager({ | ||
| servers: { myfiles: 'https://files.example.com/mcp' }, | ||
| getKeyMaterial, | ||
| }); | ||
| await manager.connectAll(); | ||
| expect(mockRequestPersonToken).not.toHaveBeenCalled(); | ||
| responseQueue.push(new Response(null, { | ||
| status: 401, | ||
| headers: { 'AAuth-Requirement': 'requirement=person-token' }, | ||
| }), new Response('{}', { status: 200 })); | ||
| const response = await transportFetch()('https://files.example.com/mcp', { | ||
| method: 'POST', | ||
| body: '{"jsonrpc":"2.0"}', | ||
| }); | ||
| expect(response.status).toBe(200); | ||
| expect(mockRequestPersonToken).toHaveBeenCalledOnce(); | ||
| expect(mockRequestPersonToken.mock.calls[0][0]).toMatchObject({ | ||
| resource: 'https://files.example.com', | ||
| }); | ||
| // First attempt on the agent token, retry on the person token. | ||
| expect(signedRequests.map((r) => r.signatureKey)).toEqual([ | ||
| { type: 'jwt', jwt: AGENT_TOKEN }, | ||
| { type: 'jwt', jwt: PERSON_TOKEN }, | ||
| ]); | ||
| }); | ||
| it('surfaces an unrecognized requirement as an error', async () => { | ||
| const manager = new ServerManager({ | ||
| servers: { myfiles: 'https://files.example.com/mcp' }, | ||
| getKeyMaterial, | ||
| }); | ||
| await manager.connectAll(); | ||
| responseQueue.push(new Response(null, { | ||
| status: 401, | ||
| headers: { 'AAuth-Requirement': 'requirement=quantum-token' }, | ||
| })); | ||
| await expect(transportFetch()('https://files.example.com/mcp')).rejects.toThrow(UnsupportedRequirementError); | ||
| expect(mockRequestPersonToken).not.toHaveBeenCalled(); | ||
| }); | ||
| it('passes through a 401 with no AAuth-Requirement header', async () => { | ||
| const manager = new ServerManager({ | ||
| servers: { myfiles: 'https://files.example.com/mcp' }, | ||
| getKeyMaterial, | ||
| }); | ||
| await manager.connectAll(); | ||
| responseQueue.push(new Response(null, { status: 401 })); | ||
| const response = await transportFetch()('https://files.example.com/mcp'); | ||
| expect(response.status).toBe(401); | ||
| expect(mockRequestPersonToken).not.toHaveBeenCalled(); | ||
| }); | ||
| }); | ||
| describe('access mode planning', () => { | ||
| it('skips a resource this agent cannot satisfy', async () => { | ||
| stubResourceMetadata('auth-token'); | ||
| const manager = new ServerManager({ | ||
| servers: { myfiles: 'https://files.example.com/mcp' }, | ||
| getKeyMaterial: keyMaterial(PS_LESS_AGENT_TOKEN), | ||
| }); | ||
| await manager.connectAll(); | ||
| expect(MockStreamableHTTPClientTransport).not.toHaveBeenCalled(); | ||
| expect(manager.getTools()).toEqual([]); | ||
| const [skipped] = manager.getSkippedServers(); | ||
| expect(skipped).toMatchObject({ | ||
| name: 'myfiles', | ||
| url: 'https://files.example.com/mcp', | ||
| mode: 'auth-token', | ||
| }); | ||
| expect(skipped.reason).toBeTruthy(); | ||
| }); | ||
| it('connects when the resource declares a mode it does not recognize', async () => { | ||
| stubResourceMetadata('some-future-mode'); | ||
| const manager = new ServerManager({ | ||
| servers: { myfiles: 'https://files.example.com/mcp' }, | ||
| getKeyMaterial, | ||
| }); | ||
| await manager.connectAll(); | ||
| expect(manager.getSkippedServers()).toEqual([]); | ||
| expect(MockStreamableHTTPClientTransport).toHaveBeenCalledOnce(); | ||
| expect(mockRequestPersonToken).not.toHaveBeenCalled(); | ||
| }); | ||
| it('connects when the resource publishes no metadata', async () => { | ||
| const manager = new ServerManager({ | ||
| servers: { myfiles: 'https://files.example.com/mcp' }, | ||
| getKeyMaterial, | ||
| }); | ||
| await manager.connectAll(); | ||
| expect(manager.getSkippedServers()).toEqual([]); | ||
| expect(MockStreamableHTTPClientTransport).toHaveBeenCalledOnce(); | ||
| }); | ||
| }); | ||
| }); | ||
| //# sourceMappingURL=server-manager.test.js.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"server-manager.test.js","sourceRoot":"","sources":["../src/server-manager.test.ts"],"names":[],"mappings":"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"} | ||
| {"version":3,"file":"server-manager.test.js","sourceRoot":"","sources":["../src/server-manager.test.ts"],"names":[],"mappings":"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"} |
@@ -22,2 +22,10 @@ { | ||
| }, | ||
| "person_server": { | ||
| "type": "string", | ||
| "description": "Person server URL (default: the agent token's ps claim)" | ||
| }, | ||
| "mission_s256": { | ||
| "type": "string", | ||
| "description": "Mission the agent is operating under, stamped into person tokens" | ||
| }, | ||
| "mcp_servers": { | ||
@@ -24,0 +32,0 @@ "type": "object", |
+4
-3
| { | ||
| "name": "@aauth/mcp-openclaw", | ||
| "version": "1.0.0", | ||
| "version": "3.0.0", | ||
| "description": "OpenClaw plugin for AAuth-authenticated MCP server connections", | ||
@@ -37,4 +37,5 @@ "type": "module", | ||
| "dependencies": { | ||
| "@aauth/mcp-agent": "^1.0.0", | ||
| "@aauth/local-keys": "^1.0.0", | ||
| "@aauth/agent": "^3.0.0", | ||
| "@aauth/protocol": "^1.0.0", | ||
| "@aauth/local-keys": "^2.0.0", | ||
| "@modelcontextprotocol/sdk": "^1.15.1" | ||
@@ -41,0 +42,0 @@ }, |
+23
-0
@@ -26,2 +26,3 @@ # @aauth/mcp-openclaw | ||
| "delegate": "openclaw", | ||
| "person_server": "https://ps.example", | ||
| "mcp_servers": { | ||
@@ -40,2 +41,18 @@ "my-files": "https://files-api.example.com/mcp", | ||
| `person_server` is optional — it defaults to the `ps` claim of the agent token. It is used for | ||
| both the token's `ps` claim and the person token requests below. | ||
| ## Person tokens | ||
| An MCP server is an AAuth resource. Under AAuth -11 a resource MUST have verified a person token | ||
| before it issues a resource token, so the plugin obtains one per server from the person server's | ||
| `person_token_endpoint`, for `resource` = the MCP server's origin. The person token is presented | ||
| via `Signature-Key` in place of the agent token. | ||
| It is obtained up front when the server's `/.well-known/aauth-resource.json` declares | ||
| `access_mode: person-token` or `auth-token`, and otherwise on demand, when the server answers | ||
| `401` with `AAuth-Requirement: requirement=person-token`. A server whose declared access mode this | ||
| agent cannot satisfy — `auth-token` with no person server, say — is skipped rather than connected; | ||
| see `getSkippedServers()`. | ||
| ## API | ||
@@ -67,2 +84,4 @@ | ||
| }), | ||
| // optional — defaults to the agent token's `ps` claim | ||
| personServerUrl: 'https://ps.example', | ||
| }) | ||
@@ -76,2 +95,6 @@ | ||
| // Servers skipped because this agent cannot satisfy their access mode | ||
| const skipped = manager.getSkippedServers() | ||
| // [{ name: 'my-db', url: '...', mode: 'auth-token', reason: 'agent has no person server' }] | ||
| // Call a tool | ||
@@ -78,0 +101,0 @@ const result = await manager.callTool('my-files_read', { path: '/data.json' }) |
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
59406
165.35%700
170.27%105
28.05%4
33.33%1
Infinity%3
200%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
Updated