@openagentid/mcp 0.1.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.
@@ -0,0 +1,87 @@
1
+ import { SkillsPolicyDecision, SkillsPolicyHook } from './types.js';
2
+ export { VerifiedIdentity } from './types.js';
3
+
4
+ /**
5
+ * Skills policy support for @openagentid/mcp.
6
+ *
7
+ * MCP tools and SKILLS.md entries describe the same thing: a capability
8
+ * an agent can invoke. When an MCP server exposes a tool that proxies
9
+ * skill invocation (typically named `invoke_skill` or any name a host
10
+ * application configures), the middleware consults a skills policy
11
+ * before allowing the call. This file provides the helper that picks the
12
+ * right policy for a given call and a small built-in store implementation
13
+ * suitable for tests and reference implementations.
14
+ */
15
+
16
+ /**
17
+ * Tool name prefixes that the middleware treats as skill-like by default.
18
+ * Host applications can override the matcher entirely via
19
+ * {@link createSkillsPolicy}.
20
+ */
21
+ declare const DEFAULT_SKILL_TOOL_NAMES: ReadonlyArray<string>;
22
+ /**
23
+ * A single rule describing whether a `(skillName, did)` pair is allowed.
24
+ * `null` for `dids` means "any verified caller". An empty array means
25
+ * "no caller".
26
+ */
27
+ interface SkillsRule {
28
+ skillName: string;
29
+ /** DIDs allowed to invoke this skill, or `null` for any. */
30
+ dids: ReadonlyArray<string> | null;
31
+ /** Optional reason emitted when the rule denies a call. */
32
+ reason?: string;
33
+ }
34
+ /**
35
+ * Policy store interface — implementations may be in-memory, file-backed
36
+ * by `SKILLS.md`, or fetched from a remote service.
37
+ */
38
+ interface SkillsPolicyStore {
39
+ lookup(skillName: string): Promise<SkillsRule | null> | SkillsRule | null;
40
+ }
41
+ /**
42
+ * Trivial in-memory store useful in tests and as a starting point for
43
+ * production stores.
44
+ */
45
+ declare class InMemorySkillsPolicyStore implements SkillsPolicyStore {
46
+ private readonly rules;
47
+ constructor(rules?: ReadonlyArray<SkillsRule>);
48
+ lookup(skillName: string): SkillsRule | null;
49
+ /** Returns a NEW store with the given rule applied (immutable update). */
50
+ withRule(rule: SkillsRule): InMemorySkillsPolicyStore;
51
+ }
52
+ interface CreateSkillsPolicyOptions {
53
+ /** The store backing skill lookups. */
54
+ store: SkillsPolicyStore;
55
+ /**
56
+ * Returns true when a tool call should be checked against the skills
57
+ * policy. Defaults to matching the tool name against
58
+ * {@link DEFAULT_SKILL_TOOL_NAMES}.
59
+ */
60
+ isSkillTool?: (toolName: string) => boolean;
61
+ /**
62
+ * Extracts the skill name from the tool's arguments. Defaults to
63
+ * reading `args.skill` or `args.skillName`.
64
+ */
65
+ extractSkillName?: (args: unknown) => string | null;
66
+ /**
67
+ * Default decision when no rule matches. Defaults to `{ allow: true }`
68
+ * to keep non-skill tools unaffected.
69
+ */
70
+ defaultDecision?: SkillsPolicyDecision;
71
+ }
72
+ /**
73
+ * Build a {@link SkillsPolicyHook} from a store and matching options.
74
+ *
75
+ * The returned hook always allows tools that are not skill-like; it only
76
+ * consults the store when {@link CreateSkillsPolicyOptions.isSkillTool}
77
+ * returns true.
78
+ */
79
+ declare function createSkillsPolicy(options: CreateSkillsPolicyOptions): SkillsPolicyHook;
80
+ /**
81
+ * Compose two skills policy hooks. The combined hook denies if either
82
+ * underlying hook denies; allow decisions from `first` are forwarded to
83
+ * `second`.
84
+ */
85
+ declare function combineSkillsPolicies(first: SkillsPolicyHook, second: SkillsPolicyHook): SkillsPolicyHook;
86
+
87
+ export { type CreateSkillsPolicyOptions, DEFAULT_SKILL_TOOL_NAMES, InMemorySkillsPolicyStore, SkillsPolicyDecision, SkillsPolicyHook, type SkillsPolicyStore, type SkillsRule, combineSkillsPolicies, createSkillsPolicy };
package/dist/skills.js ADDED
@@ -0,0 +1,91 @@
1
+ // src/skills.ts
2
+ var DEFAULT_SKILL_TOOL_NAMES = [
3
+ "invoke_skill",
4
+ "run_skill",
5
+ "execute_skill",
6
+ "skill.invoke",
7
+ "skill.run"
8
+ ];
9
+ var InMemorySkillsPolicyStore = class _InMemorySkillsPolicyStore {
10
+ rules;
11
+ constructor(rules = []) {
12
+ this.rules = new Map(rules.map((rule) => [rule.skillName, rule]));
13
+ }
14
+ lookup(skillName) {
15
+ return this.rules.get(skillName) ?? null;
16
+ }
17
+ /** Returns a NEW store with the given rule applied (immutable update). */
18
+ withRule(rule) {
19
+ const next = new Map(this.rules);
20
+ next.set(rule.skillName, rule);
21
+ return new _InMemorySkillsPolicyStore([...next.values()]);
22
+ }
23
+ };
24
+ function createSkillsPolicy(options) {
25
+ const isSkillTool = options.isSkillTool ?? ((toolName) => DEFAULT_SKILL_TOOL_NAMES.includes(toolName));
26
+ const extractSkillName = options.extractSkillName ?? defaultExtractSkillName;
27
+ const defaultDecision = options.defaultDecision ?? {
28
+ allow: true
29
+ };
30
+ return async ({
31
+ toolName,
32
+ args,
33
+ identity
34
+ }) => {
35
+ if (!isSkillTool(toolName)) {
36
+ return defaultDecision;
37
+ }
38
+ const skillName = extractSkillName(args);
39
+ if (skillName === null) {
40
+ return {
41
+ allow: false,
42
+ reason: `Skill tool '${toolName}' invoked without a skill name`
43
+ };
44
+ }
45
+ const rule = await Promise.resolve(options.store.lookup(skillName));
46
+ if (rule === null) {
47
+ return {
48
+ allow: false,
49
+ reason: `No policy entry for skill '${skillName}'`
50
+ };
51
+ }
52
+ if (rule.dids === null) {
53
+ return { allow: true };
54
+ }
55
+ if (rule.dids.includes(identity.did)) {
56
+ return { allow: true };
57
+ }
58
+ return {
59
+ allow: false,
60
+ reason: rule.reason ?? `DID '${identity.did}' is not authorized for skill '${skillName}'`
61
+ };
62
+ };
63
+ }
64
+ function defaultExtractSkillName(args) {
65
+ if (args === null || typeof args !== "object") {
66
+ return null;
67
+ }
68
+ const record = args;
69
+ const skill = record["skill"];
70
+ if (typeof skill === "string" && skill.length > 0) {
71
+ return skill;
72
+ }
73
+ const skillName = record["skillName"];
74
+ if (typeof skillName === "string" && skillName.length > 0) {
75
+ return skillName;
76
+ }
77
+ return null;
78
+ }
79
+ function combineSkillsPolicies(first, second) {
80
+ return async (input) => {
81
+ const a = await Promise.resolve(first(input));
82
+ if (!a.allow) {
83
+ return a;
84
+ }
85
+ return Promise.resolve(second(input));
86
+ };
87
+ }
88
+
89
+ export { DEFAULT_SKILL_TOOL_NAMES, InMemorySkillsPolicyStore, combineSkillsPolicies, createSkillsPolicy };
90
+ //# sourceMappingURL=skills.js.map
91
+ //# sourceMappingURL=skills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/skills.ts"],"names":[],"mappings":"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","file":"skills.js","sourcesContent":["/**\n * Skills policy support for @openagentid/mcp.\n *\n * MCP tools and SKILLS.md entries describe the same thing: a capability\n * an agent can invoke. When an MCP server exposes a tool that proxies\n * skill invocation (typically named `invoke_skill` or any name a host\n * application configures), the middleware consults a skills policy\n * before allowing the call. This file provides the helper that picks the\n * right policy for a given call and a small built-in store implementation\n * suitable for tests and reference implementations.\n */\n\nimport { SkillsPolicyDecision, SkillsPolicyHook } from './types.js';\n\n/**\n * Tool name prefixes that the middleware treats as skill-like by default.\n * Host applications can override the matcher entirely via\n * {@link createSkillsPolicy}.\n */\nexport const DEFAULT_SKILL_TOOL_NAMES: ReadonlyArray<string> = [\n 'invoke_skill',\n 'run_skill',\n 'execute_skill',\n 'skill.invoke',\n 'skill.run',\n];\n\n/**\n * A single rule describing whether a `(skillName, did)` pair is allowed.\n * `null` for `dids` means \"any verified caller\". An empty array means\n * \"no caller\".\n */\nexport interface SkillsRule {\n skillName: string;\n /** DIDs allowed to invoke this skill, or `null` for any. */\n dids: ReadonlyArray<string> | null;\n /** Optional reason emitted when the rule denies a call. */\n reason?: string;\n}\n\n/**\n * Policy store interface — implementations may be in-memory, file-backed\n * by `SKILLS.md`, or fetched from a remote service.\n */\nexport interface SkillsPolicyStore {\n lookup(skillName: string): Promise<SkillsRule | null> | SkillsRule | null;\n}\n\n/**\n * Trivial in-memory store useful in tests and as a starting point for\n * production stores.\n */\nexport class InMemorySkillsPolicyStore implements SkillsPolicyStore {\n private readonly rules: Map<string, SkillsRule>;\n\n constructor(rules: ReadonlyArray<SkillsRule> = []) {\n this.rules = new Map(rules.map((rule) => [rule.skillName, rule]));\n }\n\n lookup(skillName: string): SkillsRule | null {\n return this.rules.get(skillName) ?? null;\n }\n\n /** Returns a NEW store with the given rule applied (immutable update). */\n withRule(rule: SkillsRule): InMemorySkillsPolicyStore {\n const next = new Map(this.rules);\n next.set(rule.skillName, rule);\n return new InMemorySkillsPolicyStore([...next.values()]);\n }\n}\n\nexport interface CreateSkillsPolicyOptions {\n /** The store backing skill lookups. */\n store: SkillsPolicyStore;\n /**\n * Returns true when a tool call should be checked against the skills\n * policy. Defaults to matching the tool name against\n * {@link DEFAULT_SKILL_TOOL_NAMES}.\n */\n isSkillTool?: (toolName: string) => boolean;\n /**\n * Extracts the skill name from the tool's arguments. Defaults to\n * reading `args.skill` or `args.skillName`.\n */\n extractSkillName?: (args: unknown) => string | null;\n /**\n * Default decision when no rule matches. Defaults to `{ allow: true }`\n * to keep non-skill tools unaffected.\n */\n defaultDecision?: SkillsPolicyDecision;\n}\n\n/**\n * Build a {@link SkillsPolicyHook} from a store and matching options.\n *\n * The returned hook always allows tools that are not skill-like; it only\n * consults the store when {@link CreateSkillsPolicyOptions.isSkillTool}\n * returns true.\n */\nexport function createSkillsPolicy(\n options: CreateSkillsPolicyOptions,\n): SkillsPolicyHook {\n const isSkillTool =\n options.isSkillTool ??\n ((toolName: string) => DEFAULT_SKILL_TOOL_NAMES.includes(toolName));\n const extractSkillName =\n options.extractSkillName ?? defaultExtractSkillName;\n const defaultDecision: SkillsPolicyDecision = options.defaultDecision ?? {\n allow: true,\n };\n\n return async ({\n toolName,\n args,\n identity,\n }): Promise<SkillsPolicyDecision> => {\n if (!isSkillTool(toolName)) {\n return defaultDecision;\n }\n\n const skillName = extractSkillName(args);\n if (skillName === null) {\n return {\n allow: false,\n reason: `Skill tool '${toolName}' invoked without a skill name`,\n };\n }\n\n const rule = await Promise.resolve(options.store.lookup(skillName));\n if (rule === null) {\n return {\n allow: false,\n reason: `No policy entry for skill '${skillName}'`,\n };\n }\n\n if (rule.dids === null) {\n return { allow: true };\n }\n\n if (rule.dids.includes(identity.did)) {\n return { allow: true };\n }\n\n return {\n allow: false,\n reason:\n rule.reason ??\n `DID '${identity.did}' is not authorized for skill '${skillName}'`,\n };\n };\n}\n\nfunction defaultExtractSkillName(args: unknown): string | null {\n if (args === null || typeof args !== 'object') {\n return null;\n }\n const record = args as Record<string, unknown>;\n const skill = record['skill'];\n if (typeof skill === 'string' && skill.length > 0) {\n return skill;\n }\n const skillName = record['skillName'];\n if (typeof skillName === 'string' && skillName.length > 0) {\n return skillName;\n }\n return null;\n}\n\n/**\n * Compose two skills policy hooks. The combined hook denies if either\n * underlying hook denies; allow decisions from `first` are forwarded to\n * `second`.\n */\nexport function combineSkillsPolicies(\n first: SkillsPolicyHook,\n second: SkillsPolicyHook,\n): SkillsPolicyHook {\n return async (input): Promise<SkillsPolicyDecision> => {\n const a = await Promise.resolve(first(input));\n if (!a.allow) {\n return a;\n }\n return Promise.resolve(second(input));\n };\n}\n\n/** Re-exported for convenience. */\nexport type {\n SkillsPolicyHook,\n SkillsPolicyDecision,\n VerifiedIdentity,\n} from './types.js';\n"]}
package/dist/types.cjs ADDED
@@ -0,0 +1,10 @@
1
+ 'use strict';
2
+
3
+ // src/types.ts
4
+ var defaultScopeFormat = (toolName) => `mcp:${toolName}:invoke`;
5
+ var defaultRequireScopes = (toolName) => [defaultScopeFormat(toolName)];
6
+
7
+ exports.defaultRequireScopes = defaultRequireScopes;
8
+ exports.defaultScopeFormat = defaultScopeFormat;
9
+ //# sourceMappingURL=types.cjs.map
10
+ //# sourceMappingURL=types.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/types.ts"],"names":[],"mappings":";;;AAkMO,IAAM,kBAAA,GAAqB,CAAC,QAAA,KACjC,CAAA,IAAA,EAAO,QAAQ,CAAA,OAAA;AAMV,IAAM,uBAAuB,CAAC,QAAA,KACnC,CAAC,kBAAA,CAAmB,QAAQ,CAAC","file":"types.cjs","sourcesContent":["/**\n * Public types for @openagentid/mcp.\n *\n * These interfaces describe the contract the middleware expects from an\n * OpenAgent {@link Agent} instance and the surrounding configuration. They are\n * defined locally so the package can be installed without `@openagentid/sdk` in\n * tests, in CI, and in environments where the host application brings its own\n * verifier implementation.\n *\n * The real `@openagentid/sdk` exports types that are structurally compatible\n * with these — there is no runtime dependency.\n */\n\n/**\n * A decentralized identifier following the `did:oas:*` method or any other\n * DID method understood by the configured verifier.\n */\nexport type Did = string;\n\n/**\n * The four pieces of metadata an MCP request carries about the calling\n * agent. Populated by the {@link createClientInterceptor} on the call site\n * and consumed by the server middleware.\n */\nexport interface OpenAgentRequestIdentity {\n /** Caller's DID — typically `did:oas:...`. */\n did: Did;\n /**\n * A signed challenge response or capability token (Arsenal ACT) the\n * server can verify offline. Format is opaque to the middleware.\n */\n proof: string;\n /**\n * Optional bearer-style nonce. Servers may require it for replay\n * protection. Verifiers MUST treat the value as untrusted until\n * verification succeeds.\n */\n nonce?: string;\n /**\n * Free-form context the verifier may use (issuer DID, audience, scopes\n * the caller claims). Always validated against the verifier's policy.\n */\n context?: Record<string, unknown>;\n}\n\n/**\n * The result of running the auth pipeline against an incoming MCP request.\n * Available to post-call hooks and audit log emitters.\n */\nexport interface VerifiedIdentity {\n did: Did;\n scopes: ReadonlyArray<string>;\n /** Audit identifier echoed back to the caller in result `_meta`. */\n auditId: string;\n /** Verifier-issued claims about the caller. */\n claims: Readonly<Record<string, unknown>>;\n}\n\n/**\n * The verifier interface — implemented by `@openagentid/sdk` (production) and\n * by the in-memory test agent shipped here.\n *\n * Implementations MUST be deterministic for a given input and MUST NOT\n * mutate the request identity object.\n */\nexport interface IdentityVerifier {\n verify(\n identity: OpenAgentRequestIdentity,\n requiredScopes: ReadonlyArray<string>,\n ): Promise<VerifiedIdentity>;\n}\n\n/**\n * Minimal Agent surface — only the parts of the OpenAgent SDK Agent that\n * the MCP middleware actually needs.\n */\nexport interface Agent {\n did: Did;\n verifier: IdentityVerifier;\n /**\n * Sign an outbound MCP call so the receiving server can verify the\n * caller. Returns the identity envelope to attach as `_meta.openagent`.\n */\n signRequest(\n toolName: string,\n audience?: Did,\n ): Promise<OpenAgentRequestIdentity>;\n}\n\n/**\n * Result envelope returned by an authenticated tool call. The `auditId` is\n * pushed into `_meta.openagent.audit_id` on the response, so callers can\n * correlate logs end-to-end.\n */\nexport interface AuditedResultMeta {\n audit_id: string;\n verified_did: Did;\n scopes: ReadonlyArray<string>;\n}\n\n/** Per-tool scope deriver. */\nexport type ScopeDeriver = (\n toolName: string,\n args: unknown,\n) => ReadonlyArray<string>;\n\n/**\n * Hook signature for the skills policy. The hook receives the tool name,\n * the arguments, and the verified identity, and decides whether the call\n * should be allowed.\n */\nexport type SkillsPolicyHook = (input: {\n toolName: string;\n args: unknown;\n identity: VerifiedIdentity;\n}) => Promise<SkillsPolicyDecision> | SkillsPolicyDecision;\n\nexport interface SkillsPolicyDecision {\n allow: boolean;\n reason?: string;\n}\n\n/**\n * Hook fired before a tool body executes — after the identity has been\n * verified and the skills policy has approved the call.\n */\nexport type PreCallHook = (input: {\n toolName: string;\n args: unknown;\n identity: VerifiedIdentity;\n}) => Promise<void> | void;\n\n/**\n * Hook fired after a tool body executes successfully. Use it for audit\n * logging, metrics, and trace propagation. Throwing from this hook does\n * NOT roll back the tool call.\n */\nexport type PostCallHook = (input: {\n toolName: string;\n args: unknown;\n identity: VerifiedIdentity;\n durationMs: number;\n result: unknown;\n}) => Promise<void> | void;\n\n/**\n * Hook fired when the tool body or any earlier middleware step throws.\n * The middleware re-throws the error after running this hook so MCP\n * clients still observe the original failure mode.\n */\nexport type ErrorHook = (input: {\n toolName: string;\n args: unknown;\n identity: VerifiedIdentity | null;\n error: unknown;\n}) => Promise<void> | void;\n\n/**\n * Configuration for {@link withOpenAgent}.\n */\nexport interface OpenAgentMcpConfig {\n /** The agent that owns this MCP server (used for outbound signing). */\n agent: Agent;\n /**\n * Per-tool required scope set. Defaults to\n * `(toolName) => [`mcp:${toolName}:invoke`]`.\n */\n requireScopes?: ScopeDeriver;\n /**\n * If true (default), tool calls without an `_meta.openagent.identity`\n * envelope are rejected. Set to false to opt-in to permissive mode for\n * local development — the middleware will still run hooks but skip\n * verification.\n */\n requireIdentity?: boolean;\n /** Optional skills policy hook. */\n skillsPolicy?: SkillsPolicyHook;\n /** Optional pre-call hook. */\n preCall?: PreCallHook;\n /** Optional post-call hook for audit/log emission. */\n postCall?: PostCallHook;\n /** Optional error hook. */\n onError?: ErrorHook;\n /**\n * Override the default `mcp:<tool>:invoke` scope format. Receives the\n * tool name and returns the canonical scope string.\n */\n scopeFormat?: (toolName: string) => string;\n}\n\n/**\n * Default scope format used when {@link OpenAgentMcpConfig.scopeFormat} is\n * not supplied.\n */\nexport const defaultScopeFormat = (toolName: string): string =>\n `mcp:${toolName}:invoke`;\n\n/**\n * Default scope deriver used when {@link OpenAgentMcpConfig.requireScopes}\n * is not supplied.\n */\nexport const defaultRequireScopes = (toolName: string): ReadonlyArray<string> =>\n [defaultScopeFormat(toolName)];\n"]}
@@ -0,0 +1,179 @@
1
+ /**
2
+ * Public types for @openagentid/mcp.
3
+ *
4
+ * These interfaces describe the contract the middleware expects from an
5
+ * OpenAgent {@link Agent} instance and the surrounding configuration. They are
6
+ * defined locally so the package can be installed without `@openagentid/sdk` in
7
+ * tests, in CI, and in environments where the host application brings its own
8
+ * verifier implementation.
9
+ *
10
+ * The real `@openagentid/sdk` exports types that are structurally compatible
11
+ * with these — there is no runtime dependency.
12
+ */
13
+ /**
14
+ * A decentralized identifier following the `did:oas:*` method or any other
15
+ * DID method understood by the configured verifier.
16
+ */
17
+ type Did = string;
18
+ /**
19
+ * The four pieces of metadata an MCP request carries about the calling
20
+ * agent. Populated by the {@link createClientInterceptor} on the call site
21
+ * and consumed by the server middleware.
22
+ */
23
+ interface OpenAgentRequestIdentity {
24
+ /** Caller's DID — typically `did:oas:...`. */
25
+ did: Did;
26
+ /**
27
+ * A signed challenge response or capability token (Arsenal ACT) the
28
+ * server can verify offline. Format is opaque to the middleware.
29
+ */
30
+ proof: string;
31
+ /**
32
+ * Optional bearer-style nonce. Servers may require it for replay
33
+ * protection. Verifiers MUST treat the value as untrusted until
34
+ * verification succeeds.
35
+ */
36
+ nonce?: string;
37
+ /**
38
+ * Free-form context the verifier may use (issuer DID, audience, scopes
39
+ * the caller claims). Always validated against the verifier's policy.
40
+ */
41
+ context?: Record<string, unknown>;
42
+ }
43
+ /**
44
+ * The result of running the auth pipeline against an incoming MCP request.
45
+ * Available to post-call hooks and audit log emitters.
46
+ */
47
+ interface VerifiedIdentity {
48
+ did: Did;
49
+ scopes: ReadonlyArray<string>;
50
+ /** Audit identifier echoed back to the caller in result `_meta`. */
51
+ auditId: string;
52
+ /** Verifier-issued claims about the caller. */
53
+ claims: Readonly<Record<string, unknown>>;
54
+ }
55
+ /**
56
+ * The verifier interface — implemented by `@openagentid/sdk` (production) and
57
+ * by the in-memory test agent shipped here.
58
+ *
59
+ * Implementations MUST be deterministic for a given input and MUST NOT
60
+ * mutate the request identity object.
61
+ */
62
+ interface IdentityVerifier {
63
+ verify(identity: OpenAgentRequestIdentity, requiredScopes: ReadonlyArray<string>): Promise<VerifiedIdentity>;
64
+ }
65
+ /**
66
+ * Minimal Agent surface — only the parts of the OpenAgent SDK Agent that
67
+ * the MCP middleware actually needs.
68
+ */
69
+ interface Agent {
70
+ did: Did;
71
+ verifier: IdentityVerifier;
72
+ /**
73
+ * Sign an outbound MCP call so the receiving server can verify the
74
+ * caller. Returns the identity envelope to attach as `_meta.openagent`.
75
+ */
76
+ signRequest(toolName: string, audience?: Did): Promise<OpenAgentRequestIdentity>;
77
+ }
78
+ /**
79
+ * Result envelope returned by an authenticated tool call. The `auditId` is
80
+ * pushed into `_meta.openagent.audit_id` on the response, so callers can
81
+ * correlate logs end-to-end.
82
+ */
83
+ interface AuditedResultMeta {
84
+ audit_id: string;
85
+ verified_did: Did;
86
+ scopes: ReadonlyArray<string>;
87
+ }
88
+ /** Per-tool scope deriver. */
89
+ type ScopeDeriver = (toolName: string, args: unknown) => ReadonlyArray<string>;
90
+ /**
91
+ * Hook signature for the skills policy. The hook receives the tool name,
92
+ * the arguments, and the verified identity, and decides whether the call
93
+ * should be allowed.
94
+ */
95
+ type SkillsPolicyHook = (input: {
96
+ toolName: string;
97
+ args: unknown;
98
+ identity: VerifiedIdentity;
99
+ }) => Promise<SkillsPolicyDecision> | SkillsPolicyDecision;
100
+ interface SkillsPolicyDecision {
101
+ allow: boolean;
102
+ reason?: string;
103
+ }
104
+ /**
105
+ * Hook fired before a tool body executes — after the identity has been
106
+ * verified and the skills policy has approved the call.
107
+ */
108
+ type PreCallHook = (input: {
109
+ toolName: string;
110
+ args: unknown;
111
+ identity: VerifiedIdentity;
112
+ }) => Promise<void> | void;
113
+ /**
114
+ * Hook fired after a tool body executes successfully. Use it for audit
115
+ * logging, metrics, and trace propagation. Throwing from this hook does
116
+ * NOT roll back the tool call.
117
+ */
118
+ type PostCallHook = (input: {
119
+ toolName: string;
120
+ args: unknown;
121
+ identity: VerifiedIdentity;
122
+ durationMs: number;
123
+ result: unknown;
124
+ }) => Promise<void> | void;
125
+ /**
126
+ * Hook fired when the tool body or any earlier middleware step throws.
127
+ * The middleware re-throws the error after running this hook so MCP
128
+ * clients still observe the original failure mode.
129
+ */
130
+ type ErrorHook = (input: {
131
+ toolName: string;
132
+ args: unknown;
133
+ identity: VerifiedIdentity | null;
134
+ error: unknown;
135
+ }) => Promise<void> | void;
136
+ /**
137
+ * Configuration for {@link withOpenAgent}.
138
+ */
139
+ interface OpenAgentMcpConfig {
140
+ /** The agent that owns this MCP server (used for outbound signing). */
141
+ agent: Agent;
142
+ /**
143
+ * Per-tool required scope set. Defaults to
144
+ * `(toolName) => [`mcp:${toolName}:invoke`]`.
145
+ */
146
+ requireScopes?: ScopeDeriver;
147
+ /**
148
+ * If true (default), tool calls without an `_meta.openagent.identity`
149
+ * envelope are rejected. Set to false to opt-in to permissive mode for
150
+ * local development — the middleware will still run hooks but skip
151
+ * verification.
152
+ */
153
+ requireIdentity?: boolean;
154
+ /** Optional skills policy hook. */
155
+ skillsPolicy?: SkillsPolicyHook;
156
+ /** Optional pre-call hook. */
157
+ preCall?: PreCallHook;
158
+ /** Optional post-call hook for audit/log emission. */
159
+ postCall?: PostCallHook;
160
+ /** Optional error hook. */
161
+ onError?: ErrorHook;
162
+ /**
163
+ * Override the default `mcp:<tool>:invoke` scope format. Receives the
164
+ * tool name and returns the canonical scope string.
165
+ */
166
+ scopeFormat?: (toolName: string) => string;
167
+ }
168
+ /**
169
+ * Default scope format used when {@link OpenAgentMcpConfig.scopeFormat} is
170
+ * not supplied.
171
+ */
172
+ declare const defaultScopeFormat: (toolName: string) => string;
173
+ /**
174
+ * Default scope deriver used when {@link OpenAgentMcpConfig.requireScopes}
175
+ * is not supplied.
176
+ */
177
+ declare const defaultRequireScopes: (toolName: string) => ReadonlyArray<string>;
178
+
179
+ export { type Agent, type AuditedResultMeta, type Did, type ErrorHook, type IdentityVerifier, type OpenAgentMcpConfig, type OpenAgentRequestIdentity, type PostCallHook, type PreCallHook, type ScopeDeriver, type SkillsPolicyDecision, type SkillsPolicyHook, type VerifiedIdentity, defaultRequireScopes, defaultScopeFormat };
@@ -0,0 +1,179 @@
1
+ /**
2
+ * Public types for @openagentid/mcp.
3
+ *
4
+ * These interfaces describe the contract the middleware expects from an
5
+ * OpenAgent {@link Agent} instance and the surrounding configuration. They are
6
+ * defined locally so the package can be installed without `@openagentid/sdk` in
7
+ * tests, in CI, and in environments where the host application brings its own
8
+ * verifier implementation.
9
+ *
10
+ * The real `@openagentid/sdk` exports types that are structurally compatible
11
+ * with these — there is no runtime dependency.
12
+ */
13
+ /**
14
+ * A decentralized identifier following the `did:oas:*` method or any other
15
+ * DID method understood by the configured verifier.
16
+ */
17
+ type Did = string;
18
+ /**
19
+ * The four pieces of metadata an MCP request carries about the calling
20
+ * agent. Populated by the {@link createClientInterceptor} on the call site
21
+ * and consumed by the server middleware.
22
+ */
23
+ interface OpenAgentRequestIdentity {
24
+ /** Caller's DID — typically `did:oas:...`. */
25
+ did: Did;
26
+ /**
27
+ * A signed challenge response or capability token (Arsenal ACT) the
28
+ * server can verify offline. Format is opaque to the middleware.
29
+ */
30
+ proof: string;
31
+ /**
32
+ * Optional bearer-style nonce. Servers may require it for replay
33
+ * protection. Verifiers MUST treat the value as untrusted until
34
+ * verification succeeds.
35
+ */
36
+ nonce?: string;
37
+ /**
38
+ * Free-form context the verifier may use (issuer DID, audience, scopes
39
+ * the caller claims). Always validated against the verifier's policy.
40
+ */
41
+ context?: Record<string, unknown>;
42
+ }
43
+ /**
44
+ * The result of running the auth pipeline against an incoming MCP request.
45
+ * Available to post-call hooks and audit log emitters.
46
+ */
47
+ interface VerifiedIdentity {
48
+ did: Did;
49
+ scopes: ReadonlyArray<string>;
50
+ /** Audit identifier echoed back to the caller in result `_meta`. */
51
+ auditId: string;
52
+ /** Verifier-issued claims about the caller. */
53
+ claims: Readonly<Record<string, unknown>>;
54
+ }
55
+ /**
56
+ * The verifier interface — implemented by `@openagentid/sdk` (production) and
57
+ * by the in-memory test agent shipped here.
58
+ *
59
+ * Implementations MUST be deterministic for a given input and MUST NOT
60
+ * mutate the request identity object.
61
+ */
62
+ interface IdentityVerifier {
63
+ verify(identity: OpenAgentRequestIdentity, requiredScopes: ReadonlyArray<string>): Promise<VerifiedIdentity>;
64
+ }
65
+ /**
66
+ * Minimal Agent surface — only the parts of the OpenAgent SDK Agent that
67
+ * the MCP middleware actually needs.
68
+ */
69
+ interface Agent {
70
+ did: Did;
71
+ verifier: IdentityVerifier;
72
+ /**
73
+ * Sign an outbound MCP call so the receiving server can verify the
74
+ * caller. Returns the identity envelope to attach as `_meta.openagent`.
75
+ */
76
+ signRequest(toolName: string, audience?: Did): Promise<OpenAgentRequestIdentity>;
77
+ }
78
+ /**
79
+ * Result envelope returned by an authenticated tool call. The `auditId` is
80
+ * pushed into `_meta.openagent.audit_id` on the response, so callers can
81
+ * correlate logs end-to-end.
82
+ */
83
+ interface AuditedResultMeta {
84
+ audit_id: string;
85
+ verified_did: Did;
86
+ scopes: ReadonlyArray<string>;
87
+ }
88
+ /** Per-tool scope deriver. */
89
+ type ScopeDeriver = (toolName: string, args: unknown) => ReadonlyArray<string>;
90
+ /**
91
+ * Hook signature for the skills policy. The hook receives the tool name,
92
+ * the arguments, and the verified identity, and decides whether the call
93
+ * should be allowed.
94
+ */
95
+ type SkillsPolicyHook = (input: {
96
+ toolName: string;
97
+ args: unknown;
98
+ identity: VerifiedIdentity;
99
+ }) => Promise<SkillsPolicyDecision> | SkillsPolicyDecision;
100
+ interface SkillsPolicyDecision {
101
+ allow: boolean;
102
+ reason?: string;
103
+ }
104
+ /**
105
+ * Hook fired before a tool body executes — after the identity has been
106
+ * verified and the skills policy has approved the call.
107
+ */
108
+ type PreCallHook = (input: {
109
+ toolName: string;
110
+ args: unknown;
111
+ identity: VerifiedIdentity;
112
+ }) => Promise<void> | void;
113
+ /**
114
+ * Hook fired after a tool body executes successfully. Use it for audit
115
+ * logging, metrics, and trace propagation. Throwing from this hook does
116
+ * NOT roll back the tool call.
117
+ */
118
+ type PostCallHook = (input: {
119
+ toolName: string;
120
+ args: unknown;
121
+ identity: VerifiedIdentity;
122
+ durationMs: number;
123
+ result: unknown;
124
+ }) => Promise<void> | void;
125
+ /**
126
+ * Hook fired when the tool body or any earlier middleware step throws.
127
+ * The middleware re-throws the error after running this hook so MCP
128
+ * clients still observe the original failure mode.
129
+ */
130
+ type ErrorHook = (input: {
131
+ toolName: string;
132
+ args: unknown;
133
+ identity: VerifiedIdentity | null;
134
+ error: unknown;
135
+ }) => Promise<void> | void;
136
+ /**
137
+ * Configuration for {@link withOpenAgent}.
138
+ */
139
+ interface OpenAgentMcpConfig {
140
+ /** The agent that owns this MCP server (used for outbound signing). */
141
+ agent: Agent;
142
+ /**
143
+ * Per-tool required scope set. Defaults to
144
+ * `(toolName) => [`mcp:${toolName}:invoke`]`.
145
+ */
146
+ requireScopes?: ScopeDeriver;
147
+ /**
148
+ * If true (default), tool calls without an `_meta.openagent.identity`
149
+ * envelope are rejected. Set to false to opt-in to permissive mode for
150
+ * local development — the middleware will still run hooks but skip
151
+ * verification.
152
+ */
153
+ requireIdentity?: boolean;
154
+ /** Optional skills policy hook. */
155
+ skillsPolicy?: SkillsPolicyHook;
156
+ /** Optional pre-call hook. */
157
+ preCall?: PreCallHook;
158
+ /** Optional post-call hook for audit/log emission. */
159
+ postCall?: PostCallHook;
160
+ /** Optional error hook. */
161
+ onError?: ErrorHook;
162
+ /**
163
+ * Override the default `mcp:<tool>:invoke` scope format. Receives the
164
+ * tool name and returns the canonical scope string.
165
+ */
166
+ scopeFormat?: (toolName: string) => string;
167
+ }
168
+ /**
169
+ * Default scope format used when {@link OpenAgentMcpConfig.scopeFormat} is
170
+ * not supplied.
171
+ */
172
+ declare const defaultScopeFormat: (toolName: string) => string;
173
+ /**
174
+ * Default scope deriver used when {@link OpenAgentMcpConfig.requireScopes}
175
+ * is not supplied.
176
+ */
177
+ declare const defaultRequireScopes: (toolName: string) => ReadonlyArray<string>;
178
+
179
+ export { type Agent, type AuditedResultMeta, type Did, type ErrorHook, type IdentityVerifier, type OpenAgentMcpConfig, type OpenAgentRequestIdentity, type PostCallHook, type PreCallHook, type ScopeDeriver, type SkillsPolicyDecision, type SkillsPolicyHook, type VerifiedIdentity, defaultRequireScopes, defaultScopeFormat };
package/dist/types.js ADDED
@@ -0,0 +1,7 @@
1
+ // src/types.ts
2
+ var defaultScopeFormat = (toolName) => `mcp:${toolName}:invoke`;
3
+ var defaultRequireScopes = (toolName) => [defaultScopeFormat(toolName)];
4
+
5
+ export { defaultRequireScopes, defaultScopeFormat };
6
+ //# sourceMappingURL=types.js.map
7
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/types.ts"],"names":[],"mappings":";AAkMO,IAAM,kBAAA,GAAqB,CAAC,QAAA,KACjC,CAAA,IAAA,EAAO,QAAQ,CAAA,OAAA;AAMV,IAAM,uBAAuB,CAAC,QAAA,KACnC,CAAC,kBAAA,CAAmB,QAAQ,CAAC","file":"types.js","sourcesContent":["/**\n * Public types for @openagentid/mcp.\n *\n * These interfaces describe the contract the middleware expects from an\n * OpenAgent {@link Agent} instance and the surrounding configuration. They are\n * defined locally so the package can be installed without `@openagentid/sdk` in\n * tests, in CI, and in environments where the host application brings its own\n * verifier implementation.\n *\n * The real `@openagentid/sdk` exports types that are structurally compatible\n * with these — there is no runtime dependency.\n */\n\n/**\n * A decentralized identifier following the `did:oas:*` method or any other\n * DID method understood by the configured verifier.\n */\nexport type Did = string;\n\n/**\n * The four pieces of metadata an MCP request carries about the calling\n * agent. Populated by the {@link createClientInterceptor} on the call site\n * and consumed by the server middleware.\n */\nexport interface OpenAgentRequestIdentity {\n /** Caller's DID — typically `did:oas:...`. */\n did: Did;\n /**\n * A signed challenge response or capability token (Arsenal ACT) the\n * server can verify offline. Format is opaque to the middleware.\n */\n proof: string;\n /**\n * Optional bearer-style nonce. Servers may require it for replay\n * protection. Verifiers MUST treat the value as untrusted until\n * verification succeeds.\n */\n nonce?: string;\n /**\n * Free-form context the verifier may use (issuer DID, audience, scopes\n * the caller claims). Always validated against the verifier's policy.\n */\n context?: Record<string, unknown>;\n}\n\n/**\n * The result of running the auth pipeline against an incoming MCP request.\n * Available to post-call hooks and audit log emitters.\n */\nexport interface VerifiedIdentity {\n did: Did;\n scopes: ReadonlyArray<string>;\n /** Audit identifier echoed back to the caller in result `_meta`. */\n auditId: string;\n /** Verifier-issued claims about the caller. */\n claims: Readonly<Record<string, unknown>>;\n}\n\n/**\n * The verifier interface — implemented by `@openagentid/sdk` (production) and\n * by the in-memory test agent shipped here.\n *\n * Implementations MUST be deterministic for a given input and MUST NOT\n * mutate the request identity object.\n */\nexport interface IdentityVerifier {\n verify(\n identity: OpenAgentRequestIdentity,\n requiredScopes: ReadonlyArray<string>,\n ): Promise<VerifiedIdentity>;\n}\n\n/**\n * Minimal Agent surface — only the parts of the OpenAgent SDK Agent that\n * the MCP middleware actually needs.\n */\nexport interface Agent {\n did: Did;\n verifier: IdentityVerifier;\n /**\n * Sign an outbound MCP call so the receiving server can verify the\n * caller. Returns the identity envelope to attach as `_meta.openagent`.\n */\n signRequest(\n toolName: string,\n audience?: Did,\n ): Promise<OpenAgentRequestIdentity>;\n}\n\n/**\n * Result envelope returned by an authenticated tool call. The `auditId` is\n * pushed into `_meta.openagent.audit_id` on the response, so callers can\n * correlate logs end-to-end.\n */\nexport interface AuditedResultMeta {\n audit_id: string;\n verified_did: Did;\n scopes: ReadonlyArray<string>;\n}\n\n/** Per-tool scope deriver. */\nexport type ScopeDeriver = (\n toolName: string,\n args: unknown,\n) => ReadonlyArray<string>;\n\n/**\n * Hook signature for the skills policy. The hook receives the tool name,\n * the arguments, and the verified identity, and decides whether the call\n * should be allowed.\n */\nexport type SkillsPolicyHook = (input: {\n toolName: string;\n args: unknown;\n identity: VerifiedIdentity;\n}) => Promise<SkillsPolicyDecision> | SkillsPolicyDecision;\n\nexport interface SkillsPolicyDecision {\n allow: boolean;\n reason?: string;\n}\n\n/**\n * Hook fired before a tool body executes — after the identity has been\n * verified and the skills policy has approved the call.\n */\nexport type PreCallHook = (input: {\n toolName: string;\n args: unknown;\n identity: VerifiedIdentity;\n}) => Promise<void> | void;\n\n/**\n * Hook fired after a tool body executes successfully. Use it for audit\n * logging, metrics, and trace propagation. Throwing from this hook does\n * NOT roll back the tool call.\n */\nexport type PostCallHook = (input: {\n toolName: string;\n args: unknown;\n identity: VerifiedIdentity;\n durationMs: number;\n result: unknown;\n}) => Promise<void> | void;\n\n/**\n * Hook fired when the tool body or any earlier middleware step throws.\n * The middleware re-throws the error after running this hook so MCP\n * clients still observe the original failure mode.\n */\nexport type ErrorHook = (input: {\n toolName: string;\n args: unknown;\n identity: VerifiedIdentity | null;\n error: unknown;\n}) => Promise<void> | void;\n\n/**\n * Configuration for {@link withOpenAgent}.\n */\nexport interface OpenAgentMcpConfig {\n /** The agent that owns this MCP server (used for outbound signing). */\n agent: Agent;\n /**\n * Per-tool required scope set. Defaults to\n * `(toolName) => [`mcp:${toolName}:invoke`]`.\n */\n requireScopes?: ScopeDeriver;\n /**\n * If true (default), tool calls without an `_meta.openagent.identity`\n * envelope are rejected. Set to false to opt-in to permissive mode for\n * local development — the middleware will still run hooks but skip\n * verification.\n */\n requireIdentity?: boolean;\n /** Optional skills policy hook. */\n skillsPolicy?: SkillsPolicyHook;\n /** Optional pre-call hook. */\n preCall?: PreCallHook;\n /** Optional post-call hook for audit/log emission. */\n postCall?: PostCallHook;\n /** Optional error hook. */\n onError?: ErrorHook;\n /**\n * Override the default `mcp:<tool>:invoke` scope format. Receives the\n * tool name and returns the canonical scope string.\n */\n scopeFormat?: (toolName: string) => string;\n}\n\n/**\n * Default scope format used when {@link OpenAgentMcpConfig.scopeFormat} is\n * not supplied.\n */\nexport const defaultScopeFormat = (toolName: string): string =>\n `mcp:${toolName}:invoke`;\n\n/**\n * Default scope deriver used when {@link OpenAgentMcpConfig.requireScopes}\n * is not supplied.\n */\nexport const defaultRequireScopes = (toolName: string): ReadonlyArray<string> =>\n [defaultScopeFormat(toolName)];\n"]}