chore: improve claude.md

pull/715/head
Travis Fischer 2025-06-14 02:31:20 +07:00
rodzic c4b353d371
commit 449e927bb2
6 zmienionych plików z 37 dodań i 21 usunięć

Wyświetl plik

@ -12,7 +12,7 @@ The platform consists of:
- **API Service** (`apps/api/`) - Internal platform API with authentication, billing, and resource management - **API Service** (`apps/api/`) - Internal platform API with authentication, billing, and resource management
- **Gateway Service** (`apps/gateway/`) - Cloudflare Worker that proxies requests to origin MCP/OpenAPI services - **Gateway Service** (`apps/gateway/`) - Cloudflare Worker that proxies requests to origin MCP/OpenAPI services
- **E2E Tests** (`apps/e2e/`) - End-to-end test suite for HTTP and MCP interfaces - **E2E Tests** (`apps/e2e/`) - End-to-end test suite for HTTP and MCP gateway requests
- **Shared Packages** (`packages/`) - Common utilities, types, validators, and configuration - **Shared Packages** (`packages/`) - Common utilities, types, validators, and configuration
The gateway accepts requests at `https://gateway.agentic.so/deploymentIdentifier/toolName` for REST or `https://gateway.agentic.so/deploymentIdentifier/mcp` for MCP. The gateway accepts requests at `https://gateway.agentic.so/deploymentIdentifier/toolName` for REST or `https://gateway.agentic.so/deploymentIdentifier/mcp` for MCP.
@ -119,27 +119,30 @@ All packages must follow these `package.json` rules:
- Use TypeScript's utility types (e.g., `Partial`, `Pick`, `Omit`) to manipulate existing types - Use TypeScript's utility types (e.g., `Partial`, `Pick`, `Omit`) to manipulate existing types
- Create custom types for complex data structures used throughout the application - Create custom types for complex data structures used throughout the application
- If possible, avoid using `any`/`unknown` or casting values like `(value as any)` in TypeScript outside of test files e.g. `*.test.ts` or test fixtures e.g. `**/test-data.ts`. - If possible, avoid using `any`/`unknown` or casting values like `(value as any)` in TypeScript outside of test files e.g. `*.test.ts` or test fixtures e.g. `**/test-data.ts`.
- Don't rely on `typeof`, `ReturnType<>`, `Awaited<>`, etc for complex type inference (it's ok for simple types) - Try not to rely on `typeof`, `ReturnType<>`, `Awaited<>`, etc for complex type inference (it's ok for simple types)
- You can use `as const` as needed for better type inference - You can use `as const` as needed for better type inference
- Functions should accept an object parameter instead of multiple parameters - Functions should accept an object parameter instead of multiple parameters
- Good examples: - GOOD examples:
```ts ```ts
function myFunction({ foo, bar }: { foo: boolean; bar: string }) {} function myFunction({ foo, bar }: { foo: boolean; bar: string }) {}
function VideoPlayer({ sid }: { sid: string }) {} function VideoPlayer({ sid }: { sid: string }) {}
``` ```
- Bad examples: - BAD examples:
```ts ```ts
function myFunction(foo: boolean, bar: string, baz: number) {} function myFunction(foo: boolean, bar: string, baz: number) {}
``` ```
- Arguments should generally be destructured in the function definition, not the function body. - Arguments should generally be destructured in the function definition, not the function body.
- Good example: - GOOD example:
```ts ```ts
function myFunction({ foo, bar }: { foo: boolean; bar: string }) {} function myFunction({ foo, bar }: { foo: boolean; bar: string }) {}
function exampleWithOptionalParams({
foo = 'example'
}: { foo?: string } = {}) {}
``` ```
- Bad example: - BAD example:
```ts ```ts
function myFunction(args: { foo: boolean; bar: string }) { function myFunction(opts: { foo: boolean; bar: string }) {
const { foo, bar } = args const { foo, bar } = opts
} }
``` ```
- Zod should be used to parse untrusted data, but not for data that is trusted like function arguments - Zod should be used to parse untrusted data, but not for data that is trusted like function arguments
@ -192,8 +195,8 @@ Comments should be used to document and explain code. They should complement the
- **All unit tests should use Vitest** - **All unit tests should use Vitest**
- DO NOT attempt to install or use other testing libraries like Jest - DO NOT attempt to install or use other testing libraries like Jest
- Test files should be named `[target].test.ts` and placed in the same directory as the code they are testing (NOT a separate directory) - Test files should be named `[target].test.ts` and placed in the same directory as the code they are testing (NOT a separate directory)
- Good example: `src/my-file.ts` and `src/my-file.test.ts` - GOOD example: `src/my-file.ts` and `src/my-file.test.ts`
- Bad example: `src/my-file.ts` and `src/test/my-file.test.ts` or `test/my-file.test.ts` or `src/__tests__/my-file.test.ts` - BAD example: `src/my-file.ts` and `src/test/my-file.test.ts` or `test/my-file.test.ts` or `src/__tests__/my-file.test.ts`
- Tests should be run with `pnpm test:unit` - Tests should be run with `pnpm test:unit`
- You may use `any`/`unknown` in test files (such as `*.test.ts`) or test fixtures (like `**/test-data.ts`) to facilitate mocking or stubbing external modules or partial function arguments, referencing the usage guidelines in the TypeScript section. - You may use `any`/`unknown` in test files (such as `*.test.ts`) or test fixtures (like `**/test-data.ts`) to facilitate mocking or stubbing external modules or partial function arguments, referencing the usage guidelines in the TypeScript section.
- Frontend react code does not need unit tests - Frontend react code does not need unit tests

Wyświetl plik

@ -1,17 +1,14 @@
import { toolNameRe } from '@agentic/platform-validators' import { isToolNameAllowed, toolNameRe } from '@agentic/platform-validators'
import { z } from '@hono/zod-openapi' import { z } from '@hono/zod-openapi'
import { pricingPlanSlugSchema } from './pricing' import { pricingPlanSlugSchema } from './pricing'
import { rateLimitSchema } from './rate-limit' import { rateLimitSchema } from './rate-limit'
// TODO: add more reserved tool names?
// TODO: if we separate mcp endpoint from REST endpoint, we may be able to have
// tools named `mcp`. would be nice not to impose a blacklist.
const toolNameBlacklist = new Set(['mcp'])
/** /**
* Agentic tool name. * Agentic tool name.
* *
* Follows OpenAI/Anthropic/Gemini function calling naming conventions.
*
* @example `"get_weather"` * @example `"get_weather"`
* @example `"searchGoogle"` * @example `"searchGoogle"`
* @example `"get_user_info2"` * @example `"get_user_info2"`
@ -21,9 +18,9 @@ export const toolNameSchema = z
.nonempty() .nonempty()
.regex(toolNameRe) .regex(toolNameRe)
.refine( .refine(
(name) => !toolNameBlacklist.has(name), (name) => isToolNameAllowed(name),
(name) => ({ (name) => ({
message: `Tool name is reserved: "${name}"` message: `Tool name "${name}" is reserved; please choose a different name.`
}) })
) )
.describe('Agentic tool name') .describe('Agentic tool name')

Wyświetl plik

@ -2,5 +2,6 @@ export * from './namespace-blacklist'
export * from './parse-deployment-identifier' export * from './parse-deployment-identifier'
export * from './parse-project-identifier' export * from './parse-project-identifier'
export * from './parse-tool-identifier' export * from './parse-tool-identifier'
export * from './tool-name-blacklist'
export type * from './types' export type * from './types'
export * from './validators' export * from './validators'

Wyświetl plik

@ -2,6 +2,7 @@ import { expect, test } from 'vitest'
import { import {
isNamespaceAllowed, isNamespaceAllowed,
isToolNameAllowed,
isValidDeploymentHash, isValidDeploymentHash,
isValidDeploymentIdentifier, isValidDeploymentIdentifier,
isValidEmail, isValidEmail,
@ -177,3 +178,13 @@ test('isValidToolName failure', () => {
) )
).toBe(false) ).toBe(false)
}) })
test('isToolNameAllowed', () => {
expect(isToolNameAllowed('foo')).toBe(true)
expect(isToolNameAllowed('tool_name')).toBe(true)
expect(isToolNameAllowed('searchGoogle')).toBe(true)
expect(isToolNameAllowed('mcp')).toBe(false)
expect(isToolNameAllowed('sse')).toBe(false)
expect(isToolNameAllowed()).toBe(false)
expect(isToolNameAllowed('')).toBe(false)
})

Wyświetl plik

@ -5,6 +5,7 @@ import type { ParseIdentifierOptions } from './types'
import { namespaceBlacklist } from './namespace-blacklist' import { namespaceBlacklist } from './namespace-blacklist'
import { parseDeploymentIdentifier } from './parse-deployment-identifier' import { parseDeploymentIdentifier } from './parse-deployment-identifier'
import { parseProjectIdentifier } from './parse-project-identifier' import { parseProjectIdentifier } from './parse-project-identifier'
import { toolNameBlacklist } from './tool-name-blacklist'
export const namespaceRe = /^[a-z0-9-]{1,256}$/ export const namespaceRe = /^[a-z0-9-]{1,256}$/
export const passwordRe = /^.{3,1024}$/ export const passwordRe = /^.{3,1024}$/
@ -72,6 +73,10 @@ export function isValidToolName(value?: string): boolean {
return !!value && toolNameRe.test(value) return !!value && toolNameRe.test(value)
} }
export function isToolNameAllowed(value?: string): boolean {
return !!value && isValidToolName(value) && !toolNameBlacklist.has(value)
}
export function isValidCuid(value?: string): boolean { export function isValidCuid(value?: string): boolean {
return !!value && isCuid(value) return !!value && isCuid(value)
} }

Wyświetl plik

@ -7,8 +7,8 @@
## API Gateway ## API Gateway
- **REST**: `GET/POST` `https://gateway.agentic.so/deploymentIdentifier/toolName` - **MCP**: `https://gateway.agentic.so/@{username}/{project-name}/mcp`
- **MCP**: `https://gateway.agentic.so/deploymentIdentifier/mcp` - **HTTP**: `GET/POST` `https://gateway.agentic.so/@{username}/{project-name}/{tool-name}`
## TODO: MVP ## TODO: MVP
@ -24,7 +24,6 @@
- oauth flow - oauth flow
- https://docs.scalekit.com/guides/mcp/oauth - https://docs.scalekit.com/guides/mcp/oauth
- **test usage tracking and reporting** - **test usage tracking and reporting**
- disallow `mcp` and `sse` as tool names or figure out a different workaround
- docs - docs
- main readme - main readme
- sub readmes - sub readmes