refactor: replace authentication field with envVars in TPMJS specification

Replace the authentication field with a more general envVars array that allows tools to specify required environment variables:

Changes to type definitions:
- Remove TpmjsAuthenticationSchema and TpmjsAuthentication type
- Add TpmjsEnvVarSchema with fields: name, description, required, default
- Replace authentication field with envVars array in TpmjsRichSchema
- Update validateTpmjsField to check envVars instead of authentication

Changes to documentation:
- Update /spec page to document envVars instead of authentication
- Update /publish page examples to use envVars
- Update HOW_TO_PUBLISH_A_TOOL.md with envVars examples
- Update validation errors section
- Remove authentication from @tpmjs/createblogpost example

The envVars field is more flexible and clearer - it lists all environment variables a tool needs (API keys, endpoints, config values) rather than trying to categorize authentication types.

Example:
```json
"envVars": [
  {
    "name": "OPENAI_API_KEY",
    "description": "API key for OpenAI services",
    "required": true
  }
]
```

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Ajax Davis 2025-12-01 05:21:30 +10:00
parent a6ec7df800
commit cd3dee8133
5 changed files with 61 additions and 52 deletions

View file

@ -129,10 +129,13 @@ Complete metadata for maximum visibility:
"type": "SentimentResult",
"description": "Object with score, label, and optional emotions array"
},
"authentication": {
"type": "api-key",
"required": true
},
"envVars": [
{
"name": "SENTIMENT_API_KEY",
"description": "API key for sentiment analysis service",
"required": true
}
],
"frameworks": ["vercel-ai", "langchain"],
"links": {
"documentation": "https://docs.example.com",
@ -308,10 +311,6 @@ Here's the complete `package.json` from the published example:
"type": "BlogPost",
"description": "A structured blog post object with frontmatter, content, and metadata including slug, wordCount, readingTime, and formattedOutput"
},
"authentication": {
"required": false,
"type": "api-key"
},
"frameworks": ["vercel-ai", "langchain"],
"links": {
"documentation": "https://tpmjs.com/tools/createblogpost",
@ -354,7 +353,7 @@ Here's the complete `package.json` from the published example:
| Field | Type | Description |
|-------|------|-------------|
| `authentication` | object | Auth requirements |
| `envVars` | array | Required environment variables |
| `frameworks` | array | Compatible frameworks |
| `links` | object | Related URLs |
| `tags` | array | Additional tags |
@ -374,15 +373,24 @@ Choose one of these for the `category` field:
- `integration` - Third-party integrations
- `other` - Anything else
### Authentication Types
### Environment Variables
If your tool requires authentication:
If your tool requires environment variables:
```json
"authentication": {
"type": "api-key", // or "oauth", "bearer-token", "basic"
"required": true
}
"envVars": [
{
"name": "OPENAI_API_KEY",
"description": "API key for OpenAI services",
"required": true
},
{
"name": "API_ENDPOINT",
"description": "Custom API endpoint URL",
"required": false,
"default": "https://api.example.com"
}
]
```
## Quality Score

View file

@ -165,10 +165,13 @@ export default function PublishPage(): React.ReactElement {
"example": "const result = await analyzeSentiment({ text: 'I love this!', includeEmotions: true });",
"parameters": [...],
"returns": {...},
"authentication": {
"type": "api-key",
"required": true
},
"envVars": [
{
"name": "SENTIMENT_API_KEY",
"description": "API key for sentiment analysis service",
"required": true
}
],
"frameworks": ["vercel-ai", "langchain"],
"links": {
"documentation": "https://docs.example.com",

View file

@ -289,26 +289,27 @@ export default function SpecPage(): React.ReactElement {
<div className="space-y-6">
<div>
<h4 className="text-lg font-semibold text-foreground mb-2">
<code>authentication</code>
<code>envVars</code>
</h4>
<p className="text-sm text-foreground-secondary mb-2">
Authentication requirements. Fields:
Array of environment variables required by the tool. Each variable has:
</p>
<ul className="list-disc list-inside space-y-1 text-sm text-foreground-secondary ml-4">
<li>
<code className="text-foreground">required</code> - Boolean
<code className="text-foreground">name</code> - Environment variable name
(e.g., "OPENAI_API_KEY")
</li>
<li>
<code className="text-foreground">type</code> - "api-key", "oauth",
"basic-auth", or "custom"
<code className="text-foreground">description</code> - What the variable is
used for
</li>
<li>
<code className="text-foreground">envVar</code> - Environment variable
name (optional)
<code className="text-foreground">required</code> - Boolean (defaults to
true)
</li>
<li>
<code className="text-foreground">docsUrl</code> - Auth documentation URL
(optional)
<code className="text-foreground">default</code> - Default value if not
provided (optional)
</li>
</ul>
</div>
@ -419,12 +420,13 @@ export default function SpecPage(): React.ReactElement {
"example": "const result = await analyzeSentiment({ text: 'I love this!', includeEmotions: true });",
"parameters": [...],
"returns": {...},
"authentication": {
"required": true,
"type": "api-key",
"envVar": "SENTIMENT_API_KEY",
"docsUrl": "https://docs.example.com/auth"
},
"envVars": [
{
"name": "SENTIMENT_API_KEY",
"description": "API key for sentiment analysis service",
"required": true
}
],
"frameworks": ["vercel-ai", "langchain"],
"links": {
"documentation": "https://docs.example.com",
@ -540,16 +542,16 @@ export default function SpecPage(): React.ReactElement {
</tr>
<tr className="border-b border-border">
<td className="py-3 px-4">
<code className="text-foreground">authentication</code>
<code className="text-foreground">envVars</code>
</td>
<td className="py-3 px-4">object</td>
<td className="py-3 px-4">array</td>
<td className="py-3 px-4">
<Badge variant="success" size="sm">
Rich
</Badge>
</td>
<td className="py-3 px-4">No</td>
<td className="py-3 px-4">Auth requirements</td>
<td className="py-3 px-4">Required environment variables</td>
</tr>
<tr className="border-b border-border">
<td className="py-3 px-4">
@ -780,8 +782,8 @@ export default function SpecPage(): React.ReactElement {
at least 10 characters
</li>
<li>
<strong className="text-foreground">Invalid authentication type:</strong> Type
must be "api-key", "oauth", "basic-auth", or "custom"
<strong className="text-foreground">Invalid envVar:</strong> Each environment
variable must have a name and description
</li>
<li>
<strong className="text-foreground">Too many tags:</strong> Maximum 10 tags

View file

@ -80,10 +80,6 @@
"type": "BlogPost",
"description": "A structured blog post object with frontmatter, content, and metadata including slug, wordCount, readingTime, and formattedOutput"
},
"authentication": {
"required": false,
"type": "api-key"
},
"frameworks": ["vercel-ai", "langchain"],
"links": {
"documentation": "https://tpmjs.com/tools/createblogpost",

View file

@ -44,16 +44,16 @@ export const TpmjsReturnsSchema = z.object({
export type TpmjsReturns = z.infer<typeof TpmjsReturnsSchema>;
/**
* Authentication configuration schema
* Environment variable schema
*/
export const TpmjsAuthenticationSchema = z.object({
required: z.boolean(),
type: z.enum(['api-key', 'oauth', 'basic-auth', 'custom']),
envVar: z.string().optional(),
docsUrl: z.string().url().optional(),
export const TpmjsEnvVarSchema = z.object({
name: z.string().min(1),
description: z.string().min(1),
required: z.boolean().default(true),
default: z.string().optional(),
});
export type TpmjsAuthentication = z.infer<typeof TpmjsAuthenticationSchema>;
export type TpmjsEnvVar = z.infer<typeof TpmjsEnvVarSchema>;
/**
* External links schema
@ -99,7 +99,7 @@ export type TpmjsMinimal = z.infer<typeof TpmjsMinimalSchema>;
export const TpmjsRichSchema = TpmjsMinimalSchema.extend({
parameters: z.array(TpmjsParameterSchema).optional(),
returns: TpmjsReturnsSchema.optional(),
authentication: TpmjsAuthenticationSchema.optional(),
envVars: z.array(TpmjsEnvVarSchema).optional(),
frameworks: z
.array(z.enum(['vercel-ai', 'langchain', 'llamaindex', 'haystack', 'semantic-kernel']))
.optional(),
@ -138,7 +138,7 @@ export function validateTpmjsField(tpmjs: unknown): ValidationResult {
const hasRichFields =
data.parameters ||
data.returns ||
data.authentication ||
data.envVars ||
data.frameworks ||
data.links ||
data.tags ||