@takuhon/core 0.13.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +110 -1
- package/dist/index.js +161 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -3801,6 +3801,115 @@ interface CvDocument {
|
|
|
3801
3801
|
*/
|
|
3802
3802
|
declare function deriveCv(localized: LocalizedTakuhon): CvDocument;
|
|
3803
3803
|
|
|
3804
|
+
/**
|
|
3805
|
+
* MCP (Model Context Protocol) projection of a profile.
|
|
3806
|
+
*
|
|
3807
|
+
* This module describes how a takuhon profile is exposed to an AI agent as a
|
|
3808
|
+
* set of read-only MCP tools and resources, and how each one is answered from a
|
|
3809
|
+
* profile document — *without* committing to a transport (stdio / HTTP) or to
|
|
3810
|
+
* any MCP SDK.
|
|
3811
|
+
*
|
|
3812
|
+
* The split mirrors the rest of core: deciding *what* to expose and *what it
|
|
3813
|
+
* returns* is a pure, deterministic projection over the canonical document
|
|
3814
|
+
* (exactly like {@link generateJsonLd}), so it lives here in `@takuhon/core` and
|
|
3815
|
+
* stays runtime-free (spec §2.3). The transport, JSON-RPC framing, and server
|
|
3816
|
+
* lifecycle are runtime-aware; they live in `@takuhon/mcp` and the CLI /
|
|
3817
|
+
* Cloudflare adapters, which call the pure executors below.
|
|
3818
|
+
*
|
|
3819
|
+
* Everything here is read-only. No tool or resource touches the admin surface,
|
|
3820
|
+
* and every answer passes through {@link applyPublicPrivacyFilter}, so an MCP
|
|
3821
|
+
* client sees exactly what `GET /api/profile`, `GET /api/jsonld`, `GET
|
|
3822
|
+
* /api/schema`, and `GET /takuhon.json` already expose — no more.
|
|
3823
|
+
*
|
|
3824
|
+
* The catalog ({@link MCP_TOOLS} / {@link MCP_RESOURCES}) is plain data with no
|
|
3825
|
+
* SDK dependency, so the `@takuhon/mcp` wiring can register it against the
|
|
3826
|
+
* official `@modelcontextprotocol/sdk` and later be swapped to a hand-rolled
|
|
3827
|
+
* dispatcher without touching this file.
|
|
3828
|
+
*/
|
|
3829
|
+
|
|
3830
|
+
/**
|
|
3831
|
+
* Profile sections a `get_section` call may request: the content-bearing keys
|
|
3832
|
+
* of a locale-resolved profile (the spec §6 data sections). `settings`,
|
|
3833
|
+
* `meta`, `schemaVersion`, and `resolvedLocale` are intentionally excluded —
|
|
3834
|
+
* they are configuration / bookkeeping, not profile content an agent reads.
|
|
3835
|
+
*/
|
|
3836
|
+
declare const MCP_PROFILE_SECTIONS: readonly ["profile", "links", "careers", "projects", "skills", "certifications", "memberships", "volunteering", "honors", "education", "publications", "languages", "courses", "patents", "testScores", "recommendations", "contact"];
|
|
3837
|
+
/** One of the {@link MCP_PROFILE_SECTIONS} a `get_section` call accepts. */
|
|
3838
|
+
type McpProfileSection = (typeof MCP_PROFILE_SECTIONS)[number];
|
|
3839
|
+
/** A JSON Schema (draft 2020-12) object describing a tool's input arguments. */
|
|
3840
|
+
type McpInputSchema = Readonly<Record<string, unknown>>;
|
|
3841
|
+
/** A read-only MCP tool definition — plain data, no SDK dependency. */
|
|
3842
|
+
interface McpToolDefinition {
|
|
3843
|
+
/** Stable tool id used in `tools/call`. */
|
|
3844
|
+
name: string;
|
|
3845
|
+
/** Human-readable title for display. */
|
|
3846
|
+
title: string;
|
|
3847
|
+
/** What the tool returns; shown to the agent when it chooses a tool. */
|
|
3848
|
+
description: string;
|
|
3849
|
+
/** JSON Schema for the tool's `arguments` object. */
|
|
3850
|
+
inputSchema: McpInputSchema;
|
|
3851
|
+
}
|
|
3852
|
+
/** A read-only MCP resource definition — plain data, no SDK dependency. */
|
|
3853
|
+
interface McpResourceDefinition {
|
|
3854
|
+
/** Stable resource URI used in `resources/read`. */
|
|
3855
|
+
uri: string;
|
|
3856
|
+
name: string;
|
|
3857
|
+
title: string;
|
|
3858
|
+
description: string;
|
|
3859
|
+
/** MIME type of the resource contents. */
|
|
3860
|
+
mimeType: string;
|
|
3861
|
+
}
|
|
3862
|
+
/** Result of {@link executeMcpTool}: the structured value the tool produced. */
|
|
3863
|
+
interface McpToolResult {
|
|
3864
|
+
/**
|
|
3865
|
+
* The JSON value the tool produced — already normalized, locale-resolved, and
|
|
3866
|
+
* privacy-filtered. The transport layer serializes this to MCP wire content.
|
|
3867
|
+
*/
|
|
3868
|
+
data: unknown;
|
|
3869
|
+
/** Locale the result was resolved at, when the tool resolved one. */
|
|
3870
|
+
resolvedLocale?: string;
|
|
3871
|
+
}
|
|
3872
|
+
/** Result of {@link readMcpResource}: one resource's contents. */
|
|
3873
|
+
interface McpResourceResult {
|
|
3874
|
+
uri: string;
|
|
3875
|
+
mimeType: string;
|
|
3876
|
+
/** The JSON value of the resource. The transport layer serializes it. */
|
|
3877
|
+
data: unknown;
|
|
3878
|
+
}
|
|
3879
|
+
/**
|
|
3880
|
+
* Thrown by {@link executeMcpTool} / {@link readMcpResource} for an unknown
|
|
3881
|
+
* tool/resource name or invalid arguments. The transport layer maps it to the
|
|
3882
|
+
* appropriate MCP error (a JSON-RPC error for a malformed request, or an
|
|
3883
|
+
* `isError` tool result for a bad argument) — core stays transport-agnostic.
|
|
3884
|
+
*/
|
|
3885
|
+
declare class McpRequestError extends Error {
|
|
3886
|
+
constructor(message: string, options?: {
|
|
3887
|
+
cause?: unknown;
|
|
3888
|
+
});
|
|
3889
|
+
}
|
|
3890
|
+
/** The read-only tools an MCP client may call against the profile. */
|
|
3891
|
+
declare const MCP_TOOLS: readonly McpToolDefinition[];
|
|
3892
|
+
/** The read-only resources an MCP client may read. */
|
|
3893
|
+
declare const MCP_RESOURCES: readonly McpResourceDefinition[];
|
|
3894
|
+
/**
|
|
3895
|
+
* Execute a read-only MCP tool against a profile document.
|
|
3896
|
+
*
|
|
3897
|
+
* `profile` is the raw validated {@link Takuhon} (the transport layer loaded it
|
|
3898
|
+
* from KV / a file). Locale-aware tools normalize, locale-resolve, and
|
|
3899
|
+
* privacy-filter it exactly as `GET /api/profile` does, then project the
|
|
3900
|
+
* requested view. Pure and deterministic — no clock, no randomness, no I/O.
|
|
3901
|
+
*
|
|
3902
|
+
* @throws {McpRequestError} for an unknown tool name or invalid arguments.
|
|
3903
|
+
*/
|
|
3904
|
+
declare function executeMcpTool(name: string, args: Readonly<Record<string, unknown>>, profile: Takuhon): McpToolResult;
|
|
3905
|
+
/**
|
|
3906
|
+
* Read a read-only MCP resource from a profile document. Pure and
|
|
3907
|
+
* deterministic.
|
|
3908
|
+
*
|
|
3909
|
+
* @throws {McpRequestError} for an unknown resource URI.
|
|
3910
|
+
*/
|
|
3911
|
+
declare function readMcpResource(uri: string, profile: Takuhon): McpResourceResult;
|
|
3912
|
+
|
|
3804
3913
|
/**
|
|
3805
3914
|
* Image-asset helpers for uploaded media (avatars, project images): magic-byte
|
|
3806
3915
|
* type detection, header-only dimension / frame reading, and metadata stripping
|
|
@@ -3901,4 +4010,4 @@ declare function stripImageMetadata(bytes: Uint8Array, mime: AcceptedImageMime):
|
|
|
3901
4010
|
*/
|
|
3902
4011
|
declare const SCHEMA_VERSION = "0.5.0";
|
|
3903
4012
|
|
|
3904
|
-
export { ACCEPTED_IMAGE_MIME_TYPES, type AcceptedImageMime, type ActivitySettings, type ActivitySnapshot, type ActivityStorage, type Address, type AssetOptions, type AssetRecord, type Avatar, type Career, type Certification, type CodingTime, ConflictError, type Contact, type ContentLicense, type ContentLicenseAttribution, type ContributionCalendar, type ContributionDay, type Course, type CvDocument, type CvHeader, type CvSection, type CvSectionKind, type Education, type ExportOptions, type ExportedTakuhon, type Honor, IMAGE_EXTENSIONS, type ImageInfo, ImportError, type Iso3166Alpha2, type IsoDateTime, type Language, type LanguageBreakdown, type LanguageProficiency, type Link, type LinkBuiltin, type LinkCustom, type LinkType, type LocaleTag, type LocalizedAddress, type LocalizedAvatar, type LocalizedBody, type LocalizedCareer, type LocalizedCertification, type LocalizedCourse, type LocalizedEducation, type LocalizedHonor, type LocalizedLanguage, type LocalizedLink, type LocalizedLinkBuiltin, type LocalizedLinkCustom, type LocalizedMembership, type LocalizedPatent, type LocalizedProfile, type LocalizedProject, type LocalizedPublication, type LocalizedRecommendation, type LocalizedRecommendationAuthor, type LocalizedTakuhon, type LocalizedTestScore, type LocalizedTitle, type LocalizedVolunteering, MAX_IMAGE_BYTES, MAX_IMAGE_DIMENSION, MAX_IMAGE_FRAMES, type Membership, type Meta, type MetaPrivacy, type Migration, MigrationError, type NormalizedTakuhon, NotFoundError, type Patent, type PatentStatus, type Profile, type Project, type Publication, RANK_FULL_CODING_HOURS, RANK_FULL_CONTRIBUTIONS, RANK_TIER_THRESHOLDS, type RankInput, type RankTier, type RankTierLabel, type Recommendation, type RecommendationAuthor, SCHEMA_VERSION, SUPPORTED_SCHEMA_VERSIONS, type Schema, type Settings, type Skill, type Slug, StorageError, type Takuhon, type TakuhonAssetStorage, type TakuhonStorage, type TestScore, type ValidationError, type ValidationResult, type Volunteering, type YearMonth, applyPublicPrivacyFilter, computeLanguagePercentages, deriveCv, deriveRankTier, detectImageMime, exportTakuhon, formatCodingTime, generateJsonLd, generatePersonJsonLd, generateProfilePageJsonLd, importTakuhon, isActivitySnapshot, migrateTakuhon, migrations, normalize, readImageInfo, renderActivitySvg, resolveLocale, schema, stripImageMetadata, validate };
|
|
4013
|
+
export { ACCEPTED_IMAGE_MIME_TYPES, type AcceptedImageMime, type ActivitySettings, type ActivitySnapshot, type ActivityStorage, type Address, type AssetOptions, type AssetRecord, type Avatar, type Career, type Certification, type CodingTime, ConflictError, type Contact, type ContentLicense, type ContentLicenseAttribution, type ContributionCalendar, type ContributionDay, type Course, type CvDocument, type CvHeader, type CvSection, type CvSectionKind, type Education, type ExportOptions, type ExportedTakuhon, type Honor, IMAGE_EXTENSIONS, type ImageInfo, ImportError, type Iso3166Alpha2, type IsoDateTime, type Language, type LanguageBreakdown, type LanguageProficiency, type Link, type LinkBuiltin, type LinkCustom, type LinkType, type LocaleTag, type LocalizedAddress, type LocalizedAvatar, type LocalizedBody, type LocalizedCareer, type LocalizedCertification, type LocalizedCourse, type LocalizedEducation, type LocalizedHonor, type LocalizedLanguage, type LocalizedLink, type LocalizedLinkBuiltin, type LocalizedLinkCustom, type LocalizedMembership, type LocalizedPatent, type LocalizedProfile, type LocalizedProject, type LocalizedPublication, type LocalizedRecommendation, type LocalizedRecommendationAuthor, type LocalizedTakuhon, type LocalizedTestScore, type LocalizedTitle, type LocalizedVolunteering, MAX_IMAGE_BYTES, MAX_IMAGE_DIMENSION, MAX_IMAGE_FRAMES, MCP_PROFILE_SECTIONS, MCP_RESOURCES, MCP_TOOLS, type McpInputSchema, type McpProfileSection, McpRequestError, type McpResourceDefinition, type McpResourceResult, type McpToolDefinition, type McpToolResult, type Membership, type Meta, type MetaPrivacy, type Migration, MigrationError, type NormalizedTakuhon, NotFoundError, type Patent, type PatentStatus, type Profile, type Project, type Publication, RANK_FULL_CODING_HOURS, RANK_FULL_CONTRIBUTIONS, RANK_TIER_THRESHOLDS, type RankInput, type RankTier, type RankTierLabel, type Recommendation, type RecommendationAuthor, SCHEMA_VERSION, SUPPORTED_SCHEMA_VERSIONS, type Schema, type Settings, type Skill, type Slug, StorageError, type Takuhon, type TakuhonAssetStorage, type TakuhonStorage, type TestScore, type ValidationError, type ValidationResult, type Volunteering, type YearMonth, applyPublicPrivacyFilter, computeLanguagePercentages, deriveCv, deriveRankTier, detectImageMime, executeMcpTool, exportTakuhon, formatCodingTime, generateJsonLd, generatePersonJsonLd, generateProfilePageJsonLd, importTakuhon, isActivitySnapshot, migrateTakuhon, migrations, normalize, readImageInfo, readMcpResource, renderActivitySvg, resolveLocale, schema, stripImageMetadata, validate };
|
package/dist/index.js
CHANGED
|
@@ -11587,6 +11587,161 @@ function deriveCv(localized) {
|
|
|
11587
11587
|
};
|
|
11588
11588
|
}
|
|
11589
11589
|
|
|
11590
|
+
// src/mcp.ts
|
|
11591
|
+
var MCP_PROFILE_SECTIONS = [
|
|
11592
|
+
"profile",
|
|
11593
|
+
"links",
|
|
11594
|
+
"careers",
|
|
11595
|
+
"projects",
|
|
11596
|
+
"skills",
|
|
11597
|
+
"certifications",
|
|
11598
|
+
"memberships",
|
|
11599
|
+
"volunteering",
|
|
11600
|
+
"honors",
|
|
11601
|
+
"education",
|
|
11602
|
+
"publications",
|
|
11603
|
+
"languages",
|
|
11604
|
+
"courses",
|
|
11605
|
+
"patents",
|
|
11606
|
+
"testScores",
|
|
11607
|
+
"recommendations",
|
|
11608
|
+
"contact"
|
|
11609
|
+
];
|
|
11610
|
+
var McpRequestError = class extends Error {
|
|
11611
|
+
constructor(message, options) {
|
|
11612
|
+
super(message, options);
|
|
11613
|
+
this.name = "McpRequestError";
|
|
11614
|
+
}
|
|
11615
|
+
};
|
|
11616
|
+
var LANG_PROPERTY = {
|
|
11617
|
+
type: "string",
|
|
11618
|
+
description: 'BCP-47 locale tag (e.g. "ja", "en"). Resolves to the requested locale, falling back to the profile default when omitted or unavailable.'
|
|
11619
|
+
};
|
|
11620
|
+
var MCP_TOOLS = [
|
|
11621
|
+
{
|
|
11622
|
+
name: "get_profile",
|
|
11623
|
+
title: "Get profile",
|
|
11624
|
+
description: "Return the owner's full public profile, resolved to one locale and privacy-filtered (identical to the public `GET /api/profile`).",
|
|
11625
|
+
inputSchema: {
|
|
11626
|
+
type: "object",
|
|
11627
|
+
properties: { lang: LANG_PROPERTY },
|
|
11628
|
+
additionalProperties: false
|
|
11629
|
+
}
|
|
11630
|
+
},
|
|
11631
|
+
{
|
|
11632
|
+
name: "get_section",
|
|
11633
|
+
title: "Get profile section",
|
|
11634
|
+
description: "Return a single section of the public profile (e.g. careers, education, skills), resolved to one locale and privacy-filtered.",
|
|
11635
|
+
inputSchema: {
|
|
11636
|
+
type: "object",
|
|
11637
|
+
properties: {
|
|
11638
|
+
section: {
|
|
11639
|
+
type: "string",
|
|
11640
|
+
enum: [...MCP_PROFILE_SECTIONS],
|
|
11641
|
+
description: "Which profile section to return."
|
|
11642
|
+
},
|
|
11643
|
+
lang: LANG_PROPERTY
|
|
11644
|
+
},
|
|
11645
|
+
required: ["section"],
|
|
11646
|
+
additionalProperties: false
|
|
11647
|
+
}
|
|
11648
|
+
},
|
|
11649
|
+
{
|
|
11650
|
+
name: "get_jsonld",
|
|
11651
|
+
title: "Get JSON-LD",
|
|
11652
|
+
description: "Return the Schema.org JSON-LD (a `ProfilePage` wrapping a `Person`) for the profile, resolved to one locale (identical to `GET /api/jsonld`).",
|
|
11653
|
+
inputSchema: {
|
|
11654
|
+
type: "object",
|
|
11655
|
+
properties: { lang: LANG_PROPERTY },
|
|
11656
|
+
additionalProperties: false
|
|
11657
|
+
}
|
|
11658
|
+
},
|
|
11659
|
+
{
|
|
11660
|
+
name: "list_locales",
|
|
11661
|
+
title: "List locales",
|
|
11662
|
+
description: "List the locales this profile is available in, plus the default \u2014 useful before calling another tool with a `lang` argument.",
|
|
11663
|
+
inputSchema: { type: "object", properties: {}, additionalProperties: false }
|
|
11664
|
+
}
|
|
11665
|
+
];
|
|
11666
|
+
var MCP_RESOURCES = [
|
|
11667
|
+
{
|
|
11668
|
+
uri: "takuhon://profile",
|
|
11669
|
+
name: "profile",
|
|
11670
|
+
title: "Canonical profile (takuhon.json)",
|
|
11671
|
+
description: "The full canonical takuhon.json, privacy-filtered, with every locale retained (identical to `GET /takuhon.json`).",
|
|
11672
|
+
mimeType: "application/json"
|
|
11673
|
+
},
|
|
11674
|
+
{
|
|
11675
|
+
uri: "takuhon://schema",
|
|
11676
|
+
name: "schema",
|
|
11677
|
+
title: "Takuhon JSON Schema",
|
|
11678
|
+
description: "The public JSON Schema contract the profile conforms to (identical to `GET /api/schema`). Lets an agent understand the document shape.",
|
|
11679
|
+
mimeType: "application/json"
|
|
11680
|
+
}
|
|
11681
|
+
];
|
|
11682
|
+
function executeMcpTool(name, args, profile) {
|
|
11683
|
+
switch (name) {
|
|
11684
|
+
case "get_profile": {
|
|
11685
|
+
const localized = publicView(profile, readLang(args));
|
|
11686
|
+
return { data: localized, resolvedLocale: localized.resolvedLocale };
|
|
11687
|
+
}
|
|
11688
|
+
case "get_section": {
|
|
11689
|
+
const section = readSection(args);
|
|
11690
|
+
const localized = publicView(profile, readLang(args));
|
|
11691
|
+
return { data: localized[section], resolvedLocale: localized.resolvedLocale };
|
|
11692
|
+
}
|
|
11693
|
+
case "get_jsonld": {
|
|
11694
|
+
const localized = publicView(profile, readLang(args));
|
|
11695
|
+
return { data: generateJsonLd(localized), resolvedLocale: localized.resolvedLocale };
|
|
11696
|
+
}
|
|
11697
|
+
case "list_locales":
|
|
11698
|
+
return {
|
|
11699
|
+
data: {
|
|
11700
|
+
defaultLocale: profile.settings.defaultLocale,
|
|
11701
|
+
availableLocales: profile.settings.availableLocales,
|
|
11702
|
+
...profile.settings.fallbackLocale !== void 0 ? { fallbackLocale: profile.settings.fallbackLocale } : {}
|
|
11703
|
+
}
|
|
11704
|
+
};
|
|
11705
|
+
default:
|
|
11706
|
+
throw new McpRequestError(`Unknown MCP tool: ${name}`);
|
|
11707
|
+
}
|
|
11708
|
+
}
|
|
11709
|
+
function readMcpResource(uri, profile) {
|
|
11710
|
+
switch (uri) {
|
|
11711
|
+
case "takuhon://profile":
|
|
11712
|
+
return {
|
|
11713
|
+
uri,
|
|
11714
|
+
mimeType: "application/json",
|
|
11715
|
+
data: applyPublicPrivacyFilter(profile)
|
|
11716
|
+
};
|
|
11717
|
+
case "takuhon://schema":
|
|
11718
|
+
return { uri, mimeType: "application/json", data: schema };
|
|
11719
|
+
default:
|
|
11720
|
+
throw new McpRequestError(`Unknown MCP resource: ${uri}`);
|
|
11721
|
+
}
|
|
11722
|
+
}
|
|
11723
|
+
function publicView(profile, lang) {
|
|
11724
|
+
return applyPublicPrivacyFilter(resolveLocale(normalize(profile), lang));
|
|
11725
|
+
}
|
|
11726
|
+
function readLang(args) {
|
|
11727
|
+
const lang = args.lang;
|
|
11728
|
+
if (lang === void 0) return void 0;
|
|
11729
|
+
if (typeof lang !== "string") {
|
|
11730
|
+
throw new McpRequestError("`lang` must be a string (a BCP-47 locale tag).");
|
|
11731
|
+
}
|
|
11732
|
+
return lang;
|
|
11733
|
+
}
|
|
11734
|
+
function readSection(args) {
|
|
11735
|
+
const section = args.section;
|
|
11736
|
+
if (typeof section !== "string" || !isProfileSection(section)) {
|
|
11737
|
+
throw new McpRequestError(`\`section\` must be one of: ${MCP_PROFILE_SECTIONS.join(", ")}.`);
|
|
11738
|
+
}
|
|
11739
|
+
return section;
|
|
11740
|
+
}
|
|
11741
|
+
function isProfileSection(value) {
|
|
11742
|
+
return MCP_PROFILE_SECTIONS.includes(value);
|
|
11743
|
+
}
|
|
11744
|
+
|
|
11590
11745
|
// src/image.ts
|
|
11591
11746
|
var ACCEPTED_IMAGE_MIME_TYPES = [
|
|
11592
11747
|
"image/jpeg",
|
|
@@ -11927,6 +12082,10 @@ export {
|
|
|
11927
12082
|
MAX_IMAGE_BYTES,
|
|
11928
12083
|
MAX_IMAGE_DIMENSION,
|
|
11929
12084
|
MAX_IMAGE_FRAMES,
|
|
12085
|
+
MCP_PROFILE_SECTIONS,
|
|
12086
|
+
MCP_RESOURCES,
|
|
12087
|
+
MCP_TOOLS,
|
|
12088
|
+
McpRequestError,
|
|
11930
12089
|
MigrationError,
|
|
11931
12090
|
NotFoundError,
|
|
11932
12091
|
RANK_FULL_CODING_HOURS,
|
|
@@ -11940,6 +12099,7 @@ export {
|
|
|
11940
12099
|
deriveCv,
|
|
11941
12100
|
deriveRankTier,
|
|
11942
12101
|
detectImageMime,
|
|
12102
|
+
executeMcpTool,
|
|
11943
12103
|
exportTakuhon,
|
|
11944
12104
|
formatCodingTime,
|
|
11945
12105
|
generateJsonLd,
|
|
@@ -11951,6 +12111,7 @@ export {
|
|
|
11951
12111
|
migrations,
|
|
11952
12112
|
normalize,
|
|
11953
12113
|
readImageInfo,
|
|
12114
|
+
readMcpResource,
|
|
11954
12115
|
renderActivitySvg,
|
|
11955
12116
|
resolveLocale,
|
|
11956
12117
|
schema,
|