kopia lustrzana https://github.com/transitive-bullshit/chatgpt-api
docs: WIP work on mintlify docs
rodzic
b140deb203
commit
9a73ec9a83
|
@ -16,8 +16,7 @@ export const copyright = `© ${new Date().getFullYear()} Agentic. All rights res
|
||||||
export const githubUrl = 'https://github.com/transitive-bullshit/agentic'
|
export const githubUrl = 'https://github.com/transitive-bullshit/agentic'
|
||||||
|
|
||||||
// TODO: make an agentic-specific calendar for this
|
// TODO: make an agentic-specific calendar for this
|
||||||
export const calendarBookingUrl =
|
export const calendarBookingUrl = 'https://cal.com/travis-fischer/15min'
|
||||||
'https://cal.com/travis-fischer/15min?overlayCalendar=true'
|
|
||||||
export const docsUrl = 'https://docs.agentic.so'
|
export const docsUrl = 'https://docs.agentic.so'
|
||||||
export const docsQuickStartUrl = `${docsUrl}/quick-start`
|
export const docsQuickStartUrl = `${docsUrl}/quick-start`
|
||||||
export const docsMarketplaceUrl = `${docsUrl}/marketplace`
|
export const docsMarketplaceUrl = `${docsUrl}/marketplace`
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
---
|
||||||
|
title: Contact
|
||||||
|
---
|
||||||
|
|
||||||
|
Agentic's currently a solo team built and run by [Travis Fischer](https://x.com/transitive_bs). 👋
|
||||||
|
|
||||||
|
<Columns cols={2}>
|
||||||
|
<Card
|
||||||
|
title='DM me on Twitter / X'
|
||||||
|
href='https://x.com/transitive_bs'
|
||||||
|
icon='x-twitter'
|
||||||
|
/>
|
||||||
|
<Card
|
||||||
|
title='Send me an email'
|
||||||
|
href='mailto:travis@agentic.so'
|
||||||
|
icon='envelope'
|
||||||
|
/>
|
||||||
|
<Card
|
||||||
|
title='Schedule a call with me'
|
||||||
|
href='https://cal.com/travis-fischer/15min'
|
||||||
|
icon='calendar-days'
|
||||||
|
/>
|
||||||
|
</Columns>
|
||||||
|
|
||||||
|
**TODO**
|
|
@ -10,6 +10,10 @@
|
||||||
"background": {
|
"background": {
|
||||||
"image": "/media/bg.png"
|
"image": "/media/bg.png"
|
||||||
},
|
},
|
||||||
|
"appearance": {
|
||||||
|
"mode": "light",
|
||||||
|
"strict": true
|
||||||
|
},
|
||||||
"colors": {
|
"colors": {
|
||||||
"primary": "#0D969D",
|
"primary": "#0D969D",
|
||||||
"light": "#13D3DC",
|
"light": "#13D3DC",
|
||||||
|
@ -39,7 +43,7 @@
|
||||||
"groups": [
|
"groups": [
|
||||||
{
|
{
|
||||||
"group": "Getting Started",
|
"group": "Getting Started",
|
||||||
"pages": ["index"]
|
"pages": ["index", "marketplace/index"]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -48,7 +52,32 @@
|
||||||
"groups": [
|
"groups": [
|
||||||
{
|
{
|
||||||
"group": "Getting Started",
|
"group": "Getting Started",
|
||||||
"pages": ["publishing/index"]
|
"pages": [
|
||||||
|
"publishing/index",
|
||||||
|
"publishing/quickstart",
|
||||||
|
"publishing/origin-metadata"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group": "Publishing Guides",
|
||||||
|
"pages": [
|
||||||
|
"publishing/guides/existing-mcp-server",
|
||||||
|
"publishing/guides/existing-openapi-service",
|
||||||
|
"publishing/guides/ts-mcp-hono",
|
||||||
|
"publishing/guides/ts-openapi-hono"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group": "Config",
|
||||||
|
"pages": [
|
||||||
|
"publishing/config/index",
|
||||||
|
"publishing/config/auth",
|
||||||
|
"publishing/config/pricing",
|
||||||
|
"publishing/config/rate-limits",
|
||||||
|
"publishing/config/caching",
|
||||||
|
"publishing/config/tool-config",
|
||||||
|
"publishing/config/examples"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -61,7 +90,7 @@
|
||||||
"icon": "house"
|
"icon": "house"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"anchor": "Marketplace",
|
"anchor": "MCP Marketplace",
|
||||||
"href": "https://agentic.so/marketplace",
|
"href": "https://agentic.so/marketplace",
|
||||||
"icon": "store"
|
"icon": "store"
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,15 +1,17 @@
|
||||||
---
|
---
|
||||||
title: Home
|
title: Home
|
||||||
description: Agentic is the app store for LLM tools.
|
description: Agentic is the App Store for LLM Tools.
|
||||||
---
|
---
|
||||||
|
|
||||||
<Columns cols={2}>
|
<Columns cols={2}>
|
||||||
<Card title='MCP Marketplace' href='/marketplace' icon='store'>
|
<Card title='MCP Marketplace' href='/marketplace' icon='store'>
|
||||||
The Agentic MCP Marketplace is a curated collection of high quality LLM
|
Agentic's marketplace is a curated collection of high quality LLM tools
|
||||||
tools – all of which are exposed as both MCP servers and simple HTTP APIs.
|
– all of which are exposed as both MCP servers and simple HTTP APIs.
|
||||||
</Card>
|
</Card>
|
||||||
<Card title='Publishing MCPs' href='/publishing/mcp' icon='upload'>
|
<Card title='Publishing MCPs' href='/publishing' icon='upload'>
|
||||||
Publish any MCP server or OpenAPI service to Agentic's MCP Marketplace and
|
Publish any MCP server or OpenAPI service to Agentic's MCP Marketplace and
|
||||||
offer your LLM tools as products to an audience of over 20k AI engineers.
|
offer your LLM tools as products to an audience of over 20k AI engineers.
|
||||||
</Card>
|
</Card>
|
||||||
</Columns>
|
</Columns>
|
||||||
|
|
||||||
|
**TODO**
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
---
|
||||||
|
title: Quick Start
|
||||||
|
description: A quick start guide to using MCP tools on the Agentic marketplace.
|
||||||
|
---
|
||||||
|
|
||||||
|
<Columns cols={2}>
|
||||||
|
<Card
|
||||||
|
title='Quick Start'
|
||||||
|
href='/marketplace/quick-start'
|
||||||
|
icon='rocket-launch'
|
||||||
|
>
|
||||||
|
TODO
|
||||||
|
</Card>
|
||||||
|
<Card
|
||||||
|
title='View MCP Marketplace'
|
||||||
|
href='https://agentic.so/marketplace'
|
||||||
|
icon='arrow-up-right-from-square'
|
||||||
|
>
|
||||||
|
TODO
|
||||||
|
</Card>
|
||||||
|
</Columns>
|
||||||
|
|
||||||
|
**TODO**
|
|
@ -0,0 +1,86 @@
|
||||||
|
---
|
||||||
|
title: Auth Config
|
||||||
|
description: Configure auth for your Agentic product.
|
||||||
|
---
|
||||||
|
|
||||||
|
Ship to production fast with Agentic's free, hosted authentication. Email & password, OAuth, GitHub, Google, Twitter, etc – if your origin API requires OAuth credentials, Agentic likely already supports it, and if not, [please let us know](/contact).
|
||||||
|
|
||||||
|
Currently, Agentic supports the following auth providers:
|
||||||
|
|
||||||
|
- Email & password
|
||||||
|
- GitHub
|
||||||
|
|
||||||
|
## How it works
|
||||||
|
|
||||||
|
Your product's users will sign into Agentic, subscribe to your product using Stripe, and then be given an API key to use with their tool calls.
|
||||||
|
|
||||||
|
Agentic's MCP gateway will then track all usage of your product based on API keys.
|
||||||
|
|
||||||
|
<Tabs>
|
||||||
|
<Tab title='MCP Origin Server'>
|
||||||
|
Agentic's MCP Gateway will always include the following metadata in all tool calls within the `_meta.agentic` field.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export type AgenticMcpRequestMetadata = {
|
||||||
|
agenticProxySecret: string
|
||||||
|
sessionId: string
|
||||||
|
isCustomerSubscriptionActive: boolean
|
||||||
|
|
||||||
|
customerId?: string
|
||||||
|
customerSubscriptionStatus?: string
|
||||||
|
customerSubscriptionPlan?: string
|
||||||
|
|
||||||
|
userId?: string
|
||||||
|
userEmail?: string
|
||||||
|
userUsername?: string
|
||||||
|
userName?: string
|
||||||
|
userCreatedAt?: string
|
||||||
|
userUpdatedAt?: string
|
||||||
|
|
||||||
|
deploymentId: string
|
||||||
|
deploymentIdentifier: string
|
||||||
|
projectId: string
|
||||||
|
projectIdentifier: string
|
||||||
|
|
||||||
|
ip?: string
|
||||||
|
} & (
|
||||||
|
| {
|
||||||
|
// If the customer has an active subscription, these fields are guaranteed
|
||||||
|
// to be present in the metadata.
|
||||||
|
isCustomerSubscriptionActive: true
|
||||||
|
|
||||||
|
customerId: string
|
||||||
|
customerSubscriptionStatus: string
|
||||||
|
|
||||||
|
userId: string
|
||||||
|
userEmail: string
|
||||||
|
userUsername: string
|
||||||
|
userCreatedAt: string
|
||||||
|
userUpdatedAt: string
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
// If the customer does not have an active subscription, then the customer
|
||||||
|
// fields may or may not be present.
|
||||||
|
isCustomerSubscriptionActive: false
|
||||||
|
}
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
If a customer doesn't provide an API key, they'll default to your `free` pricing plan with `isCustomerSubscriptionActive` set to `false`.
|
||||||
|
|
||||||
|
</Tab>
|
||||||
|
|
||||||
|
<Tab title='OpenAPI Origin Server'>TODO</Tab>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
|
## Alpha Features
|
||||||
|
|
||||||
|
### MCP OAuth
|
||||||
|
|
||||||
|
Agentic's MCP Gateway is designed to interop with MCP's built-in OAuth support, but this functionality is currently in alpha and not enabled publicly by default. If you're interested in using your origin server's MCP authentication support, [please let us know](/contact).
|
||||||
|
|
||||||
|
### Custom OAuth Providers
|
||||||
|
|
||||||
|
Agentic's MCP Gateway is designed to support any third-party OAuth provider (Google, Twitter / X, Slack, Airtable, Shopify, etc), but this functionality is currently in alpha and not enabled publicly by default.
|
||||||
|
|
||||||
|
If you're interested in using a different OAuth provider or want your customers to use your own OAuth client credentials or custom scopes, [please let us know](/contact).
|
|
@ -0,0 +1,94 @@
|
||||||
|
---
|
||||||
|
title: Caching Config
|
||||||
|
description: Configure caching for your Agentic product's tools.
|
||||||
|
---
|
||||||
|
|
||||||
|
Opt-in to caching with familiar _cache-control_ and _stale-while-revalidate_ options. MCP tool calls include caching information in their _\_meta_ fields, providing parity with standard HTTP headers.
|
||||||
|
|
||||||
|
Agentic uses Cloudflare's global edge cache for caching, which guarantees unmatched global performance.
|
||||||
|
|
||||||
|
## Enabling Caching
|
||||||
|
|
||||||
|
You can enable caching for individual tools by setting [pure](/publishing/config/tool-config#param-pure) or [cacheControl](/publishing/config/tool-config#param-cache-control) on the tool's config.
|
||||||
|
|
||||||
|
## Cache Keys
|
||||||
|
|
||||||
|
Cache keys for tool calls are generated by normalizing the tool call's input, regardless of whether the tool call was made via `HTTP POST`, `HTTP GET`, or `MCP`.
|
||||||
|
|
||||||
|
Tool call args will be hashed using a deterministic, stable JSON serialization algorithm, so tool calls with semantically identical input will have identical cache keys.
|
||||||
|
|
||||||
|
## Disabling Caching
|
||||||
|
|
||||||
|
Individual tool calls can disable caching by setting the standard `Cache-Control` header to `no-store` or `no-cache`.
|
||||||
|
|
||||||
|
<Note>
|
||||||
|
Note that by default, caching is disabled for all tools. You must explicitly
|
||||||
|
enable caching for each tool in your Agentic project config.
|
||||||
|
</Note>
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
<Tabs>
|
||||||
|
<Tab title="Pure Tool">
|
||||||
|
|
||||||
|
```ts agentic.config.ts
|
||||||
|
import { defineConfig } from '@agentic/platform'
|
||||||
|
|
||||||
|
// In this example, `my-tool` is marked as pure which means its responses
|
||||||
|
// will be cached aggressively for identical requests using `cache-control`
|
||||||
|
// `public, max-age=31560000, s-maxage=31560000, stale-while-revalidate=3600`
|
||||||
|
export default defineConfig({
|
||||||
|
// ...
|
||||||
|
toolConfigs: [
|
||||||
|
{
|
||||||
|
name: 'my-tool',
|
||||||
|
pure: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
</Tab>
|
||||||
|
|
||||||
|
<Tab title="Custom Cache-Control">
|
||||||
|
|
||||||
|
```ts agentic.config.ts
|
||||||
|
import { defineConfig } from '@agentic/platform'
|
||||||
|
|
||||||
|
// In this example, `my-tool` is using a custom `Cache-Control` header to
|
||||||
|
// cache responses for 60 seconds.
|
||||||
|
export default defineConfig({
|
||||||
|
// ...
|
||||||
|
toolConfigs: [
|
||||||
|
{
|
||||||
|
name: 'my-tool',
|
||||||
|
cacheControl: 'public, max-age=60, s-maxage=60 stale-while-revalidate=10'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
</Tab>
|
||||||
|
|
||||||
|
<Tab title="Disabling Caching">
|
||||||
|
|
||||||
|
```ts agentic.config.ts
|
||||||
|
import { defineConfig } from '@agentic/platform'
|
||||||
|
|
||||||
|
// In this example, `my-tool` results will never be cached.
|
||||||
|
// Note that this is the default behavior for all tools unless caching is
|
||||||
|
// explicitly enabled for a tool.
|
||||||
|
export default defineConfig({
|
||||||
|
// ...
|
||||||
|
toolConfigs: [
|
||||||
|
{
|
||||||
|
name: 'my-tool',
|
||||||
|
cacheControl: 'no-cache'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
</Tab>
|
||||||
|
|
||||||
|
</Tabs>
|
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
title: Examples
|
||||||
|
description: Example Agentic config files.
|
||||||
|
---
|
||||||
|
|
||||||
|
**TODO**
|
|
@ -0,0 +1,169 @@
|
||||||
|
---
|
||||||
|
title: Overview
|
||||||
|
description: Configuring your Agentic project.
|
||||||
|
---
|
||||||
|
|
||||||
|
Every Agentic project needs a config file (`agentic.config.ts`, `agentic.config.js`, or `agentic.config.json`) to define the project's metadata, pricing, rate-limits, and any tool-specific behavior overrides.
|
||||||
|
|
||||||
|
<Note>
|
||||||
|
Configuring your project can feel a little overwhelming. Feel free to [reach
|
||||||
|
out to us](/contact) if you're considering using Agentic's MCP Gateway, and
|
||||||
|
I'd be happy to help walk you through getting your product set up for success.
|
||||||
|
</Note>
|
||||||
|
|
||||||
|
## Config Fields
|
||||||
|
|
||||||
|
<ResponseField name='name' type='string' required>
|
||||||
|
Display name for your project.
|
||||||
|
|
||||||
|
Max length 1024 characters.
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='slug' type='string' required>
|
||||||
|
Unique project slug.
|
||||||
|
|
||||||
|
Must be ascii-only, lower-case, and kebab-case with no spaces between 1 and 256 characters.
|
||||||
|
|
||||||
|
The project's fully qualified identifier will be `@namespace/slug`, where
|
||||||
|
the `namespace` is determined by the author's `username` or team slug.
|
||||||
|
|
||||||
|
If not provided, it will be derived by slugifying `name`.
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='description' type='string' required>
|
||||||
|
Short description of the project.
|
||||||
|
|
||||||
|
Should be no longer than a few lines.
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='version' type='string'>
|
||||||
|
Optional semantic version of the project as a [semver](https://semver.org) string.
|
||||||
|
|
||||||
|
Examples: `1.0.0`, `0.0.1`, `5.0.1`, etc.
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='readme' type='string'>
|
||||||
|
Optional embedded markdown readme documenting the project. Supports
|
||||||
|
GitHub-flavored markdown.
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='iconUrl' type='string'>
|
||||||
|
Optional logo image URL to use for the project. Logos should have a square
|
||||||
|
aspect ratio.
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='sourceUrl' type='string'>
|
||||||
|
Optional URL to the source code of the project (eg, GitHub repo).
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='origin' type='object' required>
|
||||||
|
Origin API adapter used to configure the origin API server downstream from
|
||||||
|
Agentic's API gateway.
|
||||||
|
|
||||||
|
<Expandable title="properties" defaultOpen>
|
||||||
|
<Tabs>
|
||||||
|
<Tab title="MCP origin server">
|
||||||
|
<ResponseField name="type" type="string" required>
|
||||||
|
The type of origin server. `mcp` in this case.
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name="url" type="string" required>
|
||||||
|
|
||||||
|
Required base URL of the externally hosted origin MCP server.
|
||||||
|
|
||||||
|
This URL must be accessible from Agentic's API gateway and support the Streamable HTTP transport.
|
||||||
|
|
||||||
|
Must be a valid `https` URL.
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
</Tab>
|
||||||
|
|
||||||
|
<Tab title="OpenAPI origin server">
|
||||||
|
<ResponseField name="type" type="string" required>
|
||||||
|
The type of origin server. `openapi` in this case.
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name="url" type="string" required>
|
||||||
|
|
||||||
|
Required base URL of the externally hosted origin API server.
|
||||||
|
|
||||||
|
Must be a valid `https` URL.
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name="spec" type="string" required>
|
||||||
|
|
||||||
|
Local file path or URL to an OpenAPI 3.x spec describing the origin API server.
|
||||||
|
|
||||||
|
May also be an embedded string containing a JSON stringified OpenAPI 3.x spec.
|
||||||
|
|
||||||
|
Note that older OpenAPI versions are not supported.
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
</Tab>
|
||||||
|
</Tabs>
|
||||||
|
</Expandable>
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='pricingPlans' type='array'>
|
||||||
|
List of PricingPlans configuring which Stripe subscriptions should be available for the project.
|
||||||
|
|
||||||
|
Defaults to a single free plan which is useful for developing and testing your project.
|
||||||
|
|
||||||
|
See [PricingPlan](/publishing/config/pricing#pricing-plan-config) for details.
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='pricingIntervals' type='array'>
|
||||||
|
Optional list of billing intervals to enable in pricing plans.
|
||||||
|
|
||||||
|
Defaults to a single monthly interval `['month']`.
|
||||||
|
|
||||||
|
To add support for annual pricing plans, for example, you can use:
|
||||||
|
`['month', 'year']`.
|
||||||
|
|
||||||
|
Note that for every pricing interval, you must define a corresponding set
|
||||||
|
of PricingPlans in the `pricingPlans` array. If you only have one pricing
|
||||||
|
interval (like the default `month` interval), `pricingPlans` don't need to
|
||||||
|
specify their `interval` property. Otherwise, all PricingPlans must
|
||||||
|
specify their `interval` property to differentiate between different
|
||||||
|
pricing intervals.
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='defaultRateLimit' type='object'>
|
||||||
|
Optional default rate limits to enforce across all pricing plans.
|
||||||
|
|
||||||
|
If not set, a default platform rate-limit of 1000 requests per minute per customer will be used.
|
||||||
|
|
||||||
|
To disable the default rate-limit, set `defaultRateLimit.enabled` to
|
||||||
|
`false`.
|
||||||
|
|
||||||
|
Note that pricing-plan-specific rate-limits override this default (via
|
||||||
|
`pricingPlans`), and tool-specific rate-limits may override both default
|
||||||
|
and pricing-plan-specific rate-limits (via `toolConfigs`).
|
||||||
|
|
||||||
|
See [Rate Limits](/publishing/config/rate-limits) for more details.
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='toolConfigs' type='array'>
|
||||||
|
Optional list of tool configs to override the default behavior of specific tools.
|
||||||
|
|
||||||
|
See [Tool Config](/publishing/config/tool-config) for details.
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
## Config Help
|
||||||
|
|
||||||
|
<Note>
|
||||||
|
Configuring your project can feel a little overwhelming. Feel free to [reach
|
||||||
|
out to us](/contact) if you're considering using Agentic's MCP Gateway, and
|
||||||
|
I'd be happy to help walk you through getting your product set up for success.
|
||||||
|
</Note>
|
|
@ -0,0 +1,428 @@
|
||||||
|
---
|
||||||
|
title: Pricing Config
|
||||||
|
description: Configure pricing for your Agentic product.
|
||||||
|
---
|
||||||
|
|
||||||
|
Charge for your Agentic product with a flexible, declarative pricing model built on top of [Stripe](https://stripe.com).
|
||||||
|
|
||||||
|
Agentic supports almost any combination of **fixed** and **usage-based billing** billing models, both at the MCP level, at the tool-call level, and at the custom metric level (e.g., tokens, image transformations, etc).
|
||||||
|
|
||||||
|
<Note>
|
||||||
|
Pricing can feel a little complicated to set up. Feel free to [reach out to
|
||||||
|
us](/contact) once you're ready to start charging for your product, and I'd be
|
||||||
|
happy to help you set everything up.
|
||||||
|
</Note>
|
||||||
|
|
||||||
|
## Pricing Plan Config
|
||||||
|
|
||||||
|
<ResponseField name="name" type="string" required>
|
||||||
|
Display name for the pricing plan.
|
||||||
|
|
||||||
|
Examples: "Free", "Starter Monthly", "Pro Annual", etc.
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='slug' type='string' required>
|
||||||
|
A unique slug for the pricing plan which acts as a stable identifier across deployments.
|
||||||
|
|
||||||
|
Should be lower-kebab-cased.
|
||||||
|
Should be stable across deployments.
|
||||||
|
|
||||||
|
For all plans aside from `free`, the `slug` should include the `interval`
|
||||||
|
as a suffix so pricing plans can be uniquely differentiated from each
|
||||||
|
other across billing intervals.
|
||||||
|
|
||||||
|
Examples: `free`, `starter-monthly`, `pro-annual`, etc.
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='interval' type='string' default='month'>
|
||||||
|
The frequency at which this subscription is billed.
|
||||||
|
|
||||||
|
One of `day`, `week`, `month`, or `year`.
|
||||||
|
|
||||||
|
[Stripe docs](https://docs.stripe.com/api/prices/object?api-version=2025-02-24.acacia#price_object-recurring-interval)
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='description' type='string'>
|
||||||
|
Optional description of the pricing plan (UI-only).
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='features' type='array'>
|
||||||
|
Optional list of features of the pricing plan (UI-only; array of strings).
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='trialPeriodDays' type='number'>
|
||||||
|
Optional number of days for a free trial period when a customer signs up for a
|
||||||
|
new subscription.
|
||||||
|
|
||||||
|
[Stripe docs](https://docs.stripe.com/api/subscriptions/create?api-version=2025-05-28.preview#create_subscription-trial_period_days)
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='rateLimit' type='object'>
|
||||||
|
Optional rate limit to enforce for customers on this pricing plan.
|
||||||
|
|
||||||
|
You can use this to limit the number of API requests that can be made by
|
||||||
|
a customer during a given interval.
|
||||||
|
|
||||||
|
If not set, the pricing plan will inherit the default platform rate-limit
|
||||||
|
set by `defaultRateLimit` in the Agentic project config.
|
||||||
|
|
||||||
|
You can disable rate-limiting for this pricing plan by setting
|
||||||
|
`rateLimit.enabled` to `false`.
|
||||||
|
|
||||||
|
See [Rate Limits](/publishing/config/rate-limits) for more details.
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='lineItems' type='array' required>
|
||||||
|
List of LineItems which are included in the PricingPlan.
|
||||||
|
|
||||||
|
Note: Agentic currently supports a max of 20 LineItems per pricing plan.
|
||||||
|
|
||||||
|
See [PricingPlanLineItem](#pricing-plan-line-item-config) for details.
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
## Pricing Plan Line Item Config
|
||||||
|
|
||||||
|
Each Pricing Plan Line Item corresponds to one [Stripe Product](https://docs.stripe.com/api/products/object?api-version=2025-05-28.preview), one [Stripe Price](https://docs.stripe.com/api/prices/object?api-version=2025-05-28.preview), and possibly one [Stripe Meter](https://docs.stripe.com/api/billing/meter/object?api-version=2025-05-28.preview) if the line-item is `metered`.
|
||||||
|
|
||||||
|
<ResponseField name='slug' type='string' required>
|
||||||
|
Slugs act as the primary key for LineItems. They should be lower-cased and
|
||||||
|
kebab-cased ("base", "requests", "image-transformations").
|
||||||
|
|
||||||
|
The `base` slug is reserved for a plan's default `licensed` line-item.
|
||||||
|
|
||||||
|
The `requests` slug is reserved for charging using `metered` billing based
|
||||||
|
on the number of request made during a given billing interval.
|
||||||
|
|
||||||
|
All other PricingPlanLineItem `slugs` are considered custom LineItems.
|
||||||
|
|
||||||
|
Should be stable across deployments, so if a slug refers to one type of
|
||||||
|
product / line-item / metric in one deployment, it should refer to the same
|
||||||
|
product / line-item / metric in future deployments, even if they are
|
||||||
|
configured differently. If you are switching between a licensed and metered
|
||||||
|
line-item across deployments, they must use different slugs.
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='label' type='string'>
|
||||||
|
Optional label for the line-item which will be displayed on customer bills.
|
||||||
|
|
||||||
|
If unset, the line-item's `slug` will be used as the label.
|
||||||
|
|
||||||
|
[Stripe Docs](https://docs.stripe.com/api/products/object?api-version=2025-02-24.acacia#product_object-unit_label)
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='usageType' type='string' required>
|
||||||
|
The type of usage to charge for. Either `licensed` or `metered`.
|
||||||
|
|
||||||
|
[Stripe docs](https://docs.stripe.com/api/prices/object?api-version=2025-02-24.acacia#price_object-recurring-usage_type)
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<Tabs>
|
||||||
|
<Tab title="Licensed Line Item">
|
||||||
|
Licensed line-items are used to charge for **fixed-price services**.
|
||||||
|
|
||||||
|
<ResponseField name='usageType' type='string' required>
|
||||||
|
The type of usage to charge for. `licensed` in this case.
|
||||||
|
|
||||||
|
[Stripe docs](https://docs.stripe.com/api/prices/object?api-version=2025-02-24.acacia#price_object-recurring-usage_type)
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='amount' type='number' required>
|
||||||
|
The fixed amount to charge per billing interval.
|
||||||
|
|
||||||
|
Specified in the smallest currency unit (e.g. cents for USD).
|
||||||
|
|
||||||
|
So 100 = \$1.00 USD, 1000 = \$10.00 USD, etc.
|
||||||
|
|
||||||
|
[Stripe docs](https://docs.stripe.com/api/prices/create?api-version=2025-05-28.preview#create_price-unit_amount)
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
</Tab>
|
||||||
|
|
||||||
|
<Tab title="Metered Line Item">
|
||||||
|
Metered line-items are used to charge for **usage-based services**.
|
||||||
|
|
||||||
|
<ResponseField name='usageType' type='string' required>
|
||||||
|
The type of usage to charge for. `metered` in this case.
|
||||||
|
|
||||||
|
[Stripe docs](https://docs.stripe.com/api/prices/object?api-version=2025-02-24.acacia#price_object-recurring-usage_type)
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='unitLabel' type='string'>
|
||||||
|
Optional label for the line-item which will be displayed on customer bills.
|
||||||
|
|
||||||
|
If unset, the line-item's `slug` will be used as the unit label.
|
||||||
|
|
||||||
|
[Stripe Docs](https://docs.stripe.com/api/products/object?api-version=2025-02-24.acacia#product_object-unit_label)
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='billingScheme' type='string' required>
|
||||||
|
Describes how to compute the price per period. Either `per_unit` or `tiered`.
|
||||||
|
|
||||||
|
`per_unit` indicates that the fixed amount (specified in `unitAmount`) will be charged per unit of total usage.
|
||||||
|
|
||||||
|
`tiered` indicates that the unit pricing will be computed using a tiering strategy as defined using `tiers` and `tiersMode`.
|
||||||
|
|
||||||
|
[Stripe docs](https://docs.stripe.com/api/prices/object?api-version=2025-02-24.acacia#price_object-billing_scheme)
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='unitAmount' type='number' required>
|
||||||
|
The fixed amount to charge per unit of usage.
|
||||||
|
|
||||||
|
Only applicable for `per_unit` billing schemes.
|
||||||
|
|
||||||
|
Specified in the smallest currency unit (e.g. cents for USD).
|
||||||
|
|
||||||
|
So 100 = \$1.00 USD, 1000 = \$10.00 USD, etc.
|
||||||
|
|
||||||
|
[Stripe docs](https://docs.stripe.com/api/prices/object?api-version=2025-02-24.acacia#price_object-unit_amount)
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='tiersMode' type='string'>
|
||||||
|
Defines if the tiering price should be `graduated` or `volume` based.
|
||||||
|
|
||||||
|
In `volume`-based tiering, the maximum quantity within a period
|
||||||
|
determines the per unit price.
|
||||||
|
|
||||||
|
In `graduated`-based tiering, the per-unit price changes successively
|
||||||
|
as the quantity grows.
|
||||||
|
|
||||||
|
This field requires `billingScheme` to be set to `tiered`.
|
||||||
|
|
||||||
|
[Stripe docs](https://docs.stripe.com/api/prices/object?api-version=2025-02-24.acacia#price_object-tiers_mode)
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='tiers' type='array'>
|
||||||
|
Pricing tiers for `tiered` billing schemes.
|
||||||
|
|
||||||
|
This field requires `billingScheme` to be set to `tiered`.
|
||||||
|
|
||||||
|
One of `unitAmount` or `flatAmount` must be provided, but not both.
|
||||||
|
|
||||||
|
[Stripe docs](https://docs.stripe.com/api/prices/object?api-version=2025-02-24.acacia#price_object-tiers)
|
||||||
|
|
||||||
|
<Expandable title="properties">
|
||||||
|
<ResponseField name='upTo' type='number' required>
|
||||||
|
The maximum quantity of usage for this tier.
|
||||||
|
|
||||||
|
Should be a number or `inf` for the maximum tier.
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='unitAmount' type='number'>
|
||||||
|
The fixed amount to charge per unit of usage for this pricing tier.
|
||||||
|
|
||||||
|
Specified in the smallest currency unit (e.g. cents for USD).
|
||||||
|
|
||||||
|
So 100 = \$1.00 USD, 1000 = \$10.00 USD, etc.
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='flatAmount' type='number'>
|
||||||
|
The fixed amount to charge per billing interval for this pricing tier.
|
||||||
|
|
||||||
|
Specified in the smallest currency unit (e.g. cents for USD).
|
||||||
|
|
||||||
|
So 100 = \$1.00 USD, 1000 = \$10.00 USD, etc.
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
</Expandable>
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='defaultAggregation' type='object' default="{ formula: 'sum' }">
|
||||||
|
Specifies how events are aggregated for the Stripe Meter.
|
||||||
|
|
||||||
|
[Stripe docs](https://docs.stripe.com/api/billing/meter/create?api-version=2025-02-24.acacia#create_billing_meter-default_aggregation)
|
||||||
|
|
||||||
|
<Expandable title="properties">
|
||||||
|
<ResponseField name='formula' type='string' default='sum' required>
|
||||||
|
Specifies how events are aggregated for a Stripe Meter.
|
||||||
|
|
||||||
|
Allowed values:
|
||||||
|
|
||||||
|
- `sum` - Sum each event's value during the period.
|
||||||
|
- `count` - Count the number of events during the period.
|
||||||
|
|
||||||
|
If not set, `sum` will be used.
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
</Expandable>
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='transformQuantity' type='object'>
|
||||||
|
Optional transformation to apply to the reported usage or set quantity before computing the amount billed.
|
||||||
|
|
||||||
|
Cannot be combined with `tiers`.
|
||||||
|
|
||||||
|
[Stripe docs](https://docs.stripe.com/api/prices/object?api-version=2025-02-24.acacia#price_object-transform_quantity)
|
||||||
|
|
||||||
|
<Expandable title="properties">
|
||||||
|
<ResponseField name='divideBy' type='number' required>
|
||||||
|
Divide usage by this number.
|
||||||
|
|
||||||
|
Must be a positive number.
|
||||||
|
|
||||||
|
[Stripe docs](https://docs.stripe.com/api/prices/object?api-version=2025-02-24.acacia#price_object-transform_quantity-divide_by)
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='round' type='string' required>
|
||||||
|
After division, either round the result `up` or `down`.
|
||||||
|
|
||||||
|
[Stripe docs](https://docs.stripe.com/api/prices/object?api-version=2025-02-24.acacia#price_object-transform_quantity-round)
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
</Expandable>
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
</Tab>
|
||||||
|
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
|
## Example Pricing Plans
|
||||||
|
|
||||||
|
<Tabs>
|
||||||
|
<Tab title="Default Free Plan">
|
||||||
|
|
||||||
|
This example shows a free monthly pricing plan which is used by default for projects that don't specify any pricing plans.
|
||||||
|
|
||||||
|
```ts agentic.config.ts
|
||||||
|
import { defineConfig } from '@agentic/platform'
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
// ...
|
||||||
|
pricingPlans: [
|
||||||
|
{
|
||||||
|
name: 'Free',
|
||||||
|
slug: 'free',
|
||||||
|
lineItems: [
|
||||||
|
{
|
||||||
|
slug: 'base',
|
||||||
|
usageType: 'licensed',
|
||||||
|
amount: 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
</Tab>
|
||||||
|
|
||||||
|
<Tab title="Freemium + $4.99 Basic Plan">
|
||||||
|
|
||||||
|
This example has 2 pricing plans, the default free plan and a fixed-price $4.99 / month basic plan with a 7-day trial.
|
||||||
|
|
||||||
|
```ts agentic.config.ts
|
||||||
|
import { defaultFreePricingPlan, defineConfig } from '@agentic/platform'
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
// ...
|
||||||
|
pricingPlans: [
|
||||||
|
defaultFreePricingPlan,
|
||||||
|
{
|
||||||
|
name: 'Basic',
|
||||||
|
slug: 'basic',
|
||||||
|
trialPeriodDays: 7,
|
||||||
|
lineItems: [
|
||||||
|
{
|
||||||
|
slug: 'base',
|
||||||
|
usageType: 'licensed',
|
||||||
|
amount: 499 // $4.99 USD
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
</Tab>
|
||||||
|
|
||||||
|
<Tab title="Pay-As-You-Go">
|
||||||
|
|
||||||
|
```ts agentic.config.ts
|
||||||
|
import { defineConfig } from '@agentic/platform'
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
// ...
|
||||||
|
pricingPlans: [
|
||||||
|
{
|
||||||
|
name: 'Free',
|
||||||
|
slug: 'free',
|
||||||
|
lineItems: [
|
||||||
|
{
|
||||||
|
slug: 'base',
|
||||||
|
usageType: 'licensed',
|
||||||
|
amount: 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
// Free but limited to 20 requests per day
|
||||||
|
rateLimit: {
|
||||||
|
limit: 20,
|
||||||
|
interval: '1d'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Pay-As-You-Go',
|
||||||
|
slug: 'pay-as-you-go',
|
||||||
|
lineItems: [
|
||||||
|
{
|
||||||
|
slug: 'requests',
|
||||||
|
usageType: 'metered',
|
||||||
|
billingScheme: 'tiered',
|
||||||
|
tiersMode: 'volume',
|
||||||
|
// $0.00467 USD per request up to 999 requests per month
|
||||||
|
// then $0.00053 USD for unlimited further requests that month
|
||||||
|
tiers: [
|
||||||
|
{
|
||||||
|
upTo: 999,
|
||||||
|
unitAmount: 0.467
|
||||||
|
},
|
||||||
|
{
|
||||||
|
upTo: 'inf',
|
||||||
|
unitAmount: 0.053
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
// Limit to 1000 requests per day
|
||||||
|
rateLimit: {
|
||||||
|
limit: 1000,
|
||||||
|
interval: '1d'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
</Tab>
|
||||||
|
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
|
## Pricing Help
|
||||||
|
|
||||||
|
<Note>
|
||||||
|
Pricing can feel a little complicated to set up. Feel free to [reach out to
|
||||||
|
us](/contact) once you're ready to start charging for your product, and I'd be
|
||||||
|
happy to help you set everything up.
|
||||||
|
</Note>
|
|
@ -0,0 +1,86 @@
|
||||||
|
---
|
||||||
|
title: Rate Limit Config
|
||||||
|
description: Configure rate-limits for your Agentic product.
|
||||||
|
---
|
||||||
|
|
||||||
|
Agentic's durable rate-limiting is built on top of Cloudflare's global infrastructure. Customize the default rate-limits, change them based on a customer's pricing plan, or create custom tool-specific overrides.
|
||||||
|
|
||||||
|
## Rate Limit Config
|
||||||
|
|
||||||
|
<ResponseField name='enabled' type='boolean' required>
|
||||||
|
Whether to enable rate limiting for this pricing plan.
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name="interval" type="string" required>
|
||||||
|
The interval at which the rate limit is applied.
|
||||||
|
|
||||||
|
Either a positive integer expressed in seconds or a valid positive [ms](https://github.com/vercel/ms) string (eg, "10s", "1m", "8h", "2d", "1w", "1y", etc).
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='limit' type='number' required>
|
||||||
|
The maximum number of API requests per interval (unitless).
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name="mode" type="string" default="approximate">
|
||||||
|
How to enforce the rate limit: "strict" (more precise but slower) or "approximate" (the default; faster and asynchronous but less precise).
|
||||||
|
|
||||||
|
The default rate-limiting mode is `approximate`, which means that requests
|
||||||
|
are allowed to proceed immediately, with the limit being enforced
|
||||||
|
asynchronously in the background. This is much faster than synchronous
|
||||||
|
mode, but it is less consistent if precise adherence to rate-limits is
|
||||||
|
required.
|
||||||
|
|
||||||
|
With `strict` mode, requests are blocked until the current limit has
|
||||||
|
been confirmed. The downside with this approach is that it introduces
|
||||||
|
more latency to every request by default. The advantage is that it is
|
||||||
|
more precise and consistent.
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
## Example Rate Limits
|
||||||
|
|
||||||
|
<Tabs>
|
||||||
|
<Tab title="Default">
|
||||||
|
|
||||||
|
The default platform rate limit for `requests` is a limit of 1000 requests per minute per customer.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
{
|
||||||
|
enabled: true,
|
||||||
|
interval: '1m',
|
||||||
|
limit: 1000,
|
||||||
|
mode: 'approximate'
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</Tab>
|
||||||
|
|
||||||
|
<Tab title="Strict daily">
|
||||||
|
|
||||||
|
This example rate limit restricts customers to 100 requests per day. It uses `strict` mode which adds a little extra latency but guarantees that customers will never exceed the limit.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
{
|
||||||
|
enabled: true,
|
||||||
|
interval: '1d',
|
||||||
|
limit: 100,
|
||||||
|
mode: 'strict'
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</Tab>
|
||||||
|
|
||||||
|
<Tab title="Disabled">
|
||||||
|
|
||||||
|
This is an example of a disabled rate limit.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
{
|
||||||
|
enabled: false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</Tab>
|
||||||
|
|
||||||
|
</Tabs>
|
|
@ -0,0 +1,153 @@
|
||||||
|
---
|
||||||
|
title: Tool Config
|
||||||
|
description: Configure tool-specific settings for your Agentic product.
|
||||||
|
---
|
||||||
|
|
||||||
|
Optional list of tool configs to override the default behavior of specific tools.
|
||||||
|
|
||||||
|
Make sure the tool `name` matches the origin server's tool names, either via its MCP server or OpenAPI operationIds.
|
||||||
|
|
||||||
|
Tool names are expected to be unique and stable across deployments.
|
||||||
|
|
||||||
|
With `toolConfigs`, tools can be disabled, set custom rate-limits, customize reporting usage for metered billing, and they can also override behavior for different pricing plans.
|
||||||
|
|
||||||
|
For example, you may want to disable certain tools on a `free` pricing plan or remove the rate-limit for a specific tool on a `pro` pricing plan while keeping the defualt rate-limit in place for other tools.
|
||||||
|
|
||||||
|
Note that tool-specific configs override the defaults defined in pricing plans.
|
||||||
|
|
||||||
|
If a tool is defined on the origin server but not specified in `toolConfigs`, it will use the default behavior of the Agentic API gateway.
|
||||||
|
|
||||||
|
## Tool Config
|
||||||
|
|
||||||
|
<ResponseField name='name' type='string' required>
|
||||||
|
The name of the tool, which acts as a unique, stable identifier for the tool
|
||||||
|
across deployments.
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='enabled' type='boolean' default='true'>
|
||||||
|
Whether this tool should be enabled for all customers (default).
|
||||||
|
|
||||||
|
If you want to hide a tool from customers but still have it present on your origin server, set this to `false` for the given tool.
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='pure' type='boolean' default='false'>
|
||||||
|
Whether this tool's output is deterministic and idempotent given the same input.
|
||||||
|
|
||||||
|
If `true`, tool outputs will be cached aggressively for identical requests, though origin server response headers can still override this behavior on a per-request basis.
|
||||||
|
|
||||||
|
If `false`, tool outputs will be cached according to the origin server's response headers on a per-request basis.
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='cacheControl' type='string'>
|
||||||
|
A custom `Cache-Control` header to use for caching this tool's responses.
|
||||||
|
|
||||||
|
If set, this field overrides `pure`.
|
||||||
|
|
||||||
|
If not set and `pure` is `true`, the gateway will default to: `public, max-age=31560000, s-maxage=31560000, stale-while-revalidate=3600` (cache publicly for up to 1 year).
|
||||||
|
|
||||||
|
If not set and `pure` is `false`, the gateway will default to `no-store` which will disable caching. This is the default gateway behavior for tools (no caching).
|
||||||
|
|
||||||
|
Note that origin server response headers may also choose to disable caching on a per-request basis.
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='reportUsage' type='boolean' default='true'>
|
||||||
|
Whether calls to this tool should be reported as usage for the default `requests` line-item's metered billing.
|
||||||
|
|
||||||
|
Note: This is only relevant if the customer's active pricing plan includes a `requests` line-item.
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='rateLimit' type='object'>
|
||||||
|
Customize the default `requests`-based rate-limiting for this tool.
|
||||||
|
|
||||||
|
To disable rate-limiting for this tool, set `rateLimit.enabled` to `false`.
|
||||||
|
|
||||||
|
If not set, the default rate-limiting for the active pricing plan will be used.
|
||||||
|
|
||||||
|
See [Rate Limits](/publishing/config/rate-limits) for details.
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='inputSchemaAdditionalProperties' type='boolean'>
|
||||||
|
Whether to allow additional properties in the tool's input schema.
|
||||||
|
|
||||||
|
The default MCP spec allows additional properties. Set this to `false` if you want your tool to be more strict.
|
||||||
|
|
||||||
|
Note: This is only relevant if the tool has defined an `inputSchema`.
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='outputSchemaAdditionalProperties' type='boolean'>
|
||||||
|
Whether to allow additional properties in the tool's output schema.
|
||||||
|
|
||||||
|
The default MCP spec allows additional properties. Set this to `false` if you want your tool to be more strict.
|
||||||
|
|
||||||
|
Note: This is only relevant if the tool has defined an `outputSchema`.
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='pricingPlanOverrides' type='object'>
|
||||||
|
Allows you to override this tool's behavior or disable it entirely for different pricing plans.
|
||||||
|
|
||||||
|
This is a map from PricingPlan `slug` to PricingPlanToolOverride.
|
||||||
|
|
||||||
|
```ts agentic.config.ts
|
||||||
|
import { defineConfig } from '@agentic/platform'
|
||||||
|
|
||||||
|
// In this example, `my-tool` is disabled for the `free` pricing plan.
|
||||||
|
export default defineConfig({
|
||||||
|
// ...
|
||||||
|
toolConfigs: [
|
||||||
|
{
|
||||||
|
name: 'my-tool',
|
||||||
|
pricingPlanOverridesMap: {
|
||||||
|
free: {
|
||||||
|
enabled: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
<Expandable title="PricingPlanToolOverride">
|
||||||
|
<ResponseField name='enabled' type='boolean'>
|
||||||
|
Whether this tool should be enabled for the given pricing plan.
|
||||||
|
|
||||||
|
If `undefined`, will use the tool's default enabled state.
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='reportUsage' type='boolean'>
|
||||||
|
Whether to report default `requests` usage for metered billing for customers on a given pricing plan.
|
||||||
|
|
||||||
|
Note: This is only relevant if the pricing plan includes a `requests` line-item.
|
||||||
|
|
||||||
|
If `undefined`, will use the tool's default reportUsage state.
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='rateLimit' type='object'>
|
||||||
|
Customize or disable rate limits for this tool for customers on a given pricing plan.
|
||||||
|
|
||||||
|
To disable rate-limiting for this tool on a given pricing plan, set `rateLimit.enabled` to `false`.
|
||||||
|
|
||||||
|
See [Rate Limits](/publishing/config/rate-limits) for details.
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
</Expandable>
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
## Config Help
|
||||||
|
|
||||||
|
<Note>
|
||||||
|
Configuring your project can feel a little overwhelming with the amount of
|
||||||
|
options available. Feel free to [reach out to us](/contact) if you're
|
||||||
|
considering using Agentic's MCP Gateway, and I'd be happy to help walk you
|
||||||
|
through getting your product set up for success.
|
||||||
|
</Note>
|
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
title: Existing MCP Server
|
||||||
|
description: This guide shows how to publish an existing MCP server to Agentic's MCP Gateway.
|
||||||
|
---
|
||||||
|
|
||||||
|
**TODO**
|
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
title: Existing OpenAPI Service
|
||||||
|
description: This guide shows how to publish an existing OpenAPI service to Agentic's MCP Gateway.
|
||||||
|
---
|
||||||
|
|
||||||
|
**TODO**
|
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
title: TS MCP Hono
|
||||||
|
description: This guide shows how to publish an MCP server to Agentic's MCP Gateway using TypeScript and Hono's MCP middleware.
|
||||||
|
---
|
||||||
|
|
||||||
|
**TODO**
|
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
title: TS OpenAPI Hono
|
||||||
|
description: This guide shows how to publish an OpenAPI service to Agentic's MCP Gateway using TypeScript and Hono's OpenAPI support.
|
||||||
|
---
|
||||||
|
|
||||||
|
**TODO**
|
|
@ -5,3 +5,5 @@ description: Your API → Paid MCP, Instantly.
|
||||||
|
|
||||||
Run one command to turn any MCP server or OpenAPI service into a paid MCP
|
Run one command to turn any MCP server or OpenAPI service into a paid MCP
|
||||||
product, <em>with built-in distribution to over 20k AI engineers</em>.
|
product, <em>with built-in distribution to over 20k AI engineers</em>.
|
||||||
|
|
||||||
|
**TODO**
|
||||||
|
|
|
@ -0,0 +1,219 @@
|
||||||
|
---
|
||||||
|
title: Origin Metadata
|
||||||
|
description: Agentic's MCP Gateway passes metadata to your origin server.
|
||||||
|
---
|
||||||
|
|
||||||
|
<Tabs>
|
||||||
|
<Tab title='MCP Origin Server'>
|
||||||
|
Agentic's MCP Gateway will always include the following metadata in all tool calls within the `_meta.agentic` field.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export type AgenticMcpRequestMetadata = {
|
||||||
|
agenticProxySecret: string
|
||||||
|
sessionId: string
|
||||||
|
isCustomerSubscriptionActive: boolean
|
||||||
|
|
||||||
|
customerId?: string
|
||||||
|
customerSubscriptionStatus?: string
|
||||||
|
customerSubscriptionPlan?: string
|
||||||
|
|
||||||
|
userId?: string
|
||||||
|
userEmail?: string
|
||||||
|
userUsername?: string
|
||||||
|
userName?: string
|
||||||
|
userCreatedAt?: string
|
||||||
|
userUpdatedAt?: string
|
||||||
|
|
||||||
|
deploymentId: string
|
||||||
|
deploymentIdentifier: string
|
||||||
|
projectId: string
|
||||||
|
projectIdentifier: string
|
||||||
|
|
||||||
|
ip?: string
|
||||||
|
} & (
|
||||||
|
| {
|
||||||
|
// If the customer has an active subscription, these fields are guaranteed
|
||||||
|
// to be present in the metadata.
|
||||||
|
isCustomerSubscriptionActive: true
|
||||||
|
|
||||||
|
customerId: string
|
||||||
|
customerSubscriptionStatus: string
|
||||||
|
|
||||||
|
userId: string
|
||||||
|
userEmail: string
|
||||||
|
userUsername: string
|
||||||
|
userCreatedAt: string
|
||||||
|
userUpdatedAt: string
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
// If the customer does not have an active subscription, then the customer
|
||||||
|
// fields may or may not be present.
|
||||||
|
isCustomerSubscriptionActive: false
|
||||||
|
}
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
</Tab>
|
||||||
|
|
||||||
|
<Tab title='OpenAPI Origin Server'>
|
||||||
|
Agentic's MCP Gateway will always include the following headers for all tool calls to your origin server.
|
||||||
|
|
||||||
|
<ResponseField name='x-agentic-proxy-secret' type='string' required>
|
||||||
|
The secret key of your Agentic project. This is used to guarantee that HTTP
|
||||||
|
requests are actually coming from Agentic's MCP Gateway, and not from
|
||||||
|
third-party actors.
|
||||||
|
|
||||||
|
You can find this secret key in your Agentic project's dashboard settings.
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='x-agentic-customer-id' type='string'>
|
||||||
|
The ID of the customer in Agentic's database.
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField
|
||||||
|
name='x-agentic-is-customer-subscription-active'
|
||||||
|
type='string'
|
||||||
|
required
|
||||||
|
default='false'
|
||||||
|
>
|
||||||
|
Whether the customer has an active subscription. Will be either `true` or
|
||||||
|
`false`.
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField
|
||||||
|
name='x-agentic-customer-subscription-status'
|
||||||
|
type='string'
|
||||||
|
required
|
||||||
|
default='incomplete'
|
||||||
|
>
|
||||||
|
The [Stripe status](https://docs.stripe.com/api/subscriptions/object#subscription_object-status) of the customer's subscription.
|
||||||
|
|
||||||
|
Possible values are `incomplete`, `incomplete_expired`, `trialing`, `active`, `past_due`, `canceled`, `unpaid`, or `paused`.
|
||||||
|
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField
|
||||||
|
name='x-agentic-customer-subscription-plan'
|
||||||
|
type='string'
|
||||||
|
required
|
||||||
|
default='free'
|
||||||
|
>
|
||||||
|
The slug of the customer's subscription pricing plan.
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='x-agentic-user-id' type='string'>
|
||||||
|
The ID of the user in Agentic's database.
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='x-agentic-user-email' type='string'>
|
||||||
|
The email of the user in Agentic's database.
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='x-agentic-user-username' type='string'>
|
||||||
|
The username of the user in Agentic's database.
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='x-agentic-user-name' type='string'>
|
||||||
|
The name of the user in Agentic's database.
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='x-agentic-user-created-at' type='string'>
|
||||||
|
The date and time the user was created in Agentic's database.
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='x-agentic-user-updated-at' type='string'>
|
||||||
|
The date and time the user was last updated in Agentic's database.
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='x-agentic-project-id' type='string' required>
|
||||||
|
The ID of the project in Agentic's database. (`proj_...`)
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='x-agentic-project-identifier' type='string' required>
|
||||||
|
The public identifier of the target project in Agentic's database.
|
||||||
|
(`@username/project-name`)
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='x-agentic-deployment-id' type='string' required>
|
||||||
|
The ID of the target deployment in Agentic's database. (`depl_...`)
|
||||||
|
</ResponseField>
|
||||||
|
|
||||||
|
<ResponseField name='x-agentic-deployment-identifier' type='string' required>
|
||||||
|
The public identifier of the target deployment in Agentic's database.
|
||||||
|
(`@username/project-name@<deployment-hash>`)
|
||||||
|
</ResponseField>
|
||||||
|
</Tab>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
|
## Unauthenticated requests
|
||||||
|
|
||||||
|
If a customer doesn't provide an API key for their MCP or HTTP call, Agentic's MCP Gateway will default them to your project's `free` pricing plan with `isCustomerSubscriptionActive` set to `false`.
|
||||||
|
|
||||||
|
This means they'll be subject to your project's `free` pricing plan's [rate limits](/publishing/config/rate-limits), which is important to protect your origin server from abuse.
|
||||||
|
|
||||||
|
## Securing your origin server
|
||||||
|
|
||||||
|
Agentic's MCP Gateway will always pass a proxy secret when making tool calls to your origin server (either as `_meta.agentic.agenticProxySecret` for MCP origin servers or as an `x-agentic-proxy-secret` header for OpenAPI origin servers).
|
||||||
|
|
||||||
|
You can find this secret key in your Agentic project's dashboard settings.
|
||||||
|
|
||||||
|
You'll want to set this secret key in your origin server's environment variables and use it to protect against unauthorized requests.
|
||||||
|
|
||||||
|
Note that this is only necessary if your origin server is deployed externally to a public network.
|
||||||
|
|
||||||
|
### Securing an MCP origin server
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// This is example pseudocode for how you might protect your origin MCP
|
||||||
|
// server to ensure only calls from Agentic's MCP Gateway are allowed.
|
||||||
|
if (
|
||||||
|
(_meta?.agentic as any)?.agenticProxySecret !==
|
||||||
|
process.env.AGENTIC_PROXY_SECRET
|
||||||
|
) {
|
||||||
|
return {
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: 'text',
|
||||||
|
text: 'Unauthorized'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Securing an OpenAPI origin server
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// This is example pseudocode for how you might protect your origin OpenAPI
|
||||||
|
// service to ensure only calls from Agentic's MCP Gateway are allowed.
|
||||||
|
if (
|
||||||
|
request.headers.get('x-agentic-proxy-secret') !==
|
||||||
|
process.env.AGENTIC_PROXY_SECRET
|
||||||
|
) {
|
||||||
|
return {
|
||||||
|
status: 401,
|
||||||
|
body: {
|
||||||
|
error: 'Unauthorized'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Restricting IP addresses
|
||||||
|
|
||||||
|
You can also protecting your origin server by restricting HTTP calls to specific IP addresses used by Agentic's MCP gateway.
|
||||||
|
|
||||||
|
This is currently a private beta feature. If you're interested in using it, please [get in touch](/contact).
|
||||||
|
|
||||||
|
### Signed HTTP requests
|
||||||
|
|
||||||
|
You can also protecting your origin OpenAPI server by requiring all HTTP requests to be signed with your project's proxy secret.
|
||||||
|
|
||||||
|
This is currently a private beta feature. If you're interested in using it, please [get in touch](/contact).
|
||||||
|
|
||||||
|
### Signed MCP requests
|
||||||
|
|
||||||
|
[MCP currently doesn't support signed requests](https://github.com/modelcontextprotocol/modelcontextprotocol/discussions/461).
|
||||||
|
|
||||||
|
If you're interested in this feature, please [get in touch](/contact).
|
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
title: Quick Start
|
||||||
|
description: Run one command to turn your existing MCP server or OpenAPI service into a paid MCP product.
|
||||||
|
---
|
||||||
|
|
||||||
|
**TODO**
|
|
@ -38,6 +38,11 @@ export default defineConfig({
|
||||||
name: 'Standard',
|
name: 'Standard',
|
||||||
slug: 'standard',
|
slug: 'standard',
|
||||||
lineItems: [
|
lineItems: [
|
||||||
|
{
|
||||||
|
slug: 'base',
|
||||||
|
usageType: 'licensed',
|
||||||
|
amount: 1000
|
||||||
|
},
|
||||||
{
|
{
|
||||||
slug: 'requests',
|
slug: 'requests',
|
||||||
usageType: 'metered',
|
usageType: 'metered',
|
||||||
|
|
|
@ -72,11 +72,6 @@ export default {
|
||||||
.passthrough().shape
|
.passthrough().shape
|
||||||
},
|
},
|
||||||
async (args, { _meta }) => {
|
async (args, { _meta }) => {
|
||||||
console.log('search call', {
|
|
||||||
args,
|
|
||||||
_meta
|
|
||||||
})
|
|
||||||
|
|
||||||
// Make sure the request is coming from Agentic
|
// Make sure the request is coming from Agentic
|
||||||
if (
|
if (
|
||||||
(_meta?.agentic as any)?.agenticProxySecret !==
|
(_meta?.agentic as any)?.agenticProxySecret !==
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import { defineConfig } from '@agentic/platform'
|
import { defineConfig } from '@agentic/platform'
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
name: 'Test Basic MCP',
|
name: 'test-basic-mcp',
|
||||||
slug: 'test-basic-mcp',
|
|
||||||
origin: {
|
origin: {
|
||||||
type: 'mcp',
|
type: 'mcp',
|
||||||
url: 'https://agentic-basic-mcp-test.onrender.com/mcp'
|
url: 'https://agentic-basic-mcp-test.onrender.com/mcp'
|
||||||
|
|
|
@ -188,7 +188,7 @@ To add support for annual pricing plans, for example, you can use: \`['month', '
|
||||||
.default(['month']),
|
.default(['month']),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optional default rate limits to enforce for all pricing plans.
|
* Optional default rate limits to enforce across all pricing plans.
|
||||||
*
|
*
|
||||||
* To disable the default rate-limit, set `defaultRateLimit.enabled` to
|
* To disable the default rate-limit, set `defaultRateLimit.enabled` to
|
||||||
* `false`.
|
* `false`.
|
||||||
|
@ -202,7 +202,8 @@ To add support for annual pricing plans, for example, you can use: \`['month', '
|
||||||
.default(defaultRequestsRateLimit),
|
.default(defaultRequestsRateLimit),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optional list of tool configs to customize the behavior of tools.
|
* Optional list of tool configs to override the default behavior of
|
||||||
|
* specific tools.
|
||||||
*
|
*
|
||||||
* Make sure the tool `name` matches the origin server's tool names, either
|
* Make sure the tool `name` matches the origin server's tool names, either
|
||||||
* via its MCP server or OpenAPI operationIds.
|
* via its MCP server or OpenAPI operationIds.
|
||||||
|
|
|
@ -233,14 +233,13 @@ export const pricingPlanMeteredLineItemSchema =
|
||||||
.object({
|
.object({
|
||||||
/**
|
/**
|
||||||
* Specifies how events are aggregated for a Stripe Meter.
|
* Specifies how events are aggregated for a Stripe Meter.
|
||||||
* Allowed values are `count` to count the number of events, `sum`
|
* Allowed values are `count` to count the number of events and `sum`
|
||||||
* to sum each event's value and `last` to take the last event's
|
* to sum each event's value .
|
||||||
* value in the window.
|
|
||||||
*
|
*
|
||||||
* Defaults to `sum`.
|
* Defaults to `sum`.
|
||||||
*/
|
*/
|
||||||
formula: z
|
formula: z
|
||||||
.union([z.literal('sum'), z.literal('count'), z.literal('last')])
|
.union([z.literal('sum'), z.literal('count')])
|
||||||
.default('sum')
|
.default('sum')
|
||||||
})
|
})
|
||||||
.optional(),
|
.optional(),
|
||||||
|
@ -482,7 +481,7 @@ export const pricingPlanSchema = z
|
||||||
.string()
|
.string()
|
||||||
.nonempty()
|
.nonempty()
|
||||||
.describe(
|
.describe(
|
||||||
'Human-readable name for the pricing plan (eg, "Free", "Starter Monthly", "Pro Annual", etc)'
|
'Display name for the pricing plan (eg, "Free", "Starter Monthly", "Pro Annual", etc)'
|
||||||
)
|
)
|
||||||
.openapi('name', { example: 'Starter Monthly' }),
|
.openapi('name', { example: 'Starter Monthly' }),
|
||||||
|
|
||||||
|
@ -550,13 +549,13 @@ export const pricingPlanSchema = z
|
||||||
rateLimit: rateLimitSchema.optional(),
|
rateLimit: rateLimitSchema.optional(),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of custom LineItems which are included in the PricingPlan.
|
* List of LineItems which are included in the PricingPlan.
|
||||||
*
|
*
|
||||||
* Note: we currently support a max of 20 LineItems per plan.
|
* Note: Agentic currently supports a max of 20 LineItems per pricing plan.
|
||||||
*/
|
*/
|
||||||
lineItems: z.array(pricingPlanLineItemSchema).nonempty().max(20, {
|
lineItems: z.array(pricingPlanLineItemSchema).nonempty().max(20, {
|
||||||
message:
|
message:
|
||||||
'Stripe Checkout currently supports a max of 20 LineItems per subscription.'
|
'Agentic currently supports a max of 20 LineItems per pricing plan.'
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.describe(
|
.describe(
|
||||||
|
|
Ładowanie…
Reference in New Issue