Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/application-keys-mcp-endpoint-tools.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@epcc-sdk/sdks-application-keys": minor
---

`@epcc-sdk/sdks-application-keys` has a new `/mcp` export. It has one Model Context Protocol (MCP) tool factory for each of its 5 operations, such as `listApplicationKeysTool`, and `tools()`, which returns all 5. A factory returns the `name`, `config` and `handler` that `McpServer.registerTool` takes. Without a `client`, a tool uses the package's module level `client`, which has no credentials until you configure it. `@modelcontextprotocol/sdk` is an optional peer dependency. The main entry does not change.
5 changes: 5 additions & 0 deletions .changeset/currencies-mcp-endpoint-tools.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@epcc-sdk/sdks-currencies": minor
---

`@epcc-sdk/sdks-currencies` has a new `/mcp` export. It has one Model Context Protocol (MCP) tool factory for each of its 5 operations, such as `getAllCurrenciesTool`, and `tools()`, which returns all 5. A factory returns the `name`, `config` and `handler` that `McpServer.registerTool` takes. Without a `client`, a tool uses the package's module level `client`, which has no credentials until you configure it. `@modelcontextprotocol/sdk` is an optional peer dependency. The main entry does not change.
5 changes: 5 additions & 0 deletions .changeset/merchant-realm-mapping-mcp-endpoint-tools.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@epcc-sdk/sdks-merchant-realm-mapping": minor
---

`@epcc-sdk/sdks-merchant-realm-mapping` has a new `/mcp` export. It has one Model Context Protocol (MCP) tool factory for each of its 3 operations, such as `getMerchantRealmMappingsTool`, and `tools()`, which returns all 3. A factory returns the `name`, `config` and `handler` that `McpServer.registerTool` takes. Without a `client`, a tool uses the package's module level `client`, which has no credentials until you configure it. `@modelcontextprotocol/sdk` is an optional peer dependency. The main entry does not change.
5 changes: 5 additions & 0 deletions .changeset/permissions-mcp-endpoint-tools.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@epcc-sdk/permissions": minor
---

`@epcc-sdk/permissions` has a new `/mcp` export. It has one Model Context Protocol (MCP) tool factory for each of its 9 operations, such as `listStandardUserRolesTool`, and `tools()`, which returns all 9. A factory returns the `name`, `config` and `handler` that `McpServer.registerTool` takes. Without a `client`, a tool uses the package's module level `client`, which has no credentials until you configure it. `@modelcontextprotocol/sdk` is an optional peer dependency. The main entry does not change.
5 changes: 5 additions & 0 deletions .changeset/personal-data-mcp-endpoint-tools.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@epcc-sdk/personal-data": minor
---

`@epcc-sdk/personal-data` has a new `/mcp` export. It has one Model Context Protocol (MCP) tool factory for each of its 7 operations, such as `getPersonalDataLogsTool`, and `tools()`, which returns all 7. A factory returns the `name`, `config` and `handler` that `McpServer.registerTool` takes. Without a `client`, a tool uses the package's module level `client`, which has no credentials until you configure it. `@modelcontextprotocol/sdk` is an optional peer dependency. The main entry does not change.
5 changes: 5 additions & 0 deletions .changeset/settings-mcp-endpoint-tools.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@epcc-sdk/settings": minor
---

`@epcc-sdk/settings` has a new `/mcp` export. It has one Model Context Protocol (MCP) tool factory for each of its 3 operations, such as `getV2SettingsTool`, and `tools()`, which returns all 3. A factory returns the `name`, `config` and `handler` that `McpServer.registerTool` takes. Without a `client`, a tool uses the package's module level `client`, which has no credentials until you configure it. `@modelcontextprotocol/sdk` is an optional peer dependency. The main entry does not change.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,11 @@ packages/sdks/catalogs/test/.generated-*/
packages/sdks/rule-promotions/test/.generated-*/
packages/sdks/cart-checkout-order/test/.generated-*/
packages/sdks/files/test/.generated-*/
packages/sdks/personal-data/test/.generated-*/
packages/sdks/permissions/test/.generated-*/
packages/sdks/merchant-realm-mapping/test/.generated-*/
packages/sdks/settings/test/.generated-*/
packages/sdks/currencies/test/.generated-*/
packages/sdks/application-keys/test/.generated-*/
.vercel
.pnpm-store/
197 changes: 128 additions & 69 deletions packages/sdks/application-keys/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

Below you'll find instructions on how to install, set up, and use the client, along with a list of available operations.


## Features

- type-safe response data and errors
Expand All @@ -13,7 +12,6 @@ Below you'll find instructions on how to install, set up, and use the client, al

---


## Installation

```bash
Expand All @@ -28,7 +26,6 @@ yarn add @epcc-sdk/sdks-application-keys

## Client Usage


Clients are responsible for sending the actual HTTP requests.

The Fetch client is built as a thin wrapper on top of Fetch API, extending its functionality. If you're already familiar with Fetch, configuring your client will feel like working directly with Fetch API.
Expand All @@ -40,23 +37,22 @@ You can configure the client in two ways:

**When using the operation function to make requests, by default the global client will be used unless another is provided.**


### 1. Configure the internal `client` instance directly

This is the simpler approach. You can call the setConfig() method at the beginning of your application or anytime you need to update the client configuration. You can pass any Fetch API configuration option to setConfig(), and even your own Fetch implementation.

```ts
import { client } from "@epcc-sdk/sdks-application-keys";
import { client } from "@epcc-sdk/sdks-application-keys"

client.setConfig({
// set default base url for requests
baseUrl: 'https://euwest.api.elasticpath.com',
// set default base url for requests
baseUrl: "https://euwest.api.elasticpath.com",

// set default headers for requests
headers: {
Authorization: 'Bearer YOUR_AUTH_TOKEN',
},
});
// set default headers for requests
headers: {
Authorization: "Bearer YOUR_AUTH_TOKEN",
},
})
```

The disadvantage of this approach is that your code may call the client instance before it's configured for the first time. Depending on your use case, you might need to use the second approach.
Expand All @@ -66,27 +62,27 @@ The disadvantage of this approach is that your code may call the client instance
This is useful when you want to use a different instance of the client for different parts of your application or when you want to use different configurations for different parts of your application.

```ts
import { createClient } from "@epcc-sdk/sdks-application-keys";
import { createClient } from "@epcc-sdk/sdks-application-keys"

// Create the client with your API base URL.
const client = createClient({
// set default base url for requests
baseUrl: "https://euwest.api.elasticpath.com",
/**
* Set default headers only for requests made by this client.
*/
headers: {
"Custom-Header": 'My Value',
},
});
// set default base url for requests
baseUrl: "https://euwest.api.elasticpath.com",
/**
* Set default headers only for requests made by this client.
*/
headers: {
"Custom-Header": "My Value",
},
})
```

You can also pass this instance to any SDK function through the client option. This will override the default instance from `import { client } from "@epcc-sdk/sdks-application-keys>".

```ts
const response = await getKey({
client: myClient,
});
client: myClient,
})
```

### Direct configuration
Expand All @@ -95,44 +91,43 @@ Alternatively, you can pass the client configuration options to each SDK functio

```ts
const response = await getKey({
baseUrl: 'https://example.com', // <-- override default configuration
});
baseUrl: "https://example.com", // <-- override default configuration
})
```

## Interceptors (Middleware)

Interceptors (middleware) can be used to modify requests before they're sent or responses before they're returned to your application. They can be added with use and removed with eject. Below is an example request interceptor

```ts
import { client } from "@epcc-sdk/sdks-application-keys";
import { client } from "@epcc-sdk/sdks-application-keys"

// Supports async functions
client.interceptors.request.use(async (request) => {
// do something
return request;
});
// do something
return request
})

client.interceptors.request.eject((request) => {
// do something
return request;
});

// do something
return request
})
```

and an example response interceptor

```ts
import { client } from "@epcc-sdk/sdks-application-keys";
import { client } from "@epcc-sdk/sdks-application-keys"

client.interceptors.response.use((response) => {
// do something
return response;
});
// do something
return response
})

client.interceptors.response.eject((response) => {
// do something
return response;
});
// do something
return response
})
```

> **_Tip:_** To eject, you must provide a reference to the function that was passed to use().
Expand All @@ -146,15 +141,15 @@ source, sets the `auth` hook, refreshes and replays once on a 401, and backs off
import {
createApplicationKeysClient,
listApplicationKeys,
} from "@epcc-sdk/sdks-application-keys";
} from "@epcc-sdk/sdks-application-keys"

const client = createApplicationKeysClient({
baseUrl: "https://euwest.api.elasticpath.com",
clientId: process.env.EPCC_CLIENT_ID!,
clientSecret: process.env.EPCC_CLIENT_SECRET!,
});
})

const { data } = await listApplicationKeys({ client });
const { data } = await listApplicationKeys({ client })
```

Credentials come from `source`, `provider`, `token`, `clientId` plus `clientSecret`, or
Expand All @@ -176,46 +171,117 @@ Zod schemas for every request body, path and response are published under the `/
subpath. `zod` is an optional peer dependency (4.x), so the root entry never imports it.

```ts
import { zApplicationKey } from "@epcc-sdk/sdks-application-keys/zod";
import { zApplicationKey } from "@epcc-sdk/sdks-application-keys/zod"

const key = zApplicationKey.parse(data?.data?.[0]);
const key = zApplicationKey.parse(data?.data?.[0])
```

## MCP endpoint tools

The `/mcp` subpath turns each of the 5 application keys operations into a Model Context Protocol (MCP) tool.
The main entry imports none of it. `zod` 4 and `@modelcontextprotocol/sdk` are needed only for this
subpath.

Each operation has one tool factory, named after its function with `Tool` added, such as
`listApplicationKeysTool`. A factory returns `{ name, config, handler }`, the three arguments that
`McpServer.registerTool` takes. `tools()` returns all 5 in operation order. A handler returns an API
error as an `isError` result and does not throw.

Register one tool:

```ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"
import { listApplicationKeysTool } from "@epcc-sdk/sdks-application-keys/mcp"

const server = new McpServer({ name: "application-keys", version: "1.0.0" })
const tool = listApplicationKeysTool()
server.registerTool(tool.name, tool.config, tool.handler)
```

A tool built without a client calls through the package's module level `client`, like an operation
does. That client has no credentials until you configure it. Configure it once:

```ts
import {
client,
createApplicationKeysClient,
} from "@epcc-sdk/sdks-application-keys"

client.setConfig(
createApplicationKeysClient({ baseUrl, clientId, clientSecret }).getConfig(),
)
```

Register every tool, with a client that sends the same headers on every call:

```ts
import * as applicationKeys from "@epcc-sdk/sdks-application-keys/mcp"

const client = createApplicationKeysClient({
baseUrl,
clientId,
clientSecret,
config: { headers: { "EP-Store-Id": storeId, "EP-Org-Id": orgId } },
})
applicationKeys
.tools({ client })
.forEach((t) => server.registerTool(t.name, t.config, t.handler))
```

Register the read-only tools only:

```ts
applicationKeys
.tools({ client })
.filter((t) => t.config._meta["com.elasticpath/operation"].risk === "read")
.forEach((t) => server.registerTool(t.name, t.config, t.handler))
```

Each tool is named `application_keys_<snake_case_function>`, and its arguments are grouped under `path`,
`query`, `headers` and `body`. The `path`, `query` and `headers` groups reject keys the spec does not
list. The `body` keeps them, so an attribute the spec does not list still reaches the API. The client
supplies the `Authorization` header, so no tool asks for it. Cancelling the MCP request cancels the
HTTP request.

Each tool's description is written for a model choosing between tools: what the tool does, when to
use it rather than a similar tool, and any caveat that changes when to call it, in at most 600
characters. The full spec description stays in the doc comment of the operation's function and its
tool factory.

`config._meta["com.elasticpath/operation"]` holds the operation's `id`, `method`, `path` and `risk`.
The risk is `read`, `create`, `update` or `delete`, and the annotations follow from it.

## Build URL

If you need to access the compiled URL, you can use the buildUrl() method. It's loosely typed by default to accept almost any value; in practice, you will want to pass a type hint.

```ts
type FooData = {
path: {
fooId: number;
};
fooId: number
}
query?: {
bar?: string;
};
url: '/foo/{fooId}';
};
bar?: string
}
url: "/foo/{fooId}"
}

const url = client.buildUrl<FooData>({
path: {
fooId: 1,
},
query: {
bar: 'baz',
bar: "baz",
},
url: '/foo/{fooId}',
});
console.log(url); // prints '/foo/1?bar=baz'
url: "/foo/{fooId}",
})
console.log(url) // prints '/foo/1?bar=baz'
```


---





## Operation Usage

The following examples demonstrate how to use the operation function to make requests.

```ts
Expand All @@ -234,12 +300,8 @@ const product = await getKey({

---



## Available Operations



- **`getAllKeys`** (`GET /v2/application-keys`)

- **`createKey`** (`POST /v2/application-keys`)
Expand All @@ -250,7 +312,4 @@ const product = await getKey({

- **`updateKey`** (`PUT /v2/application-keys/{application_key_id}`)




---
---
Loading