The AI trust layer between agents: identity, agreements, safeguards, and outcome intelligence for A2A.

Viewing files at commit 82a1651a33d0Commit detailsView latest

api/mcp.ts 40 lines · 1.7 KB · typescript
1
import descopeSdk from '@descope/node-sdk';
2
import type { AuthInfo } from '@modelcontextprotocol/server';
3
import { createMcpHandler, withMcpAuth } from 'mcp-handler';
4
import { TrustEngine } from '../packages/core/src/index.js';
5
import { registerOpenClaspTools } from '../packages/mcp-server/src/server.js';
6
7
const engine = new TrustEngine();
8
const mcp = createMcpHandler((server) => registerOpenClaspTools(server, engine), {
9
  serverInfo: { name: 'openclasp', version: '0.1.0' },
10
  instructions:
11
    'OpenClasp provides identity, interaction assurance, private clues, receipts, and contextual behavioural history. Never submit raw private conversations.',
12
});
13
14
async function verifyToken(_request: Request, bearerToken?: string): Promise<AuthInfo | undefined> {
15
  const projectId = process.env.DESCOPE_PROJECT_ID ?? process.env.NEXT_PUBLIC_DESCOPE_PROJECT_ID;
16
  if (!projectId || !bearerToken) return undefined;
17
  const descope = descopeSdk({ projectId });
18
  const authentication = await descope.validateSession(bearerToken, {
19
    ...(process.env.OPENCLASP_MCP_URL ? { audience: process.env.OPENCLASP_MCP_URL } : {}),
20
  });
21
  if (!authentication.token.exp) return undefined;
22
  return {
23
    token: bearerToken,
24
    clientId: authentication.token.sub ?? 'unknown-client',
25
    scopes: descope.getJwtPermissions(bearerToken),
26
    expiresAt: authentication.token.exp,
27
    extra: { operatorId: authentication.token.sub },
28
  };
29
}
30
31
const handler = withMcpAuth(mcp, verifyToken, {
32
  required: true,
33
  requiredScopes: ['full-access'],
34
  resourceMetadataPath: '/.well-known/oauth-protected-resource',
35
  ...(process.env.OPENCLASP_MCP_URL
36
    ? { resourceUrl: new URL(process.env.OPENCLASP_MCP_URL).origin }
37
    : {}),
38
});
39
40
export { handler as GET, handler as POST };