pinecone_search
Located at dapp/app/lib/mcp/tools/pinecone-search.ts, this tool turns user prompts into vector queries and returns a dual output: readable summaries for the LLM and JSON matches for the UI.
Runtime Traits
- Dynamic schema — The input schema is built from
pineconeConfig, so enum values always match the configured indexes/namespaces. - Embeddings — Uses Pinecone’s hosted
multilingual-e5-largemodel for both query and corpus vectors, keeping deployments provider-agnostic. - Namespace safety —
pineconeConfig.isValidIndexNamespaceguards against malformed requests before hitting the API. - Result formatting — JSON includes
matcheswith top scores and URLs. The text stream prefixes results with scores and emits gif-friendly<gif>tags for the UI renderer.
Pinecone Configuration
dapp/app/config/pinecone.config.tsvalidates index names and namespace lists, and exposes helpers (getIndexNames,getNamespacesForIndex,isValidIndexNamespace) so tools can reject invalid queries before hitting the API.- CLI utilities in
dapp/pinecone(seed.ts,clear-namespace.ts, etc.) ingest JSON datasets such asgifs.json,rito-pics.json, andritorhymes.json. They use Pinecone’s hosted embedding service (multilingual-e5-large) to stay provider-agnostic. - MCP tools (
pinecone-search.ts,agent-rap-verse/phases/gathering.ts) rely on the config to know which namespaces exist and to surface helper metadata (URLs, descriptions, meme categories).
Knowledge Hygiene
Semantic data is intentionally playful (memes, rhymes, lore) but still token-gated. The agent respects mode rules—for instance, rap battles limit balance lookups and enforce unique insults to avoid repetitive fetches.
- Namespace awareness ensures the model never guesses index names; invalid combinations trigger descriptive errors before reaching Pinecone.
- Tool outputs mix text and JSON so transcripts remain lightweight while presenters and hydration hooks can extract structured information.
- JWT context (chain, token ID, address) is injected server-side for any tool that needs on-chain identity, reducing the risk of prompt spoofing.
// dapp/app/lib/mcp/tools/pinecone-search.ts
const pineconeSearchTool: Tool<PineconeSearchParams> = {
name: 'pinecone_search',
description: 'Perform semantic vector search in Pinecone indexes.',
inputSchema: buildInputSchema(),
async handler({ query, index, namespace = '__default__', topK = 5, includeMetadata = true, filter }) {
const pc = getPineconeClient();
const embeddingResponse = await pc.inference.embed('multilingual-e5-large', [query], { inputType: 'query', truncate: 'END' });
const vector = embeddingResponse.data[0].values;
const results = await pc.index(index).namespace(namespace).query({ vector, topK, includeMetadata, filter });
const matches = Array.isArray(results.matches) ? results.matches : [];
const text = textResult(buildSummary(index, namespace, matches));
const json = jsonResult({ query, index, namespace, totalMatches: matches.length, topK, matches: normalize(matches) });
return { content: [...text.content, ...json.content] };
},
};Presenter Notes
dapp/components/chatBot/ToolActivity/catalog/presenters/pinecone_search.presenter.ts adds context to the chips:
| Status | Behavior |
|---|---|
| pending | Label includes index/namespace, and the text shows a truncated query. |
| success | Announces Found N results in index/namespace plus the top score and best-match title when present. |
| error | Normalizes common failures (“API key missing”, “Index not found”, etc.) for quicker debugging. |
Usage Tips
Because pinecone_search emits both text and JSON, the LLM can cite top matches inline while the UI renders gifs or images referenced in the metadata—perfect for the stylized rap experience described in the Chat Experience chapter.