@typeship-ax/mcp 0.21.0 → 0.22.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.
Files changed (129) hide show
  1. package/AGENTS.md +15 -11
  2. package/README.md +22 -53
  3. package/api.json +9998 -10118
  4. package/api.md +8983 -9120
  5. package/dist/arguments.d.ts +47 -0
  6. package/dist/arguments.d.ts.map +1 -0
  7. package/dist/arguments.js +254 -0
  8. package/dist/core/http.d.ts +162 -19
  9. package/dist/core/http.d.ts.map +1 -1
  10. package/dist/core/http.js +381 -48
  11. package/dist/core/pagination.d.ts +42 -6
  12. package/dist/core/pagination.d.ts.map +1 -1
  13. package/dist/core/pagination.js +111 -17
  14. package/dist/credential-storage.d.ts +10 -3
  15. package/dist/credential-storage.d.ts.map +1 -1
  16. package/dist/credential-storage.js +15 -6
  17. package/dist/dates.d.ts +1 -1
  18. package/dist/dates.js +1 -1
  19. package/dist/errors.d.ts +20 -84
  20. package/dist/errors.d.ts.map +1 -1
  21. package/dist/errors.js +20 -108
  22. package/dist/fields.d.ts +29 -0
  23. package/dist/fields.d.ts.map +1 -0
  24. package/dist/fields.js +101 -0
  25. package/dist/index.d.ts +28 -18
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +35 -25
  28. package/dist/mcp-authorization.d.ts.map +1 -1
  29. package/dist/mcp-authorization.js +34 -10
  30. package/dist/mcp-protocol.d.ts +87 -44
  31. package/dist/mcp-protocol.d.ts.map +1 -1
  32. package/dist/mcp-protocol.js +552 -478
  33. package/dist/mcp.d.ts.map +1 -1
  34. package/dist/mcp.js +127 -28
  35. package/dist/named-credentials.d.ts +19 -0
  36. package/dist/named-credentials.d.ts.map +1 -1
  37. package/dist/named-credentials.js +81 -1
  38. package/dist/oauth-request.d.ts +7 -1
  39. package/dist/oauth-request.d.ts.map +1 -1
  40. package/dist/oauth-request.js +26 -4
  41. package/dist/oauth-session.d.ts +13 -1
  42. package/dist/oauth-session.d.ts.map +1 -1
  43. package/dist/oauth-session.js +34 -18
  44. package/dist/ops.d.ts +53 -5
  45. package/dist/ops.d.ts.map +1 -1
  46. package/dist/ops.js +49 -40
  47. package/dist/resources/api-keys.d.ts +10 -7
  48. package/dist/resources/api-keys.d.ts.map +1 -1
  49. package/dist/resources/api-keys.js +10 -31
  50. package/dist/resources/deliveries.d.ts +88 -4
  51. package/dist/resources/deliveries.d.ts.map +1 -1
  52. package/dist/resources/deliveries.js +95 -18
  53. package/dist/resources/drafts.d.ts +15 -15
  54. package/dist/resources/drafts.d.ts.map +1 -1
  55. package/dist/resources/drafts.js +11 -64
  56. package/dist/resources/files.d.ts +4 -4
  57. package/dist/resources/files.d.ts.map +1 -1
  58. package/dist/resources/files.js +3 -12
  59. package/dist/resources/generations.d.ts +14 -14
  60. package/dist/resources/generations.d.ts.map +1 -1
  61. package/dist/resources/generations.js +21 -45
  62. package/dist/resources/organization.d.ts +4 -4
  63. package/dist/resources/organization.d.ts.map +1 -1
  64. package/dist/resources/organization.js +3 -10
  65. package/dist/resources/{generate.d.ts → packages.d.ts} +16 -16
  66. package/dist/resources/packages.d.ts.map +1 -0
  67. package/dist/resources/{generate.js → packages.js} +13 -29
  68. package/dist/resources/projects.d.ts +50 -50
  69. package/dist/resources/projects.d.ts.map +1 -1
  70. package/dist/resources/projects.js +60 -116
  71. package/dist/resources/releases.d.ts +21 -16
  72. package/dist/resources/releases.d.ts.map +1 -1
  73. package/dist/resources/releases.js +18 -39
  74. package/dist/resources/spec-revisions.d.ts +15 -6
  75. package/dist/resources/spec-revisions.d.ts.map +1 -1
  76. package/dist/resources/spec-revisions.js +6 -28
  77. package/dist/resources/specs.d.ts +7 -7
  78. package/dist/resources/specs.d.ts.map +1 -1
  79. package/dist/resources/specs.js +6 -34
  80. package/dist/resources/targets.d.ts +48 -48
  81. package/dist/resources/targets.d.ts.map +1 -1
  82. package/dist/resources/targets.js +58 -114
  83. package/dist/schemas.d.ts.map +1 -1
  84. package/dist/schemas.js +78 -76
  85. package/dist/search.d.ts +54 -0
  86. package/dist/search.d.ts.map +1 -0
  87. package/dist/search.js +421 -0
  88. package/dist/types.d.ts +499 -339
  89. package/dist/types.d.ts.map +1 -1
  90. package/dist/types.js +18 -18
  91. package/dist/worker.js +2 -2
  92. package/package.json +5 -2
  93. package/server.json +5 -5
  94. package/src/arguments.ts +242 -0
  95. package/src/core/http.ts +457 -58
  96. package/src/core/pagination.ts +129 -18
  97. package/src/credential-storage.ts +16 -6
  98. package/src/dates.ts +1 -1
  99. package/src/errors.ts +46 -115
  100. package/src/fields.ts +91 -0
  101. package/src/index.ts +45 -28
  102. package/src/mcp-authorization.ts +29 -9
  103. package/src/mcp-protocol.ts +580 -428
  104. package/src/mcp.ts +113 -26
  105. package/src/named-credentials.ts +66 -1
  106. package/src/oauth-request.ts +32 -6
  107. package/src/oauth-session.ts +37 -19
  108. package/src/ops.ts +82 -44
  109. package/src/resources/api-keys.ts +34 -48
  110. package/src/resources/deliveries.ts +211 -30
  111. package/src/resources/drafts.ts +60 -107
  112. package/src/resources/files.ts +19 -20
  113. package/src/resources/generations.ts +57 -75
  114. package/src/resources/organization.ts +11 -16
  115. package/src/resources/{generate.ts → packages.ts} +43 -51
  116. package/src/resources/projects.ts +145 -200
  117. package/src/resources/releases.ts +48 -65
  118. package/src/resources/spec-revisions.ts +38 -47
  119. package/src/resources/specs.ts +39 -59
  120. package/src/resources/targets.ts +143 -193
  121. package/src/schemas.ts +78 -76
  122. package/src/search.ts +434 -0
  123. package/src/types.ts +538 -357
  124. package/src/worker.ts +2 -2
  125. package/dist/resources/generate.d.ts.map +0 -1
  126. package/dist/resources/publications.d.ts +0 -47
  127. package/dist/resources/publications.d.ts.map +0 -1
  128. package/dist/resources/publications.js +0 -70
  129. package/src/resources/publications.ts +0 -140
package/src/index.ts CHANGED
@@ -1,5 +1,5 @@
1
- // typeship — client entry point.
2
- // Generated by typeship — https://typeship.dev
1
+ // Typeship — client entry point.
2
+ // Generated by Typeship — https://typeship.dev
3
3
 
4
4
  import {
5
5
  HttpCore,
@@ -10,34 +10,33 @@ import {
10
10
  type RequestContext,
11
11
  bearerAuth,
12
12
  } from "./core/http.js";
13
- import { DEFS, SCHEMAS } from "./schemas.js";
14
13
 
15
- import { GenerateResource } from "./resources/generate.js";
16
14
  import { ProjectsResource } from "./resources/projects.js";
17
15
  import { SpecsResource } from "./resources/specs.js";
18
16
  import { SpecRevisionsResource } from "./resources/spec-revisions.js";
19
17
  import { TargetsResource } from "./resources/targets.js";
20
- import { DraftsResource } from "./resources/drafts.js";
21
- import { ReleasesResource } from "./resources/releases.js";
22
18
  import { DeliveriesResource } from "./resources/deliveries.js";
23
- import { PublicationsResource } from "./resources/publications.js";
24
19
  import { GenerationsResource } from "./resources/generations.js";
20
+ import { DraftsResource } from "./resources/drafts.js";
21
+ import { ReleasesResource } from "./resources/releases.js";
25
22
  import { FilesResource } from "./resources/files.js";
23
+ import { PackagesResource } from "./resources/packages.js";
26
24
  import { OrganizationResource } from "./resources/organization.js";
27
25
  import { ApiKeysResource } from "./resources/api-keys.js";
28
26
 
29
27
  /** This package's version, also sent as the `User-Agent`. */
30
- export const VERSION = "0.21.0";
31
- const USER_AGENT = "@typeship-ax/mcp/0.21.0";
28
+ export const VERSION = "0.22.0";
29
+ const USER_AGENT = "@typeship-ax/mcp/0.22.0";
32
30
 
33
31
  export interface ClientOptions {
34
32
  /** Override the server URL. Default: `https://typeship.dev/api/v1` */
35
33
  baseUrl?: string;
36
34
  /**
37
35
  * Sent as `Authorization: Bearer <token>`. Pass a callback for tokens that expire; it is resolved
38
- * before every attempt.
36
+ * before every attempt, and after a 401 it is called once more with `{ rejected: true }` so it
37
+ * can refresh instead of returning the rejected token.
39
38
  */
40
- bearerToken?: string | (() => string | Promise<string>);
39
+ bearerToken?: AuthValue;
41
40
  /**
42
41
  * Credentials keyed by the Spec's security scheme names. Only one complete alternative is sent
43
42
  * for each operation. Named values take precedence over convenience options.
@@ -45,10 +44,15 @@ export interface ClientOptions {
45
44
  credentials?: {
46
45
  "apiKey"?: AuthValue;
47
46
  };
48
- /** Per-attempt timeout in milliseconds. Default: 30000. */
47
+ /** Per-attempt timeout in milliseconds. Default: 60000. */
49
48
  timeoutMs?: number;
50
49
  /** Retries after the first attempt (retryable failures only). Default: 2. */
51
50
  maxRetries?: number;
51
+ /**
52
+ * The longest wait a server may request (Retry-After, x-ratelimit-reset) that a retry honors; a
53
+ * longer one fails the call with the reset time. Default: 60000.
54
+ */
55
+ maxRetryWaitMs?: number;
52
56
  /** Custom fetch implementation (proxies, testing, instrumentation). */
53
57
  fetch?: typeof fetch;
54
58
  /** Headers sent with every request. */
@@ -83,7 +87,7 @@ export interface ClientOptions {
83
87
  }
84
88
 
85
89
  /**
86
- * typeship — v0.21.0
90
+ * Typeship — v0.22.0
87
91
  *
88
92
  * Resolve an OpenAPI or GraphQL Spec, diagnose it, and keep every
89
93
  * selected CLI, MCP, and SDK Target current.
@@ -100,21 +104,22 @@ export interface ClientOptions {
100
104
  * petstore Spec is a runnable sample.
101
105
  */
102
106
  export class TypeshipClient {
103
- readonly generate: GenerateResource;
104
107
  readonly projects: ProjectsResource;
105
108
  readonly specs: SpecsResource;
106
109
  readonly specRevisions: SpecRevisionsResource;
107
110
  readonly targets: TargetsResource;
108
- readonly drafts: DraftsResource;
109
- readonly releases: ReleasesResource;
110
111
  readonly deliveries: DeliveriesResource;
111
- readonly publications: PublicationsResource;
112
112
  readonly generations: GenerationsResource;
113
+ readonly drafts: DraftsResource;
114
+ readonly releases: ReleasesResource;
113
115
  readonly files: FilesResource;
116
+ readonly packages: PackagesResource;
114
117
  readonly organization: OrganizationResource;
115
118
  readonly apiKeys: ApiKeysResource;
119
+ private readonly _options: ClientOptions;
116
120
 
117
121
  constructor(options: ClientOptions = {}) {
122
+ this._options = options;
118
123
  // Identifies this package to the API (ignored by browsers, which
119
124
  // control their own User-Agent); override via defaultHeaders.
120
125
  const headers: Record<string, AuthValue> = { "User-Agent": USER_AGENT, ...options.defaultHeaders };
@@ -157,30 +162,42 @@ export class TypeshipClient {
157
162
  query,
158
163
  credentials,
159
164
  fetch: options.fetch ?? fetch,
160
- timeoutMs: options.timeoutMs ?? 30_000,
165
+ timeoutMs: options.timeoutMs ?? 60_000,
161
166
  maxRetries: options.maxRetries ?? 2,
167
+ maxRetryWaitMs: options.maxRetryWaitMs,
162
168
  onRequest: options.onRequest,
163
169
  onResponse: options.onResponse,
164
170
  onError: options.onError,
165
171
  debug,
166
172
  validate,
167
- schemas: validate ? SCHEMAS : undefined,
168
- schemaDefs: validate ? DEFS : undefined,
173
+ // Loaded on the first validated request, so the schema table costs
174
+ // nothing when validation is off.
175
+ loadSchemas: validate ? () => import("./schemas.js") : undefined,
169
176
  });
170
- this.generate = new GenerateResource(core);
171
177
  this.projects = new ProjectsResource(core);
172
178
  this.specs = new SpecsResource(core);
173
179
  this.specRevisions = new SpecRevisionsResource(core);
174
180
  this.targets = new TargetsResource(core);
175
- this.drafts = new DraftsResource(core);
176
- this.releases = new ReleasesResource(core);
177
181
  this.deliveries = new DeliveriesResource(core);
178
- this.publications = new PublicationsResource(core);
179
182
  this.generations = new GenerationsResource(core);
183
+ this.drafts = new DraftsResource(core);
184
+ this.releases = new ReleasesResource(core);
180
185
  this.files = new FilesResource(core);
186
+ this.packages = new PackagesResource(core);
181
187
  this.organization = new OrganizationResource(core);
182
188
  this.apiKeys = new ApiKeysResource(core);
183
189
  }
190
+
191
+ /**
192
+ * A client with this client's configuration and only these credentials,
193
+ * for a server acting on behalf of many users. Nothing is inherited from
194
+ * this client's credentials. The copy shares the configured fetch.
195
+ */
196
+ withCredentials(credentials: Pick<ClientOptions, "bearerToken" | "credentials">): TypeshipClient {
197
+ const options: Record<string, unknown> = { ...this._options };
198
+ for (const key of ["bearerToken","credentials"]) delete options[key];
199
+ return new TypeshipClient({ ...options, ...credentials } as ClientOptions);
200
+ }
184
201
  }
185
202
 
186
203
  export * from "./types.js";
@@ -188,6 +205,7 @@ export * from "./errors.js";
188
205
  export {
189
206
  formatDebugEvent,
190
207
  type AuthValue,
208
+ type CredentialContext,
191
209
  type DebugEvent,
192
210
  type RequestContext,
193
211
  type RequestOptions,
@@ -195,16 +213,15 @@ export {
195
213
  } from "./core/http.js";
196
214
  export { Page, PagePromise } from "./core/pagination.js";
197
215
 
198
- export * from "./resources/generate.js";
199
216
  export * from "./resources/projects.js";
200
217
  export * from "./resources/specs.js";
201
218
  export * from "./resources/spec-revisions.js";
202
219
  export * from "./resources/targets.js";
203
- export * from "./resources/drafts.js";
204
- export * from "./resources/releases.js";
205
220
  export * from "./resources/deliveries.js";
206
- export * from "./resources/publications.js";
207
221
  export * from "./resources/generations.js";
222
+ export * from "./resources/drafts.js";
223
+ export * from "./resources/releases.js";
208
224
  export * from "./resources/files.js";
225
+ export * from "./resources/packages.js";
209
226
  export * from "./resources/organization.js";
210
227
  export * from "./resources/api-keys.js";
@@ -77,17 +77,35 @@ function decode(value: string): Record<string, unknown> {
77
77
 
78
78
  interface SigningKey { kty?: string; kid?: string; alg?: string; use?: string; key_ops?: string[]; n?: string; e?: string; crv?: string; x?: string; y?: string; d?: string; k?: string }
79
79
 
80
- function principalFor(claims: Record<string, unknown>, configuration: McpAuthorizationConfiguration): McpPrincipal {
80
+ /** Providers name granted scopes in `scope` (RFC 8693/9068, a space-separated
81
+ * string) or `scp` (Okta and Entra: a string or an array of strings). */
82
+ function grantedScopes(claims: Record<string, unknown>): string[] {
83
+ const scopes: string[] = [];
84
+ if (claims.scope !== undefined) {
85
+ if (typeof claims.scope !== "string" || claims.scope.length > 10_000) throw invalid();
86
+ scopes.push(...claims.scope.split(" ").filter(Boolean));
87
+ }
88
+ if (claims.scp !== undefined) {
89
+ if (typeof claims.scp === "string") {
90
+ if (claims.scp.length > 10_000) throw invalid();
91
+ scopes.push(...claims.scp.split(" ").filter(Boolean));
92
+ } else if (Array.isArray(claims.scp) && claims.scp.length <= 100 && claims.scp.every(s => typeof s === "string" && s.length > 0 && s.length <= 500)) {
93
+ scopes.push(...claims.scp as string[]);
94
+ } else throw invalid();
95
+ }
96
+ if (scopes.some(s => !scopePattern.test(s))) throw invalid();
97
+ return scopes;
98
+ }
99
+
100
+ function principalFor(claims: Record<string, unknown>, configuration: McpAuthorizationConfiguration, audience: unknown = claims.aud): McpPrincipal {
81
101
  const now = Date.now() / 1000;
82
- const audiences = typeof claims.aud === "string" ? [claims.aud] : claims.aud;
102
+ const audiences = typeof audience === "string" ? [audience] : audience;
83
103
  if (claims.cnf !== undefined || claims.iss !== configuration.issuer || typeof claims.sub !== "string" || !claims.sub || claims.sub.length > 1000 ||
84
104
  !Array.isArray(audiences) || !audiences.every(a => typeof a === "string") || !audiences.includes(configuration.resource) ||
85
105
  typeof claims.exp !== "number" || !Number.isFinite(claims.exp) || claims.exp <= now ||
86
106
  (claims.nbf !== undefined && (typeof claims.nbf !== "number" || !Number.isFinite(claims.nbf) || claims.nbf > now)) ||
87
- (claims.iat !== undefined && (typeof claims.iat !== "number" || !Number.isFinite(claims.iat) || claims.iat > now + 60)) ||
88
- (claims.scope !== undefined && (typeof claims.scope !== "string" || claims.scope.length > 10_000))) throw invalid();
89
- const scopes = typeof claims.scope === "string" ? claims.scope.split(" ").filter(Boolean) : [];
90
- if (scopes.some(s => !scopePattern.test(s))) throw invalid();
107
+ (claims.iat !== undefined && (typeof claims.iat !== "number" || !Number.isFinite(claims.iat) || claims.iat > now + 60))) throw invalid();
108
+ const scopes = grantedScopes(claims);
91
109
  if (configuration.scopes!.some(s => !scopes.includes(s))) throw new McpAuthorizationError(403, "insufficient_scope");
92
110
  return Object.freeze({ issuer: configuration.issuer, subject: claims.sub, resource: configuration.resource, scopes: Object.freeze([...new Set(scopes)]), claims: Object.freeze(claims) });
93
111
  }
@@ -113,11 +131,13 @@ function introspector(input: McpTokenIntrospectionConfiguration, configuration:
113
131
  if (!data || typeof data.active !== "boolean") throw unavailable();
114
132
  if (!data.active || (data.token_type !== undefined && (typeof data.token_type !== "string" || data.token_type.toLowerCase() !== "bearer"))) throw invalid();
115
133
  // RFC 7662 permits omitted issuer: the owner-pinned authenticated endpoint
116
- // establishes it. Audience, subject and expiry are mandatory for this handler.
117
- // Never substitute client_id for the MCP resource audience.
134
+ // establishes it. Subject and expiry are mandatory for this handler. The
135
+ // audience is `aud`; a provider that omits it must name the exact MCP
136
+ // resource in `resource` instead. Never substitute client_id for it.
118
137
  const claims = { ...data, iss: data.iss === undefined ? configuration.issuer : data.iss };
119
138
  for (const key of ["token", "access_token", "refresh_token", "id_token", "client_secret"]) delete (claims as Record<string, unknown>)[key];
120
- return principalFor(claims, configuration);
139
+ const audience = data.aud === undefined ? data.resource : data.aud;
140
+ return principalFor(claims, configuration, audience);
121
141
  };
122
142
  }
123
143