From 9a73ec9a836cde0e710fae45f80ed66a03bb815e Mon Sep 17 00:00:00 2001 From: Travis Fischer Date: Fri, 27 Jun 2025 11:10:25 -0500 Subject: [PATCH] docs: WIP work on mintlify docs --- apps/web/src/lib/config.ts | 3 +- docs/contact.mdx | 25 + docs/docs.json | 35 +- docs/index.mdx | 10 +- docs/marketplace/index.mdx | 23 + docs/publishing/config/auth.mdx | 86 ++++ docs/publishing/config/caching.mdx | 94 ++++ docs/publishing/config/examples.mdx | 6 + docs/publishing/config/index.mdx | 169 +++++++ docs/publishing/config/pricing.mdx | 428 ++++++++++++++++++ docs/publishing/config/rate-limits.mdx | 86 ++++ docs/publishing/config/tool-config.mdx | 153 +++++++ .../publishing/guides/existing-mcp-server.mdx | 6 + .../guides/existing-openapi-service.mdx | 6 + docs/publishing/guides/ts-mcp-hono.mdx | 6 + docs/publishing/guides/ts-openapi-hono.mdx | 6 + docs/publishing/index.mdx | 2 + docs/publishing/origin-metadata.mdx | 219 +++++++++ docs/publishing/quickstart.mdx | 6 + examples/search/agentic.config.ts | 5 + examples/search/src/worker.ts | 5 - .../valid/basic-mcp/agentic.config.ts | 3 +- packages/types/src/agentic-project-config.ts | 5 +- packages/types/src/pricing.ts | 15 +- 24 files changed, 1376 insertions(+), 26 deletions(-) create mode 100644 docs/contact.mdx create mode 100644 docs/marketplace/index.mdx create mode 100644 docs/publishing/config/auth.mdx create mode 100644 docs/publishing/config/caching.mdx create mode 100644 docs/publishing/config/examples.mdx create mode 100644 docs/publishing/config/index.mdx create mode 100644 docs/publishing/config/pricing.mdx create mode 100644 docs/publishing/config/rate-limits.mdx create mode 100644 docs/publishing/config/tool-config.mdx create mode 100644 docs/publishing/guides/existing-mcp-server.mdx create mode 100644 docs/publishing/guides/existing-openapi-service.mdx create mode 100644 docs/publishing/guides/ts-mcp-hono.mdx create mode 100644 docs/publishing/guides/ts-openapi-hono.mdx create mode 100644 docs/publishing/origin-metadata.mdx create mode 100644 docs/publishing/quickstart.mdx diff --git a/apps/web/src/lib/config.ts b/apps/web/src/lib/config.ts index 8945a976..55855d8d 100644 --- a/apps/web/src/lib/config.ts +++ b/apps/web/src/lib/config.ts @@ -16,8 +16,7 @@ export const copyright = `© ${new Date().getFullYear()} Agentic. All rights res export const githubUrl = 'https://github.com/transitive-bullshit/agentic' // TODO: make an agentic-specific calendar for this -export const calendarBookingUrl = - 'https://cal.com/travis-fischer/15min?overlayCalendar=true' +export const calendarBookingUrl = 'https://cal.com/travis-fischer/15min' export const docsUrl = 'https://docs.agentic.so' export const docsQuickStartUrl = `${docsUrl}/quick-start` export const docsMarketplaceUrl = `${docsUrl}/marketplace` diff --git a/docs/contact.mdx b/docs/contact.mdx new file mode 100644 index 00000000..b932fbfd --- /dev/null +++ b/docs/contact.mdx @@ -0,0 +1,25 @@ +--- +title: Contact +--- + +Agentic's currently a solo team built and run by [Travis Fischer](https://x.com/transitive_bs). 👋 + + + + + + + +**TODO** diff --git a/docs/docs.json b/docs/docs.json index 799e9c59..57d8f9cd 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -10,6 +10,10 @@ "background": { "image": "/media/bg.png" }, + "appearance": { + "mode": "light", + "strict": true + }, "colors": { "primary": "#0D969D", "light": "#13D3DC", @@ -39,7 +43,7 @@ "groups": [ { "group": "Getting Started", - "pages": ["index"] + "pages": ["index", "marketplace/index"] } ] }, @@ -48,7 +52,32 @@ "groups": [ { "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" }, { - "anchor": "Marketplace", + "anchor": "MCP Marketplace", "href": "https://agentic.so/marketplace", "icon": "store" }, diff --git a/docs/index.mdx b/docs/index.mdx index e8bb3bb6..76015003 100644 --- a/docs/index.mdx +++ b/docs/index.mdx @@ -1,15 +1,17 @@ --- title: Home -description: Agentic is the app store for LLM tools. +description: Agentic is the App Store for LLM Tools. --- - The Agentic MCP Marketplace is a curated collection of high quality LLM - tools – all of which are exposed as both MCP servers and simple HTTP APIs. + Agentic's marketplace is a curated collection of high quality LLM tools + – all of which are exposed as both MCP servers and simple HTTP APIs. - + 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. + +**TODO** diff --git a/docs/marketplace/index.mdx b/docs/marketplace/index.mdx new file mode 100644 index 00000000..914a6347 --- /dev/null +++ b/docs/marketplace/index.mdx @@ -0,0 +1,23 @@ +--- +title: Quick Start +description: A quick start guide to using MCP tools on the Agentic marketplace. +--- + + + + TODO + + + TODO + + + +**TODO** diff --git a/docs/publishing/config/auth.mdx b/docs/publishing/config/auth.mdx new file mode 100644 index 00000000..e8578a89 --- /dev/null +++ b/docs/publishing/config/auth.mdx @@ -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. + + + +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`. + + + +TODO + + +## 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). diff --git a/docs/publishing/config/caching.mdx b/docs/publishing/config/caching.mdx new file mode 100644 index 00000000..f09a0a11 --- /dev/null +++ b/docs/publishing/config/caching.mdx @@ -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 that by default, caching is disabled for all tools. You must explicitly + enable caching for each tool in your Agentic project config. + + +## Examples + + + + +```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 + } + ] +}) +``` + + + + + +```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' + } + ] +}) +``` + + + + + +```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' + } + ] +}) +``` + + + + diff --git a/docs/publishing/config/examples.mdx b/docs/publishing/config/examples.mdx new file mode 100644 index 00000000..c9effbd0 --- /dev/null +++ b/docs/publishing/config/examples.mdx @@ -0,0 +1,6 @@ +--- +title: Examples +description: Example Agentic config files. +--- + +**TODO** diff --git a/docs/publishing/config/index.mdx b/docs/publishing/config/index.mdx new file mode 100644 index 00000000..c00ff345 --- /dev/null +++ b/docs/publishing/config/index.mdx @@ -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. + + + 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. + + +## Config Fields + + +Display name for your project. + +Max length 1024 characters. + + + + +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`. + + + + + Short description of the project. + +Should be no longer than a few lines. + + + + +Optional semantic version of the project as a [semver](https://semver.org) string. + +Examples: `1.0.0`, `0.0.1`, `5.0.1`, etc. + + + + + Optional embedded markdown readme documenting the project. Supports + GitHub-flavored markdown. + + + + Optional logo image URL to use for the project. Logos should have a square + aspect ratio. + + + + + Optional URL to the source code of the project (eg, GitHub repo). + + + + Origin API adapter used to configure the origin API server downstream from + Agentic's API gateway. + + + + + + The type of origin server. `mcp` in this case. + + + + +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. + + + + + + + + The type of origin server. `openapi` in this case. + + + + +Required base URL of the externally hosted origin API server. + +Must be a valid `https` URL. + + + + + +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. + + + + + + + + + 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. + + + + +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. + + + + +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. + + + + +Optional list of tool configs to override the default behavior of specific tools. + +See [Tool Config](/publishing/config/tool-config) for details. + + + +## Config Help + + + 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. + diff --git a/docs/publishing/config/pricing.mdx b/docs/publishing/config/pricing.mdx new file mode 100644 index 00000000..246fa607 --- /dev/null +++ b/docs/publishing/config/pricing.mdx @@ -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). + + + 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. + + +## Pricing Plan Config + + +Display name for the pricing plan. + +Examples: "Free", "Starter Monthly", "Pro Annual", etc. + + + + +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. + + + + +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) + + + + + Optional description of the pricing plan (UI-only). + + + + Optional list of features of the pricing plan (UI-only; array of strings). + + + + 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) + + + + +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. + + + + +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. + + + +## 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`. + + +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. + + + + +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) + + + + + 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) + + + + + +Licensed line-items are used to charge for **fixed-price services**. + + + 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) + + + + +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) + + + + + +Metered line-items are used to charge for **usage-based services**. + + + 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) + + + + +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) + + + + +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) + + + + +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) + + + + +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) + + + + +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) + + + + The maximum quantity of usage for this tier. + +Should be a number or `inf` for the maximum tier. + + + + +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. + + + + +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. + + + + + + + + +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) + + + +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. + + + + + + + + +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) + + + +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) + + + + +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) + + + + + + + + + + + +## Example Pricing Plans + + + + +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 + } + ] + } + ] +}) +``` + + + + + +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 + } + ] + } + ] +}) +``` + + + + + +```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' + } + } + ] +}) +``` + + + + + +## Pricing Help + + + 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. + diff --git a/docs/publishing/config/rate-limits.mdx b/docs/publishing/config/rate-limits.mdx new file mode 100644 index 00000000..72113f49 --- /dev/null +++ b/docs/publishing/config/rate-limits.mdx @@ -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 + + + Whether to enable rate limiting for this pricing plan. + + + + 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). + + + + + The maximum number of API requests per interval (unitless). + + + + 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. + + + +## Example Rate Limits + + + + +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' +} +``` + + + + + +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' +} +``` + + + + + +This is an example of a disabled rate limit. + +```ts +{ + enabled: false +} +``` + + + + diff --git a/docs/publishing/config/tool-config.mdx b/docs/publishing/config/tool-config.mdx new file mode 100644 index 00000000..255fd0b2 --- /dev/null +++ b/docs/publishing/config/tool-config.mdx @@ -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 + + + The name of the tool, which acts as a unique, stable identifier for the tool + across deployments. + + + +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. + + + + +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. + + + + +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. + + + + +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. + + + + +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. + + + + +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`. + + + + +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`. + + + + +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 + } + } + } + ] +}) +``` + + + + Whether this tool should be enabled for the given pricing plan. + + If `undefined`, will use the tool's default enabled state. + + + + + 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. + + + + +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. + + + + + + + +## Config Help + + + 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. + diff --git a/docs/publishing/guides/existing-mcp-server.mdx b/docs/publishing/guides/existing-mcp-server.mdx new file mode 100644 index 00000000..597d119f --- /dev/null +++ b/docs/publishing/guides/existing-mcp-server.mdx @@ -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** diff --git a/docs/publishing/guides/existing-openapi-service.mdx b/docs/publishing/guides/existing-openapi-service.mdx new file mode 100644 index 00000000..918d1728 --- /dev/null +++ b/docs/publishing/guides/existing-openapi-service.mdx @@ -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** diff --git a/docs/publishing/guides/ts-mcp-hono.mdx b/docs/publishing/guides/ts-mcp-hono.mdx new file mode 100644 index 00000000..e72c694e --- /dev/null +++ b/docs/publishing/guides/ts-mcp-hono.mdx @@ -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** diff --git a/docs/publishing/guides/ts-openapi-hono.mdx b/docs/publishing/guides/ts-openapi-hono.mdx new file mode 100644 index 00000000..00a54d5f --- /dev/null +++ b/docs/publishing/guides/ts-openapi-hono.mdx @@ -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** diff --git a/docs/publishing/index.mdx b/docs/publishing/index.mdx index 4f371c08..75657f15 100644 --- a/docs/publishing/index.mdx +++ b/docs/publishing/index.mdx @@ -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 product, with built-in distribution to over 20k AI engineers. + +**TODO** diff --git a/docs/publishing/origin-metadata.mdx b/docs/publishing/origin-metadata.mdx new file mode 100644 index 00000000..8bf9205e --- /dev/null +++ b/docs/publishing/origin-metadata.mdx @@ -0,0 +1,219 @@ +--- +title: Origin Metadata +description: Agentic's MCP Gateway passes metadata to your 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 + } +) +``` + + + + +Agentic's MCP Gateway will always include the following headers for all tool calls to your origin server. + + + 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. + + + + + The ID of the customer in Agentic's database. + + + + Whether the customer has an active subscription. Will be either `true` or + `false`. + + + + 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`. + + + + + The slug of the customer's subscription pricing plan. + + + + The ID of the user in Agentic's database. + + + + The email of the user in Agentic's database. + + + + The username of the user in Agentic's database. + + + + The name of the user in Agentic's database. + + + + The date and time the user was created in Agentic's database. + + + + The date and time the user was last updated in Agentic's database. + + + + The ID of the project in Agentic's database. (`proj_...`) + + + + The public identifier of the target project in Agentic's database. + (`@username/project-name`) + + + + The ID of the target deployment in Agentic's database. (`depl_...`) + + + + The public identifier of the target deployment in Agentic's database. + (`@username/project-name@`) + + + + +## 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). diff --git a/docs/publishing/quickstart.mdx b/docs/publishing/quickstart.mdx new file mode 100644 index 00000000..e81b2e28 --- /dev/null +++ b/docs/publishing/quickstart.mdx @@ -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** diff --git a/examples/search/agentic.config.ts b/examples/search/agentic.config.ts index 3433aac7..b6a1f347 100644 --- a/examples/search/agentic.config.ts +++ b/examples/search/agentic.config.ts @@ -38,6 +38,11 @@ export default defineConfig({ name: 'Standard', slug: 'standard', lineItems: [ + { + slug: 'base', + usageType: 'licensed', + amount: 1000 + }, { slug: 'requests', usageType: 'metered', diff --git a/examples/search/src/worker.ts b/examples/search/src/worker.ts index 5db4c03d..a75c0b7b 100644 --- a/examples/search/src/worker.ts +++ b/examples/search/src/worker.ts @@ -72,11 +72,6 @@ export default { .passthrough().shape }, async (args, { _meta }) => { - console.log('search call', { - args, - _meta - }) - // Make sure the request is coming from Agentic if ( (_meta?.agentic as any)?.agenticProxySecret !== diff --git a/packages/fixtures/valid/basic-mcp/agentic.config.ts b/packages/fixtures/valid/basic-mcp/agentic.config.ts index 0521715a..8580da38 100644 --- a/packages/fixtures/valid/basic-mcp/agentic.config.ts +++ b/packages/fixtures/valid/basic-mcp/agentic.config.ts @@ -1,8 +1,7 @@ import { defineConfig } from '@agentic/platform' export default defineConfig({ - name: 'Test Basic MCP', - slug: 'test-basic-mcp', + name: 'test-basic-mcp', origin: { type: 'mcp', url: 'https://agentic-basic-mcp-test.onrender.com/mcp' diff --git a/packages/types/src/agentic-project-config.ts b/packages/types/src/agentic-project-config.ts index b8d55218..f473dec6 100644 --- a/packages/types/src/agentic-project-config.ts +++ b/packages/types/src/agentic-project-config.ts @@ -188,7 +188,7 @@ To add support for annual pricing plans, for example, you can use: \`['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 * `false`. @@ -202,7 +202,8 @@ To add support for annual pricing plans, for example, you can use: \`['month', ' .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 * via its MCP server or OpenAPI operationIds. diff --git a/packages/types/src/pricing.ts b/packages/types/src/pricing.ts index 4a99f34a..0d0529f3 100644 --- a/packages/types/src/pricing.ts +++ b/packages/types/src/pricing.ts @@ -233,14 +233,13 @@ export const pricingPlanMeteredLineItemSchema = .object({ /** * Specifies how events are aggregated for a Stripe Meter. - * Allowed values are `count` to count the number of events, `sum` - * to sum each event's value and `last` to take the last event's - * value in the window. + * Allowed values are `count` to count the number of events and `sum` + * to sum each event's value . * * Defaults to `sum`. */ formula: z - .union([z.literal('sum'), z.literal('count'), z.literal('last')]) + .union([z.literal('sum'), z.literal('count')]) .default('sum') }) .optional(), @@ -482,7 +481,7 @@ export const pricingPlanSchema = z .string() .nonempty() .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' }), @@ -550,13 +549,13 @@ export const pricingPlanSchema = z 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, { message: - 'Stripe Checkout currently supports a max of 20 LineItems per subscription.' + 'Agentic currently supports a max of 20 LineItems per pricing plan.' }) }) .describe(