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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions app/app/mcp-catalog/api/docs/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,8 @@
"Enterprise",
"Job Search",
"Local files",
"General"
"General",
null
]
},
"quality_score": {
Expand Down Expand Up @@ -370,7 +371,7 @@
"provider": {
"type": "string",
"nullable": true,
"enum": ["google", "slack", "linkedin"]
"enum": ["google", "slack", "linkedin", null]
},
"required": {
"type": "boolean"
Expand Down
2 changes: 1 addition & 1 deletion app/app/mcp-catalog/api/search/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export async function GET(request: NextRequest) {

if (!validationResult.success) {
return NextResponse.json(
{ error: 'Invalid query parameters', details: validationResult.error.errors },
{ error: 'Invalid query parameters', details: validationResult.error.issues },
{ status: 400 }
);
}
Expand Down
20 changes: 10 additions & 10 deletions app/app/mcp-catalog/components/DependenciesCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { ChevronDown, ChevronUp } from 'lucide-react';
import { useState } from 'react';

import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@components/ui/card';
import { ArchestraMcpServerManifest } from '@mcpCatalog/types';
import type { ArchestraMcpServerManifest, MCPDependency } from '@mcpCatalog/types';

import EvaluatedByModelInfo from './EvaluatedByModelInfo';

Expand All @@ -17,9 +17,9 @@ export default function DependenciesCard({ server }: DependenciesCardProps) {
const { dependencies } = server;

// Group dependencies by importance level
const mainDeps = dependencies?.filter((d) => d.importance >= 8) || [];
const mediumDeps = dependencies?.filter((d) => d.importance >= 5 && d.importance < 8) || [];
const lightDeps = dependencies?.filter((d) => d.importance < 5) || [];
const mainDeps = dependencies?.filter((d: MCPDependency) => d.importance >= 8) || [];
const mediumDeps = dependencies?.filter((d: MCPDependency) => d.importance >= 5 && d.importance < 8) || [];
const lightDeps = dependencies?.filter((d: MCPDependency) => d.importance < 5) || [];
const totalDeps = (dependencies || []).length;

const DependenciesContent = () => (
Expand All @@ -30,8 +30,8 @@ export default function DependenciesCard({ server }: DependenciesCardProps) {
<h4 className="text-sm font-semibold text-gray-700 mb-2">Main</h4>
<div className="space-y-2">
{mainDeps
.sort((a, b) => b.importance - a.importance)
.map((dep, index) => (
.sort((a: MCPDependency, b: MCPDependency) => b.importance - a.importance)
.map((dep: MCPDependency, index: number) => (
<div
key={index}
className="px-3 py-2 rounded-lg font-medium text-sm bg-gradient-to-r from-green-500 to-green-600 text-white shadow-md overflow-hidden"
Expand All @@ -50,8 +50,8 @@ export default function DependenciesCard({ server }: DependenciesCardProps) {
<h4 className="text-sm font-semibold text-gray-700 mb-2">Medium</h4>
<div className="space-y-2">
{mediumDeps
.sort((a, b) => b.importance - a.importance)
.map((dep, index) => (
.sort((a: MCPDependency, b: MCPDependency) => b.importance - a.importance)
.map((dep: MCPDependency, index: number) => (
<div
key={index}
className="px-3 py-2 rounded-lg font-medium text-sm bg-gradient-to-r from-gray-300 to-gray-400 text-gray-800 shadow-sm overflow-hidden"
Expand All @@ -70,8 +70,8 @@ export default function DependenciesCard({ server }: DependenciesCardProps) {
<h4 className="text-sm font-semibold text-gray-700 mb-2">Light</h4>
<div className="space-y-2">
{lightDeps
.sort((a, b) => b.importance - a.importance)
.map((dep, index) => (
.sort((a: MCPDependency, b: MCPDependency) => b.importance - a.importance)
.map((dep: MCPDependency, index: number) => (
<div
key={index}
className="px-3 py-2 rounded-lg font-medium text-sm bg-gradient-to-r from-gray-100 to-gray-200 text-gray-600 shadow-sm overflow-hidden"
Expand Down
13 changes: 9 additions & 4 deletions app/app/mcp-catalog/components/McpCatalogClient.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { Badge } from '@components/ui/badge';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@components/ui/card';
import { Input } from '@components/ui/input';
import { QualityBar } from '@mcpCatalog/components/QualityBar';
import { ArchestraMcpServerManifest } from '@mcpCatalog/types';
import type { ArchestraMcpServerManifest, MCPDependency } from '@mcpCatalog/types';

const ITEMS_PER_PAGE = 30;

Expand Down Expand Up @@ -271,7 +271,8 @@ export default function McpCatalogClient({
// Filter by dependency
const matchesDependency =
selectedDependency === 'All' ||
(dependencies && dependencies.some((dep) => dep.name === selectedDependency && dep.importance >= 8));
(dependencies &&
dependencies.some((dep: MCPDependency) => dep.name === selectedDependency && dep.importance >= 8));

// Filter by MCP features
const matchesFeature =
Expand Down Expand Up @@ -496,7 +497,9 @@ export default function McpCatalogClient({
: mcpServers.filter(
(s) =>
s.dependencies &&
s.dependencies.some((dep) => dep.name === dependency && dep.importance >= 8)
s.dependencies.some(
(dep: MCPDependency) => dep.name === dependency && dep.importance >= 8
)
).length}
</span>
</button>
Expand Down Expand Up @@ -700,7 +703,9 @@ export default function McpCatalogClient({
: mcpServers.filter(
(s) =>
s.dependencies &&
s.dependencies.some((dep) => dep.name === dependency && dep.importance >= 8)
s.dependencies.some(
(dep: MCPDependency) => dep.name === dependency && dep.importance >= 8
)
).length}
</span>
</button>
Expand Down
6 changes: 3 additions & 3 deletions app/app/mcp-catalog/lib/quality-calculator/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ArchestraMcpServerManifest, ArchestraScoreBreakdown } from '@mcpCatalog/types';
import type { ArchestraMcpServerManifest, ArchestraScoreBreakdown, MCPDependency } from '@mcpCatalog/types';

/**
* Calculate MCP Protocol Implementation Score (40 points max)
Expand Down Expand Up @@ -184,7 +184,7 @@ export function calculateDependenciesScore(
let score = 20;

// Count significant dependencies (importance >= 5)
const significantDeps = dependencies.filter((dep) => dep.importance >= 5);
const significantDeps = dependencies.filter((dep: MCPDependency) => dep.importance >= 5);
const depCount = significantDeps.length;

// Penalty only if more than 10 dependencies
Expand All @@ -200,7 +200,7 @@ export function calculateDependenciesScore(
const depFrequency = new Map<string, number>();
for (const otherServer of allServers) {
if (otherServer.dependencies) {
for (const dep of otherServer.dependencies.filter((d) => d.importance >= 5)) {
for (const dep of otherServer.dependencies.filter((d: MCPDependency) => d.importance >= 5)) {
depFrequency.set(dep.name, (depFrequency.get(dep.name) || 0) + 1);
}
}
Expand Down
23 changes: 11 additions & 12 deletions app/app/mcp-catalog/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,18 +166,17 @@ const RemoteServerSchema = z.object({
docs_url: z.string().url().nullable(),
});

export const ArchestraMcpServerManifestSchema = McpbManifestSchema._def.schema
.omit({
repository: true,
$schema: true,
version: true,
dxt_version: true,
manifest_version: true,
icons: true,
localization: true,
privacy_policies: true,
_meta: true,
})
export const ArchestraMcpServerManifestSchema = McpbManifestSchema.omit({
repository: true,
$schema: true,
version: true,
dxt_version: true,
manifest_version: true,
icons: true,
localization: true,
privacy_policies: true,
_meta: true,
})
.extend({
/**
* Machine-readable name (used for CLI, APIs)
Expand Down
10 changes: 5 additions & 5 deletions app/app/mcp-catalog/scripts/evaluate-catalog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1025,7 +1025,7 @@ If no run command found, respond with: {}`;

// For Gemini, we need a simpler schema without additionalProperties
const isGemini = model.startsWith('gemini-');
const configFormat = isGemini ? undefined : zodToJsonSchema(ArchestraClientConfigPermutationsSchema);
const configFormat = isGemini ? undefined : zodToJsonSchema(ArchestraClientConfigPermutationsSchema as any);

try {
const result = await callLLM(prompt, configFormat, model);
Expand Down Expand Up @@ -1393,7 +1393,7 @@ REMEMBER:

// For Gemini, we need a simpler schema without additionalProperties
const isGemini = model.startsWith('gemini-');
const configFormat = isGemini ? undefined : zodToJsonSchema(CanonicalServerAndUserConfigSchema);
const configFormat = isGemini ? undefined : zodToJsonSchema(CanonicalServerAndUserConfigSchema as any);

try {
const result = await callLLM(prompt, configFormat, model);
Expand Down Expand Up @@ -1462,7 +1462,7 @@ Rules:

If no configuration found, respond: {"oauth": { "provider": null, "required": false }}`;

const configFormat = zodToJsonSchema(ArchestraOauthSchema);
const configFormat = zodToJsonSchema(ArchestraOauthSchema as any);

try {
const result = await callLLM(prompt, configFormat, model);
Expand Down Expand Up @@ -1579,7 +1579,7 @@ If no library dependencies found, respond: {"dependencies": []}`;
const DependenciesResponseSchema = z.object({
dependencies: z.array(MCPDependencySchema),
});
const dependenciesFormat = zodToJsonSchema(DependenciesResponseSchema);
const dependenciesFormat = zodToJsonSchema(DependenciesResponseSchema as any);

try {
const result = await callLLM(prompt, dependenciesFormat, model);
Expand Down Expand Up @@ -1662,7 +1662,7 @@ Respond with JSON format:
"implementing_oauth2": true/false
}`;

const protocolFormat = zodToJsonSchema(ArchestraMcpServerProtocolFeaturesSchema);
const protocolFormat = zodToJsonSchema(ArchestraMcpServerProtocolFeaturesSchema as any);

try {
const result = await callLLM(prompt, protocolFormat, model);
Expand Down
6 changes: 4 additions & 2 deletions app/app/mcp-catalog/types.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { z } from 'zod';
import type { z } from 'zod';

import {
import type {
ArchestraMcpServerGitHubRepoInfoSchema,
ArchestraMcpServerManifestSchema,
ArchestraScoreBreakdownSchema,
MCPDependencySchema,
McpServerCategorySchema,
} from '@mcpCatalog/schemas';

Expand All @@ -12,3 +13,4 @@ export type McpServerCategory = z.infer<typeof McpServerCategorySchema>;
export type ArchestraScoreBreakdown = z.infer<typeof ArchestraScoreBreakdownSchema>;
export type ArchestraMcpServerGitHubRepoInfo = z.infer<typeof ArchestraMcpServerGitHubRepoInfoSchema>;
export type ArchestraMcpServerManifest = z.infer<typeof ArchestraMcpServerManifestSchema>;
export type MCPDependency = z.infer<typeof MCPDependencySchema>;
7 changes: 4 additions & 3 deletions app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"codegen:all": "pnpm openapi:generate"
},
"dependencies": {
"@asteasolutions/zod-to-openapi": "^7.3.4",
"@asteasolutions/zod-to-openapi": "^8.4.0",
"@date-fns/tz": "^1.4.1",
"@next/third-parties": "^16.1.1",
"@radix-ui/react-slot": "1.2.4",
Expand All @@ -43,7 +43,7 @@
"swagger-ui-react": "^5.30.3",
"tailwind-merge": "^3.4.0",
"tailwindcss-animate": "^1.0.7",
"zod": "^3.25.67",
"zod": "^4.2.1",
"zod-to-json-schema": "^3.25.1"
},
"devDependencies": {
Expand Down Expand Up @@ -75,7 +75,8 @@
"js-yaml": "3.14.2",
"mdast-util-to-hast": "13.2.1",
"node-forge": "1.3.2",
"tmp": "0.2.4"
"tmp": "0.2.4",
"zod": "^4.2.1"
}
},
"packageManager": "pnpm@10.24.0"
Expand Down
Loading